第四十二章. Postgres 规则系统

内容
Querytree(查询树)是什么?
视图和规则系统
INSERT,UPDATE 和 DELETE 的规则
规则和权限
规则与触发器之比较
生产规则系统的概念是很简单的,但是在实际使用的时候会碰到很多细微的问题.这些问题的一部分和 Postgres 规则系统的理论基础可以在 [Stonebraker et al, ACM, 1990] 找到.

有些数据库系统定义动态的数据库规则.这些通常是存储过程和触发器,在 Postgres 里是通过函数和触发器来实现的.

"查询重写规则系统"(从现在开始称之为 "规则系统")是和存储过程和触发器完全不同的东西.它把查询修改为需要考虑规则的形式,然后把修改过的查询传递给查询优化器执行.这是非常有效的工具并且可以用于许多象查询语言过程,视图,和版本等.规则系统的能力在  [Ong and Goh, 1990] 和  [Stonebraker et al, ACM, 1990] 里有讨论.

Querytree(查询树)是什么?

要理解规则系统如何工作,首先要知道规则何时被激发以及它的输入和结果是什么.

规则系统位于查询分析器和优化器之间.以分析器的输出 -- 一个查询树,以及从 pg_rewrite 表里来的重写规则作为输入,(重写规则)也是一个查询树,只不过增加了一些扩展信息,然后创建零个或者多个查询树作为结果.所以它的输入和输出总是那些分析器可以生成的东西,因而任何它(规则系统)看到的东西都是可以用 SQL 语句表达的.

那么什么是 querytree(查询树)呢?它是一个 SQL 语句的内部表现形式,这时组成该语句的每个部分都是分别存储的.当你用调试级别(debuglevel)4 运行 Postgres 后端并且在 SQL 界面交互地输入查询命令时可以看到这些查询树.在 pg_rewrite 系统表里的规则动作也是以查询树的方式存储的.不过不是用象调试输出那样的格式,但内容是完全一样的.

读查询树的内容需要一定的经验,我开始在规则系统上干活时经历了一段很困难的时光.我还记得当初我站在一台咖啡机面前把杯子当做目标列,水和咖啡粉当作可排列的元素,所有按钮是合格的表达式来想象查询树的情景.因为查询树的 SQL 表现是理解规则系统的很重要的部分,这份文档将不会告诉你如何读取它们.这篇文档可能帮助你学习规则系统和它的命名传统以便于后面的描述.

Querytree(查询树)的成员

当我们读取这份文档中查询树的 SQL 表现时,我们必须能够识别该语句被分解后放在查询树里的成员.查询树的成员有
命令类型 ( commandtype )
这是一个简单的值,说明哪条命令 (SELECT,INSERT,UPDATE,DELETE)生成这个分析树.
可排列元素 (rangetable)
可排列元素是一个查询中使用的关系的列表.在 SELECT 语句里是在 FORM 关键字后面给出的关系.

 
每个可排列元素表示一个表或一个视图,表明是查询里哪个成员调用了它.在查询树里,可排列元素   是用索引而不是用名字引用的,所以这里不用象在 SQL 语句里一样关心是否有重名问题.这种情 况在引入了规则的可排列元素后可能会发生.本文档的例子将不讨论这种情况.

 
结果关系(resultrelation)

 
这是一个可排列元素的索引,用于标识查询结果之间的关系.

 
SELECT 查询通常没有结果集关系.SELECT INTO 几乎等于一个 CREATE TABLE,INSERT ... SELECT 序列,所以这里我们就不单独讨论了.

 
在 INSERT,UPDATE 和 DELETE 查询里,结果关系(resultrelation )是更改发生影响的表(或视图!).
目标列 (targetlist)

 
目标列是一列定义查询结果的表达式.在 SELECT 的情况下,这些表达式是就是构建查询的最终输出的东西.它们是位于 SELECT 和 FROM 关键字之间的表达式 (* 只是表明一个关系的所有字段的缩写).

 

 
 
 
 
 
 
 

DELETE 不需要目标列是因为它们不产生任何结果.实际上优化器会向空目标列增加一个特殊入口.但这是在规则系统之后并且我们将稍后讨论.对于规则系统而言,目标列是空的.

 
在 INSERT  查询里面,目标列描述了应该进入结果集的新行.忽略的字段将由优化器自动赋予一个常量NULL.这些就是在 VALUES 子句里的表达式或在 INSERT ... SELECT 语句里的话 SELECT 子句.

 
在 UPDATE 查询里,它(目标列)描述应该替换旧行的新行.这时,优化器将通过插入从旧行抽取数据到新行的表达式向新行追加缺失的字段.并且它也会象 在 DELETE 里那样增加特殊的入口.它是从查询的 SET attribute = expression 部分抽取的表达式.

 

 

目标列里的每个元素都包含着一个可以为常量,可以为一个指向某个可排列元素里面的关系的字段的变量指 针,可以为一个由函数调用,常量,变量,操作符等构成的表达式树的表达式.
 

资格 (qualification)

 
查询资格是一个表达式,它非常类似那些包含在目标列里的条目.这个表达式的值是一个布尔值,通过此值来判断对最终结果行是否要执操作(INSERT,UPDATE,DELETE 或 SELECT).它是一个 SQL 语句 的 WHERE 子句.
其他 (others)

 
查询树的其他部分,像 ORDER BY 子句,我们不准备在这里讨论.规则系统在附加规则时将在那里(ORDER BY 子句)替换规则,但是这对于规则系统的基本原理并没有多大关系.当 GROUP BY  在视图定义中出现时是一个特例,仍然需要在我们的文档里做些说明.