1

我们使用具有名为 docid 的列和名为 parentid 的列的表将文档之间的关系存储在 Oracle 数据库中。如果我有一个与子文档 child1_1 和 child1_2 相关的文档 doc1,它们将由 Documents 表中的以下记录表示。

docid  parentid
1000   null    record for doc1
1001   1000    "       "  child1_1
1002   1000    "       "  child1_2

Documents 表可以有数百万行,因此为了确保在我们的 UI 中将所有相关文档分组在一起,我们使用名为 sortedfamily 的索引 varchar 列对 Documents 表进行预排序,并使用相关文档的 docid 的串联填充它. 不使用 sortedfamily 列在查询时对记录进行排序太慢。上面显示的记录变成了。

docid  parentid  sortedfamily
1000   null      1000           record for doc1
1001   1000      1000_1001      "       "  child1_1
1002   1000      1000_1002      "       "  child1_2

这允许我们在查询中添加“ordered by sortedfamily”,并且返回的记录将始终按相关文档排序。我上面概述的效果很好,但它有一些与文档族层次深度相关的限制,并且感觉很奇怪连接整数来对记录进行排序。有没有办法只使用整数来完成上述操作?

提前致谢。

更新:我上面的例子不够详细。孩子们自己也可能有相关文件。如果 child1_1 有相关文档,则 sortedfamily 的结果值可能是“1000_1001_2000”。

4

1 回答 1

5

Oracle 对分层查询有很好的支持。sortedfamily您可以在不借助列的情况下获取文档层次结构。这是查询:

SELECT docid, PRIOR docid AS "Parent"
FROM Documents
START WITH parentid IS NULL
CONNECT BY parentid = PRIOR docid
ORDER SIBLINGS BY docid

现在来解释一下:

SELECT docid, PRIOR docid AS "Parent"

这通过与操作员“回顾”来获取同一行的文档及其父PRIOR级。

START WITH parentid IS NULL

这定义了层次结构的根。具有空值的每一行都parentid被视为分支的根。

CONNECT BY parentid = PRIOR docid

这表示当前行的“父级”由parentid子级连接到docid父级。

ORDER SIBLINGS BY docid

这会按照整个层次结构而不是单个值进行排序。这很难解释,但它确实有效。

Oracle 分层查询的最佳之处在于它们将查询整个分支,因此,如果您的文档有一个有一个孩子的文档(有一个孩子,然后……),Oracle 将处理它。它还将处理每个父母的多个孩子。

这里有一个SQL Fiddle,其中包含您的数据以及一些其他文档。

Fiddle 还包含一列,使用该SYS_CONNECT_BY_PATH函数显示整个“根到分支”关系。与您的列SYS_CONNECT_BY_PATH执行相同的操作sortedfamily,但它是动态执行的,无需维护列。这也是可视化层次结构的每个分支的好方法。

附录

请注意,上面的查询将返回每个文档的每个分支。如果您只对单个文档(例如 )感兴趣,请将 替换为:docid = 1000START WITH parentid IS NULL

START WITH docid = 1000

这将为您提供docid1000 的整个分支。如果您有索引,docid它将非常快。

于 2013-05-02T03:53:22.180 回答