当前位置: 首页 > 面试题库 >

为分层定义的数据集创建展平的表/视图

解飞语
2023-03-14
问题内容

我有一个包含层次结构数据的表。目前,在此层次结构中大约有8个级别。

我真的很喜欢数据的结构方式,但是当我需要知道第8级记录是否是第1级记录的子级时,性能令人沮丧。

我有PL / SQL存储的函数,这些函数为我执行这些查找,每个函数都有一条select * from tbl start with ... connect by...语句。当我查询少量记录时,这种方法很好用,但是现在我需要一次查询约1万条记录,并且每个记录都运行此功能。我需要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


问题答案:

因此,您想要的是实现可传递闭包。也就是说,给定此应用程序表…

 ID   | PARENT_ID
------+----------
    1 | 
    2 |         1
    3 |         2
    4 |         2
    5 |         4

…图形表如下所示:

 PARENT_ID | CHILD_ID
-----------+----------
         1 |        2
         1 |        3
         1 |        4
         1 |        5
         2 |        3
         2 |        4
         2 |        5
         4 |        5

在Oracle中可以维护一个这样的表,尽管您需要为其滚动自己的框架。问题是这是否值得开销。如果源表是易失性的,则保持图形数据新鲜可能花费的周期比您将在查询中节省的周期更多。只有您知道数据的个人资料。

我认为您无法使用CONNECT
BY查询和级联外键来维护这样的图形表。间接活动过多,难以正确解决。物化视图也已退出,因为我们无法编写SQL查询,1->5当删除的源记录时,该查询将破坏记录ID=4

因此,我建议您阅读由Dong,Libkin,Su和Wong撰写的名为“维护SQL中的图的传递闭包”的论文。它包含许多理论和一些粗糙的(Oracle)SQL,但是它将为您构建维护图表所需的PL /
SQL提供基础。

“您能否扩展一下用CONNECT BY
/级联FK维护起来太困难的部分?如果我控制对表的访问,并且所有插入/更新/删除都是通过存储过程进行的,那么在哪种情况下会发生这种情况?分解?”

考虑1->5是短路的记录1->2->4->5。现在,如果像我之前说的那样,我们删除的源记录,该ID=4怎么办?级联外键可以删除该条目2->44->5。但是,尽管它们
不再代表 图形中 的有效边,但仍保留 在图形表中1->5(并且确实如此2->5)。 __

可能有效的方法(我想,我还没有做到)是在源表中使用附加的合成键,如下所示。

 ID   | PARENT_ID | NEW_KEY
------+-----------+---------
    1 |           | AAA
    2 |         1 | BBB
    3 |         2 | CCC
    4 |         2 | DDD
    5 |         4 | EEE

现在,图形表将如下所示:

 PARENT_ID | CHILD_ID | NEW_KEY
-----------+----------+---------
         1 |        2 | BBB
         1 |        3 | CCC
         1 |        4 | DDD
         1 |        5 | DDD
         2 |        3 | CCC
         2 |        4 | DDD
         2 |        5 | DDD
         4 |        5 | DDD

因此,图形表具有一个外键,该外键引用生成它的源表中的关系,而不是链接到ID。然后删除的记录,ID=4将会级联删除图形表中的所有记录,其中NEW_KEY=DDD

如果任何给定的ID只能有零个或一个父ID,这将起作用。但是,如果允许发生这种情况,它将无法正常工作:

 ID   | PARENT_ID
------+----------
    5 |         2
    5 |         4

换句话说,边缘1->5代表1->2->4->51->2->5。因此,可能有效的方法取决于数据的复杂性。



 类似资料:
  • 问题内容: 我有对象T的列表,它具有父属性,其中顶级对象的父属性为null。我想将所有对象放入TreeSet(或TreeMap)中。顶级对象将是所有没有父级的根对象(父级为null),并且它们的下级将是其子级。 像这样 所以我可以得到Ra并找到它的子代(Ca1,Ca2,Ca11,Ca12…。) 更新:很抱歉,可能不清楚,节点指向父节点,如果parent为null,则它们是根节点。问题是父母需要了解

  • pre { white-space: pre-wrap; } 在不同的情况下,您可能需要为数据网格(datagrid)运用更灵活的布局。对于用户来说,卡片视图(Card View)是个不错的选择。这个工具可以在数据网格(datagrid)中迅速获取和显示数据。在数据网格(datagrid)的头部,您可以仅仅通过点击列的头部来排序数据。本教程将向您展示如何创建自定义卡片视图(Card View)。

  • 我试图创建一个位于两个单元格之间的UILabel,就像表格分隔符的显示方式一样。 Swift在UITableView的内置函数中允许这样做吗? 我该怎么做呢?

  • 本文向大家介绍Android 创建自定义视图,包括了Android 创建自定义视图的使用技巧和注意事项,需要的朋友参考一下 示例 如果需要完全自定义的视图,则需要子类View(所有Android视图的超类),并提供自定义的sizing(onMeasure(...))和drawing(onDraw(...))方法: 创建您的自定义视图框架:每个自定义视图的基本相同。在这里,我们为自定义视图创建框架,

  • 问题内容: 假设我有一个用户定义的类型: 现在,我想创建一个表来保存这些类型。我可以执行以下操作: 这给了我一张只有一列的表格test_type_field。 有没有一种简单而自动化的方法来代替,以创建一个表,使其具有2列f1和f2?。这样就等同于编写: 问题答案: 你有没有尝试过:

  • 在Laravel 4中,当使用4.2文档中描述的多对多关系时,我如何让Laravel为我创建透视表? 我是否需要在我的迁移中为所涉及的两个模型添加一些东西?是否需要手动创建数据透视表的迁移?或者Laravel如何知道创建透视表? 到目前为止,我所做的一切就是将