2013-02-22 24 views
2

我正在构建一个多租户系统,其中许多客户端数据将位于同一个数据库中。如何确保所有Postgres查询都有WHERE子句?

我对某些开发人员有些偏执,忘记将适当的“WHERE clientid =”放到每个查询上。

有没有办法在数据库级别确保每个查询都有正确的WHERE =子句,从而确保不会执行任何查询,而又不指定哪个客户端查询?

我想知道如果查询重写规则可以做到这一点,但它不知道他们是否可以这样做。

感谢

+0

'select * from very_big_table WHERE 1 = 1;'voila!有你的where-clause ... – wildplasser 2013-02-23 13:03:57

回答

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 
+0

任何性能影响到这个解决方案? – 2013-02-23 03:57:32

1

另一种方法是创建一个VIEW为:

SELECT * 
FROM t 
WHERE t.client_id = current_setting('session_vars.client_id'); 

,并在会话开始使用SET session_vars.client_id = 1234

拒绝对表格进行访问,只留下意见的许可。

您可能需要为视图(取决于您的PostgreSQL版本)创建UPDATE,DELETEINSERT的重写规则。

因为PostgreSQL会在执行前重写查询,所以性能损失很小(如果有的话)。