我正在构建一个多租户系统,其中许多客户端数据将位于同一个数据库中。
对于某些开发人员忘记在每个查询中放置适当的“WHERE clientid =”,我很偏执。
有没有办法在数据库级别确保每个查询都有正确的WHERE =子句,从而确保在没有指定查询所针对的客户端的情况下也不会执行任何查询?
我想知道查询重写规则是否可以做到这一点,但我不清楚他们是否可以这样做。
感谢
答案 0 :(得分:3)
拒绝所有用户对表t
的权限。然后授予他们对函数f
的权限,该函数返回表并接受参数client_id:
create or replace function f(_client_id integer)
returns setof t as
$$
select *
from t
where client_id = _client_id
$$ language sql
;
select * from f(1);
client_id | v
-----------+---
1 | 2
答案 1 :(得分:1)
另一种方法是为:
创建VIEW
SELECT *
FROM t
WHERE t.client_id = current_setting('session_vars.client_id');
在会话开始时使用SET session_vars.client_id = 1234
。
拒绝访问表格,只留下视图的许可。
您可能需要为视图创建UPDATE
,DELETE
,INSERT
的重写规则(这取决于您的PostgreSQL版本)。
性能损失很小(如果有的话),因为PostgreSQL会在执行前重写查询。