你在这里提出的方案违反了启用或拒绝数据库中数据访问的标准方式。通常,您可以通过在表和函数上授予权限来解决此问题。您的情况可以通过以下方式解决:
首先,使用特定角色(用户、组)创建表,例如“管理员”。
CREATE TABLE x (...);
ALTER TABLE x OWNER to admin;
CREATE TABLE y (...);
ALTER TABLE y OWNER to admin;
目前只有“管理员”角色可以访问表格。如果您希望其他用户 (比如"app_user"角色) 可以从表 x
中进行选择,并且可以从表 y
进行选择、插入、更新和删除操作,那么您需要明确地授予权限:GRANT
。
GRANT SELECT ON x TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON y TO app_user;
您需要在表
y
上定义一个触发器,并在触发器函数中将更改级联到表
x
;我假设您已经解决了这个问题。这里的诀窍是将“admin”用户作为触发器函数的所有者(因为只有“admin”可以在表
y
上创建触发器),然后使用
SECURITY DEFINER
。这意味着即使“app_user”执行了一个
INSERT INTO y ...
,触发器被调用,级联操作表
x
的触发器函数也会以用户“admin”的权限执行:
CREATE FUNCTION my_trigger_func RETURNS trigger AS $$
BEGIN
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION my_trigger_func OWNER TO admin;
REVOKE ALL ON FUNCTION my_trigger_func FROM public;
CREATE TRIGGER my_trigger
BEFORE INSERT, UPDATE, DELETE ON y
FOR EACH ROW EXECUTE PROCEDURE my_trigger_func();
请注意,您不必在触发器函数上授予
GRANT EXECUTE
权限:因为“app_user”对调用运行触发器函数的触发器所涉及的表
y
具有权限,“app_user”被允许执行触发器函数。
按照此过程,"app_user"修改表
x
的唯一方式是通过表
y
。使用"admin"可以直接修改表
x
,但作为表和触发器所有者,该角色应该知道不要直接修改表
x
。