我想隐藏选择对象不是重写所有的SQL查询,而是通过更简单的方式。
所以,我想为一个特定的表添加一个规则(或其他东西)到数据库中。例如,如果我们从网站上删除一个用户,我们执行如下操作:
UPDATE user_common SET is_deleted='t' WHERE user_id=1234
并且不需要重写所有关于用户的现有查询,条件是隐藏的:
SELECT first_name, second_name FROM user_common WHERE coins>200
上面的SELECT将在隐藏条件下执行,例如:
SELECT first_name, second_name FROM user_common WHERE coins>200 AND is_deleted!='t'
如何使它工作?
正如@Gordon在他的回答中指出的那样,您可以使用视图来隐藏已删除的行,并且(至少从Postgres 9.3开始)对该视图的更改将自动应用于底层表。
但是你可以更进一步,使用Postgres的规则系统,将视图上的DELETE
s转换为基表的is_deleted
标志的UPDATE
s。如果从视图中排除is_deleted
本身,它应该与"正常"表几乎无法区分。
CREATE TABLE user_common_base
(
user_id SERIAL PRIMARY KEY,
first_name TEXT,
second_name TEXT,
coins INTEGER,
is_deleted BOOLEAN DEFAULT false
);
CREATE VIEW user_common AS
SELECT
user_id,
first_name,
second_name,
coins
FROM user_common_base
WHERE NOT is_deleted;
CREATE RULE user_common_delete AS
ON DELETE TO user_common
DO INSTEAD
UPDATE user_common_base
SET is_deleted = true
WHERE id = OLD.id;
你可以用视图完成你想要的。
create view v_table
select uc.*
from user_common uc
where is_deleted <> 't';
关键是对表的引用确实需要更改到视图。一种方法是重命名表,然后创建一个同名的视图:
alter table user_common to base_user_common;
create view user_common as
select uc.*
from user_common uc
where is_deleted <> 't';