4.1模型的映射
我将它简化一下仅保留item、attributeGroup和relationship, 如下
<!--[endif]--> CREATE TABLE identifierObject ( id INTEGER PRIMARY KEY ) ; CREATE TABLE itemObject ( ) INHERITS (identifierObject); CREATE TABLE item ( ) INHERITS (itemObject); CREATE TABLE relationship ( id INTEGER PRIMARY KEY, source INTEGER NOT NULL REFERENCES item (id) ON UPDATE CASCADE ON DELETE CASCADE, destination INTEGER NOT NULL REFERENCES item (id) ON UPDATE CASCADE ON DELETE CASCADE, UNIQUE(source, destination) ) INHERITS (itemObject); CREATE TABLE attributeGroup ( id INTEGER PRIMARY KEY, ownerid INTEGER NOT NULL REFERENCES item (id) ON UPDATE CASCADE ON DELETE CASCADE ) INHERITS (identifierObject); CREATE INDEX a_idx ON relationship (source); CREATE INDEX b_idx ON relationship (destination); CREATE INDEX c_idx ON attributeGroup (ownerid);-–确保它不与自己发生关系ALTER TABLE relationship ADD CHECK (source <> destination) ;
现在模型建立好了,我们可以开始对它进行操作了.
4.1.1创建
这个不用说了吧
4.1.2删除
删除一个条目
DELETE FROM item WHERE id = 2; --因为相关的relationship和attributeGroup有CASCADE选项,与之相关的关系和属性组会自动删除
删除一个关系
DELETE FROM relationship WHERE id = 3;
删除一个属性组
DELETE FROM attributeGroup WHERE id = 6;
4.1.3更新
这个不用说了吧
4.1.4查询
呵呵,普通查询我就不说了,我们说说图查询吧.
4.1.4.1简单一级的查询
查询id为1的条目相邻的条目
<!--[endif]--> SELECT * FROM item n LEFT JOIN relationship e ON n.id = e.source WHERE e.id = 1; -- 查询id为1的条目相邻的条目
4.1.4.2复杂一点的递归查询
从id为1的条目出发,询它沿关系能到达的条目,并返回路过的中间节点的个数和路径
<!--[endif]--> WITH RECURSIVE transitive_closure(source, b, distance, path_string) AS( SELECT source, destination, 1 AS distance, source || '.' || destination || '.' AS path_string FROM relationshipWHERE source = 1 -- source UNION ALL SELECT tc.source, e.destination, tc.distance + 1, tc.path_string || e.destination || '.' AS path_string FROM relationship AS e JOIN transitive_closure AS tc ON e.source = tc.destination WHERE tc.path_string NOT LIKE '%' || e.destination || '.%')SELECT * FROMtransitive_closure
4.2讨论
我对postgresql进行过测试,在这种继承结构下,它是很低效的,一般来说你对一个父表进行查询时,它会依次对派生表进行查询的,当派生表太多时,它的查询时候基本上变成了你查询每一个表的时间总和的三分之一(这好像是依赖于查询的并发数)。此外继承还有一定的局限性。
因此我想既然item表中没有用户定义的属性,那么父条目与子条目的属性是相同的(有一些系统定义的属性),那么条目(item)的继承我们可以不用表继承的方式实现,而是加入一个表示它的类型的字段。当你查询指定类型的条目时,可以在where中加上一个 type = x的过滤表过式,而这个表示类型的字段的设计请参见层次型枚举。
将对象的类型改成一个字段来表示,还有一个好处就是用户可以更改对象的类型,而这样子更符合面向对象的思想。
5.后记呵呵,这个数据库是我为公司设计一个CMDB原型时开始构思的,花了8天完成了本文。其间对数据库了解从仅知道简单的Select到了解分区、物化视图、自定义操作符、公共表表达式(Common Table Expression,CTE)。感谢Google,让我可以查到大量的资料。
原文:http://www.cnblogs.com/runner-mei/archive/2010/09/15/1826219.html
本文链接:http://www.blueidea.com/tech/program/2010/7966.asp
出处:博客园
责任编辑:bluehearts
上一页 GraphDatabase在关系数据库中的实现 [7] 下一页
◎进入论坛网络编程版块参加讨论
|