【发布时间】:2011-03-24 10:30:34
【问题描述】:
我有一个包含分层数据的表。此层次结构中目前有大约 8 个级别。
我真的很喜欢数据的结构方式,但是当我需要知道第 8 级的记录是否是第 1 级记录的子记录时,性能很差。
我有 PL/SQL 存储函数来为我进行这些查找,每个函数都有一个 select * from tbl start with ... connect by... 语句。当我查询少量记录时,这很好用,但我现在需要一次查询约 10k 条记录,并且为每个记录运行此函数。它需要 2-3 分钟,我需要它在几秒钟内运行。
根据我对当前数据的了解,使用一些启发式方法,我可以摆脱查找功能而只使用childrecord.key || '%' LIKE parentrecord.key,但这是一个非常肮脏的技巧,并不总是有效。
所以现在我在想,对于这个分层定义的表,我需要一个单独的父子表,其中将包含所有关系......对于从 1-8 级开始的层次结构,将有 8 个!记录,将 1 与 2、1 与 3、...、1 与 8 和 2 与 3、2 与 4、...、2 与 8 相关联。以此类推。
我的想法是,我需要有一个插入触发器,它基本上会运行connect by 查询,并且对于每个匹配层次结构的匹配,它都会在查找表中插入一条记录。为了处理旧数据,我只需使用级联删除为主表设置外键。
还有比这更好的选择吗?我是否错过了另一种可以更快地确定这些遥远的祖先/后代关系的方法?
编辑:这似乎正是我的想法:http://evolt.org/working_with_hierarchical_data_in_sql_using_ancestor_tables
【问题讨论】:
-
您的主要兴趣是回答“谁是我的最终父母”这个问题?或“谁是我的第一个定义了某些属性的父母?”如果是这样,物化视图可能比触发器更容易、更安全。
-
@Adam Musch:我很想知道是否有两条记录相互关联。您指的是触发器的哪些安全问题?未能锁定相应的记录并获取损坏的数据?
-
主要是数据损坏,是的。通过表和物化视图维护传递闭包意味着可以独立更新——触发器可以被禁用,映射表可以针对它们编写 SQL。我已经写了物化视图来寻找“上游”来回答我在之前评论中提到的问题,而不是回答通用形式“谁是 B 的所有祖先”或“A 是 B 的祖先吗?”
标签: sql oracle database-design query-optimization hierarchical-data