我有一个关于表设计的最佳实践/最佳解决方案的问题,其中大多数列在满足特定条件(设置lock_date)后必须受到写保护。
想象一下下表的设置。一个文件夹表和一个文档表,大约有 15 列,其中一列是锁定日期。
folder table COLUMNS id, ...
document table COLUMNS fk_folder, lock_date, col_1, col_2, col_3, ....
因此,设置锁定日期后,应保护文档表上的前 10 列不被更改。
我目前有两个解决方案:
创建两张表,其中一张保存不可更改的信息。并用扳机固定第一个。 (
fk_folder
该去哪里??)
为整个表创建一个触发器,检查所有不应该更新的列。
还有更好的解决方案吗?
CREATE TABLE locked_rows (
id integer PRIMARY KEY,
locked timestamp with time zone,
val text
);
-- enforce row level security for everyone except superusers
ALTER TABLE locked_rows ENABLE ROW LEVEL SECURITY;
ALTER TABLE locked_rows FORCE ROW LEVEL SECURITY;
现在什么都不允许,我们必须显式允许使用行级安全策略的操作:
-- everything allowed on all rows
CREATE POLICY allow_all ON locked_rows
AS PERMISSIVE FOR ALL TO PUBLIC
USING (TRUE);
-- but updates cannot see locked rows
CREATE POLICY dont_edit_locked ON locked_rows
AS RESTRICTIVE FOR UPDATE TO PUBLIC
USING (locked IS NULL)
WITH CHECK (TRUE);
我们可以测试它是否有效:
-- insert an unlocked row
INSERT INTO locked_rows VALUES (1, NULL, 'orig');
INSERT 0 1
-- we can change "val"
UPDATE locked_rows SET val = 'new'
WHERE id = 1;
UPDATE 1
-- we can lock the row
UPDATE locked_rows SET locked = current_timestamp
WHERE id = 1;
UPDATE 1
-- but updating a locked row changes nothing
UPDATE locked_rows SET val = 'another'
WHERE id = 1;
UPDATE 0
您不会收到错误,但您可以检查受
UPDATE
影响的行数。