我有一个PHP网的应用程序,它使用一个数据库为目标,在这我已经使用的标签结构接受的答案 这个这么问题.

我想要实现的一个标签的层次结构,其中每个标记可以有一个独特的父母的标记。搜索父母的标记T会然后匹配的所有后代的T(即T、标签的是谁的父母是T(儿童的T)、孙子女的叔,等等)。

最简单的办法,这样做似乎是添加一个ParentID场标记表,其中包含的标识标记的父母的标记,或一些神奇的数字如果标记没有父母。在寻找后裔,但是,随后需要重复进行全面搜索的数据库找到的标记在每个时代的',这是我想要避免的。

一(大概是)更快地,但较少的正规化的办法,这样做将有一个表,其中包含的所有儿童的每个标记,或甚至所有后代的每个标记。然而,这可能不一致的数据库中的数据(例如标记是儿童超过父母之一).

是有一个很好的方式来进行查询,以查找后裔快,同时保持数据作为正规化的可能吗?

有帮助吗?

解决方案 2

阿里的答案有一个指向 Joe Celko的树和层次结构的SQL for Smarties的链接,这证实了我的怀疑 - 没有一个简单的数据库结构可以提供最好的世界。对我来说最好的目的似乎是“频繁插入树”。在本书中详细说明,它类似于“嵌套集模型”。阿里的链接,但非连续索引。这允许O(1)插入( a la 非结构化BASIC行编号),并在需要时偶尔进行索引重组。

其他提示

我实现了它使用两栏。我简化这一点,因为我必须保持该标签名在一个单独的领域/表,因为我得将它用于不同的语言:

  • 标记
  • 路径

看看这些行为的例子:

tag            path
---            ----
database       database/
mysql          database/mysql/
mysql4         database/mysql/mysql4/
mysql4-1       database/mysql/mysql4-1/
oracle         database/oracle/
sqlserver      database/sqlserver/
sqlserver2005  database/sqlserver/sqlserver2005/
sqlserver2005  database/sqlserver/sqlserver2008/

等等。

使用 like 操作者的道路上场你可以很容易地得到所有必需的标签行:

SELECT * FROM tags WHERE path LIKE 'database/%'

有一些执行细节,如当时你移动的一个节点的层次,你必须改变所有的孩子太等等, 但这并不难。

另外,还要确保长的道路是足够长的时间-在我的情况下,我使用的不是签名的道路,但是另一个领域,以确保我不会太长的道路。

您可以构建Kimball称为层次结构助手表的内容。

假设您的层次结构如下所示:A - > B | B - > C | C - > d

您将记录插入到这个

的表中
ParentID, ChildID, Depth, Highest Flag, Lowest Flag
A, A, 0, Y, N
A, B, 1, N, N
A, C, 2, N, N
A, D, 3, N, Y
B, B, 0, N, N
B, C, 1, N, N
B, D, 2, N, Y
C, C, 0, N, N
C, D, 1, N, Y
D, D, 0. N, Y

我认为我有正确的......反正。关键是你仍然正确地存储你的层次结构,你只需从正确的表中构建这个表。这个表像Banshee一样查询。假设您想知道B下面的所有第一级是什么。

WHERE parentID = 'B' and Depth = 1

我会使用某种数组来存储子标签,这应该比连接表本身快得多(特别是如果你有大量的标签)。我看了一下,我不知道mysql是否有本机数组数据类型,但您可以通过使用文本列并在其中存储序列化数组来模拟它。如果你想进一步加快速度,你应该能够在该列上放置一个文本搜索索引,以找出哪些标签是相关的。

[编辑] 在阅读了阿里的文章之后,我又做了一些狩猎,并在一堆上发现了这个演示文稿。在postgres中实现层次结构的方法。可能仍然有助于解释目的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top