CREATE ROW POLICY
创建行策略,即用于确定用户可以从表中读取哪些行的过滤器。
行策略仅对具有只读访问权限的用户有意义。如果用户可以修改表或在表之间复制分区,则会破坏行策略的限制。
语法
CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name1 [ON CLUSTER cluster_name1] ON [db1.]table1|db1.*
[, policy_name2 [ON CLUSTER cluster_name2] ON [db2.]table2|db2.* ...]
[IN access_storage_type]
[FOR SELECT] USING condition
[AS {PERMISSIVE | RESTRICTIVE}]
[TO {role1 [, role2 ...] | ALL | ALL EXCEPT role1 [, role2 ...]}]
USING 子句
允许指定一个条件来过滤行。如果为该行计算出的条件为非零,则用户将看到该行。
TO 子句
在TO
部分,您可以提供此策略应适用的用户和角色列表。例如,CREATE ROW POLICY ... TO accountant, john@localhost
。
关键字ALL
表示所有 ClickHouse 用户,包括当前用户。关键字ALL EXCEPT
允许从所有用户列表中排除某些用户,例如,CREATE ROW POLICY ... TO ALL EXCEPT accountant, john@localhost
如果未为表定义任何行策略,则任何用户都可以从表中SELECT
所有行。为表定义一个或多个行策略会使对表的访问依赖于行策略,无论这些行策略是否为当前用户定义。例如,以下策略
CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter
禁止用户mira
和peter
查看b != 1
的行,并且任何未提及的用户(例如,用户paul
)都将完全看不到mydb.table1
中的任何行。
如果这不是您想要的,可以通过添加另一个行策略来解决,如下所示
CREATE ROW POLICY pol2 ON mydb.table1 USING 1 TO ALL EXCEPT mira, peter
AS 子句
允许在同一张表上为同一用户同时启用多个策略。因此,我们需要一种方法来组合来自多个策略的条件。
默认情况下,策略使用布尔OR
运算符组合。例如,以下策略
CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 TO peter, antonio
允许用户peter
查看b=1
或c=2
的行。
AS
子句指定如何将策略与其他策略组合。策略可以是许可的或限制性的。默认情况下,策略是许可的,这意味着它们使用布尔OR
运算符组合。
可以选择将策略定义为限制性。限制性策略使用布尔AND
运算符组合。
以下是通用公式
row_is_visible = (one or more of the permissive policies' conditions are non-zero) AND
(all of the restrictive policies's conditions are non-zero)
例如,以下策略
CREATE ROW POLICY pol1 ON mydb.table1 USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 AS RESTRICTIVE TO peter, antonio
仅当b=1
和c=2
都满足时,才允许用户peter
查看行。
数据库策略与表策略组合。
例如,以下策略
CREATE ROW POLICY pol1 ON mydb.* USING b=1 TO mira, peter
CREATE ROW POLICY pol2 ON mydb.table1 USING c=2 AS RESTRICTIVE TO peter, antonio
仅当b=1
和c=2
都满足时,才允许用户peter
查看table1的行,尽管mydb中的任何其他表都只对用户应用了b=1
策略。
ON CLUSTER 子句
允许在集群上创建行策略,请参阅分布式 DDL。
示例
CREATE ROW POLICY filter1 ON mydb.mytable USING a<1000 TO accountant, john@localhost
CREATE ROW POLICY filter2 ON mydb.mytable USING a<1000 AND b=5 TO ALL EXCEPT mira
CREATE ROW POLICY filter3 ON mydb.mytable USING 1 TO admin
CREATE ROW POLICY filter4 ON mydb.* USING 1 TO admin