一、pg特色之规则介绍¶
什么叫规则? 规则系统更准确地说是查询重写规则系统?对应pg来说:把用户发过来的SQL命令在执行前通过内部的规则定 义改编成另一个SQL命令后再执行的一种方式
1.1 SELECT规则¶
PostgreSQL的视图是通过SELECT规则来实现的:(pg试图就是一个select规则)
案例:
create table t(id int,name varchar);
#创建视图:
CREATE VIEW myview AS SELECT * FROM t;
等价于:
CREATE TABLE myview (same column list as t);
CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD SELECT * FROM t;
\dt;
\dv;
```视图实际上是一张表,然后在这张表中加了一个
SELECT规则
SELECT 规则有如下限制:
- 后续动作只能是INSTEAD。
- 规则的名称只能是“_RETURN”。
- 只能创建在空表上。
案例:
CREATE TABLE mytab1(id int, note varchar(40));
CREATE TABLE mytab2(id int, note varchar(40));
\d mytab2;
在表“mytab2”上建一个SELECT规则
CREATE RULE myrule AS ON SELECT TO mytab2 DO ALSO SELECT * from mytab1;
-- SELECT规则的后续动作只能是INSTEAD
CREATE RULE myrule AS ON SELECT TO mytab2 DO INSTEAD SELECT * from mytab1; --SELECT规则的名称只能是“_RETURN”
CREATE RULE "_RETURN" AS ON SELECT TO mytab2 DO INSTEAD SELECT * from mytab1; -- mytab2变成了一个试图
更新规则
我们所说的更新规则就是指事务为“INSERT”“UPDATE”“DELETE”的这3种规则
“ALSO”与“INSTEAD”:
ALSO:除执行原操作外还执行一些附加操作,这些附加操作由后面的“command”指定 INSTEAD:把原操作替换为后面的“command”的操作
案例1 创建insert规则禁止插入数据
create table t(id int,name varchar);
insert into t values(1,'aaa');
insert into t values(2,'aaadd');
#在t表上创建一个规则,执行insert时什么都不做 create rule t_r as on insert to t do instead nothing;
insert into t values(7,'cha');
案例2
记录某个表所有的 dml的操作记录
CREATE TABLE mytab(id int primary key, note text);
6.2 建一个操作记录表¶
CREATE TABLE mytab_log(
seq bigserial primary key,
oprtype char(1),
oprtime timestamp,
old_id int,
new_id int,
old_note text,
new_note text);
6.3 建如下规则¶
CREATE RULE rule_mytab_insert AS ON INSERT TO mytab DO ALSO INSERT INTO mytab_log(oprtype, oprtime, new_id, new_note) VALUES('i', now(), [new.id](http://new.id/), new.note);
CREATE RULE rule_mytab_update AS ON UPDATE TO mytab DO ALSO INSERT INTO mytab_log(oprtype, oprtime, old_id, new_id, old_note, new_note) VALUES('u', now(), [old.id](http://old.id/), [new.id](http://new.id/), old.note, new.note);
CREATE RULE rule_mytab_delete AS ON DELETE DO ALSO INSERT INTO mytab_log(oprtype, oprtime, old_id, old_note) VALUES('d', now(), [old.id](http://old.id/), old.note);
6.4 对原表操作¶
insert into mytab values(1, '11111');
insert into mytab values(2, '22222');
update mytab set note ='aaaaa' where id=1;
update mytab set note ='bbbbb' where id=2;
delete from mytab;
6.5 对update进行改造¶
CREATE RULE rule_mytab_update AS ON UPDATE TO mytab DO ALSO ( INSERT INTO mytab_log(oprtype, oprtime, id, note) VALUES('d', now(), [old.id](http://old.id/), old.note); INSERT INTO mytab_log(oprtype, oprtime, id, note) VALUES('i', now(), [new.id](http://new.id/), new.note));
规则和权限
规则(RULE)是从属于表或视图的。 如果一张表属于一个用户,则这张表上的所有规则都是属于这个用户的。 用户只需要对查询中明确指定的表拥有所需的权限就可进行操作
如果我给一个试图查询权限了,但是底层表没有权限是否可以访问? 比如:用户“osdba”有一张视图“myview”
create view myview as select id from mytab;
其中mytab也所属 osdba用户
grant select on myview to user01;
修改规则
ALTER RULE name ON table_name RENAME TO new_name name:要修改的一条现有规则的名称。 table_name:该规则适用的表或视图的名称(可以是模式限定的)。 new_name:该规则的新名称。
删除规则
drop rule t_rule on t;
规则与触发器的比较
-
触发器能做的很多事情使用PostgreSQL的规则系统也可以完成
-
规则修改或生成额外的查询,有时让人觉得不好理解,而触发器的方法从概念上远比规则的方法要简单,更容易掌握
什么时候用规则什么使用用触发器
规则系统是通过查询重写来实现的,而触发器通常是为每个行都触发执行一次,所以对于批量操作,使用规则可能会生成更 好的执行计划,从而效率更高一些