作为补充
理论部分在文档中有很好的描述
文章没有什么新意,没有隐藏的含义或秘密知识。 只是一个关于理论想法的实际实施的草图。 如果有人感兴趣,请阅读它。 如果您不感兴趣,请不要浪费时间。
制定问题
在不深入研究该主题领域的情况下,简单地说,问题可以表述如下: 有一个表,实现了某个业务实体。 表中的行可以被删除,但行不能被物理删除;它们必须被隐藏。
因为有句话说:“不要删除任何内容,只需重命名即可。 互联网存储一切”
在此过程中,建议不要重写与该实体一起使用的现有存储函数。
为了实现这个概念,该表具有属性 已删除。 那么一切就很简单了 - 您需要确保客户端只能看到属性所在的行 已删除 错误的该机制是用来做什么的? 行级安全性。
履行
创建单独的角色和架构
CREATE ROLE repos;
CREATE SCHEMA repos;
创建目标表
CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos
打开 行级安全性
ALTER TABLE repos.file ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;
服务功能 — 删除表中的一行
CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE
WHERE id = curr_id ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
业务功能 — 删除文档
CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
结果
客户端删除文档
SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );
删除后客户端看不到该文档
SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)
但在数据库中文档并没有被删除,只是属性被改变了 是_删除
psql -d my_db
SELECT id, name , is_del FROM repos.file ;
id | name | is_del
--+---------+------------
1 | test_1 | t
(1 row)
这就是问题陈述中所要求的。
总
如果该主题有趣,在下一个研究中,您可以展示一个实现基于角色的模型以使用行级安全性分离数据访问的示例。
来源: habr.com