当前位置:早雪网网络学院编程文档数据库技术Postgresql → PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统

PostgreSQL7.0手册-程序员手册 -42. Postgres 规则系统

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-23 12:21:48
_log 只有SELECT 权限.写日志记录的规则动作(action)仍然可以成功的执行.并且 Al 可以看到日志记录.但他不能创建伪记录,而且他也不能对现有记录进行修改或删除. 

警告:GRANT ALL 目前包括 RULE (规则)权限.这意味着赋予权限的用户可以删除规则,做修改和重新安装之.我想这些可能很快就会改变.

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

规则与触发器之比较
许多用触发器可以干的事情同样也可以用 Postgres 规则系统来完成.目前不能用规则来实现的东西是某些约束.我们还可能在某字段的值没有在另一个表里出现的情况下用一条合格的规则把查询重写为 NOTHING.不过这样做数据就会被不声不响的被仍掉,因而这也不是一个好主意.如果需要检查有效的值,而且如果是无效值出现时要生成一个错误信息,这种情况下现在我们要用触发器来做. 
另一方面,一个用于 INSERT 一个视图的触发器可以做到与规则一样,把数据放到另外的地方去而取代对视图的插入.但它不能在 UPDATE 或 DELETE 时做同样的事情,因为在视图关系里没有可供扫描的真实数据因而触发器将永远不被调用.这时只有规则可用. 

对于两者都可用的情况,哪个更好取决于对数据库的使用.触发器用于任何涉及到一次的行.规则修改分析树或生成另外一个.所以如果在一个语句中涉及到多行,一个生成一个额外查询的规则通常可能会比一个对每一行都分别执行一次的触发器要好一些. 

例如:这里有两个表 

    CREATE TABLE computer (
        hostname        text     -- indexed
        manufacturer    text     -- indexed
    );

    CREATE TABLE software (
        software        text,    -- indexed
        hostname        text     -- indexed
    );
两个表都有好几千行,并且 hostname 是唯一的.hostname 字段包含计算机完全合格的域名.规则/触发器应该对来自软件的删除已删除主机的行的动作进行约束.因为触发器在每个独立的行删除的时候都要调用,它可以使用下面语句 
    DELETE FROM software WHERE hostname = $1;
写在一个准备好了并且保存了的规划里,把 hostname (主机名)作为参数传递.规则应该这样写 
    CREATE RULE computer_del AS ON DELETE TO computer
        DO DELETE FROM software WHERE hostname = OLD.hostname;
现在我们看看这两种不同的删除.在下面情况 
    DELETE FROM computer WHERE hostname = 'mypc.local.net';
对表 computer 使用索引(快速)进行扫描并且由触发器声明的查询也用索引进行扫描(同样快速).规则里多出来的查询是一个 
    DELETE FROM software WHERE computer.hostname = 'mypc.local.net'
                           AND software.hostname = computer.hostname;
因为已经建立了合适的索引,优化器将创建一个下面的规划 
    Nestloop
      ->  Index Scan using comp_hostidx on computer
      ->  Index Scan using soft_hostidx on software
所以在规则和触发器的实现之间没有太多的速度差别.下面的删除我们希望删掉所有 2000 个以 'old' 开头的计算机.有两个可能的用于这个用途的查询.一个是 
    DELETE FROM computer WHERE hostname >= 'old'
                           AND hostname <  'ole'
这样的规则查询的规划将会是 
    Hash Join
      ->  Seq Scan on software
      ->  Hash
            ->  Index Scan using comp_hostidx on computer
另一个可能的查询是 
    DELETE FROM computer WHERE hostname ~ '^old';
它的执行规划是 
    Nestloop
      ->  Index Scan using comp_hostidx on computer
      ->  Index Scan using soft_hostidx on software
这表明,优化器不能认识到表 computer 的 hostname (计算机主机名)的资格(条件)在多个资格表达式以 AND (与)的方式组合在一起时同样可以用于 software (软件),就象在用规则表达式的查询里一样.触发器将在任何 2000 个要被删除的旧计算机里被调用一次,结果是对 computer 的一次索引扫描和对 software 的2000次索引扫描.规则的实现将在两个对索引的查询实现之.所以这是由 software 表的实际大小决定规则进行了顺序扫描后是否还是快一些.2000 个在 SPI 管理器上的查询的执行是要点时间的,即使所有要使用的索引块都很快在缓冲里出现. 
我们看看最后一个查询 

    DELETE FROM computer WHERE manufacurer = 'bim';
同样,这也会导致从 computer 表里的多行删除.所以触发器同样会向执行器提交很多查询.但规则规划又将是对两个 IndexScan (索引扫描)的 Nestloop (内部循环).只对 computer 用另外一个索引: 
    Nestloop
      ->  Index Scan using comp_manufidx on computer
      ->  Index Scan using soft_hostidx on software
从规则查询出来的东西是 
    DELETE FROM software WHERE computer.manufacurer = 'bim'
                           AND software.hostname = computer.hostname;
在任何一个情况下,从规则系统出来的额外查询都或多或少与查询中涉及到的行的数量相对独立. 
另一情况是(更新)UPDATE,这时某字段的更改决定一个规则动作(action)是否被执行.在 Postgres 版本 6.4 里,对规则事件的字段/属性声明被取消了(将在 6.5 晚些版本,也可能早些的版本中恢复-耐心点).所以现在创建象在 showlace_log 里那样的规则的唯一的办法是用一个规

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]  下一页

[数据载入中...] [返回上一页] [打 印]