好的概述
一般来说,您要在快速读取时间(例如,嵌套集)或快速写入时间(邻接列表)之间做出决定。通常,您最终会得到最适合您需求的以下选项组合。以下提供了一些深入阅读:
选项
我知道和一般的功能:
O(n/2)
移动,插入,由于易失性编码而删除O(log n)
(子树的大小) LEFT(lineage, #) = '/enumerated/path'
) O(log n)
(子树的大小) 数据库特定说明
MySQL 的
神谕
PostgreSQL 的
SQL Server
我最喜欢的答案就是这个帖子中第一句话的建议。使用邻接列表维护层次结构并使用嵌套集查询层次结构。
直到现在的问题一直是从邻接列表到嵌套集的转换方法非常缓慢,因为大多数人使用称为 “推送栈” 的极端 RBAR 方法来进行转换,并且被认为是昂贵的方式通过邻接列表和嵌套集的强大性能来达到 Nirvana 的简单维护。结果,大多数人最终不得不满足于一个或另一个,特别是如果有超过 10 万个节点那么多。使用推送栈方法可能需要一整天的时间来完成 MLM'ers 认为是一个小百万节点层次结构的转换。
我想我会通过提出一种方法将 Celacency List 转换为嵌套集合,以一种看似不可能的速度给 Celko 带来一些竞争。这是 i5 笔记本电脑上推送栈方法的性能。
Duration for 1,000 Nodes = 00:00:00:870
Duration for 10,000 Nodes = 00:01:01:783 (70 times slower instead of just 10)
Duration for 100,000 Nodes = 00:49:59:730 (3,446 times slower instead of just 100)
Duration for 1,000,000 Nodes = 'Didn't even try this'
这是新方法的持续时间(在括号中使用推送堆栈方法)。
Duration for 1,000 Nodes = 00:00:00:053 (compared to 00:00:00:870)
Duration for 10,000 Nodes = 00:00:00:323 (compared to 00:01:01:783)
Duration for 100,000 Nodes = 00:00:03:867 (compared to 00:49:59:730)
Duration for 1,000,000 Nodes = 00:00:54:283 (compared to something like 2 days!!!)
对,那是正确的。在不到一分钟的时间内转换了 100 万个节点,在 4 秒内转换了 100,000 个节点。
您可以阅读有关新方法的信息,并从以下 URL 获取代码的副本。 http://www.sqlservercentral.com/articles/Hierarchy/94040/
我还使用类似的方法开发了 “预聚合” 层次结构。 MLM'ers 和制作材料清单的人将对本文特别感兴趣。 http://www.sqlservercentral.com/articles/T-SQL/94570/
如果你停下来看看这两篇文章,请跳到 “加入讨论” 链接,让我知道你的想法。
这是对你的问题的非常局部的答案,但我希望仍然有用。
Microsoft SQL Server 2008 实现了两个对管理分层数据非常有用的功能:
在 MSDN 上查看 Kent Tegels 的“使用 SQL Server 2008 建模您的数据层次结构”以获取启动。另请参阅我自己的问题: SQL Server 2008 中的递归同表查询
此设计尚未提及:
虽然它有局限性,但如果你能承受它,那就非常简单而且效率很高。特征:
下面是一个例子 - 鸟类的分类树,所以层次结构是 Class / Order / Family / Genus / Species - 物种是最低级别,1 行 = 1 个分类单元(对应于叶子节点的物种):
CREATE TABLE `taxons` (
`TaxonId` smallint(6) NOT NULL default '0',
`ClassId` smallint(6) default NULL,
`OrderId` smallint(6) default NULL,
`FamilyId` smallint(6) default NULL,
`GenusId` smallint(6) default NULL,
`Name` varchar(150) NOT NULL default ''
);
以及数据的例子:
+---------+---------+---------+----------+---------+-------------------------------+
| TaxonId | ClassId | OrderId | FamilyId | GenusId | Name |
+---------+---------+---------+----------+---------+-------------------------------+
| 254 | 0 | 0 | 0 | 0 | Aves |
| 255 | 254 | 0 | 0 | 0 | Gaviiformes |
| 256 | 254 | 255 | 0 | 0 | Gaviidae |
| 257 | 254 | 255 | 256 | 0 | Gavia |
| 258 | 254 | 255 | 256 | 257 | Gavia stellata |
| 259 | 254 | 255 | 256 | 257 | Gavia arctica |
| 260 | 254 | 255 | 256 | 257 | Gavia immer |
| 261 | 254 | 255 | 256 | 257 | Gavia adamsii |
| 262 | 254 | 0 | 0 | 0 | Podicipediformes |
| 263 | 254 | 262 | 0 | 0 | Podicipedidae |
| 264 | 254 | 262 | 263 | 0 | Tachybaptus |
这很好,因为只要内部类别不改变树中的级别,这种方式就可以非常简单的方式完成所有需要的操作。
我最喜欢的答案就是这个帖子中第一句话的建议。使用邻接列表维护层次结构并使用嵌套集查询层次结构。
直到现在的问题一直是从邻接列表到嵌套集的转换方法非常缓慢,因为大多数人使用称为 “推送栈” 的极端 RBAR 方法来进行转换,并且被认为是昂贵的方式通过邻接列表和嵌套集的强大性能来达到 Nirvana 的简单维护。结果,大多数人最终不得不满足于一个或另一个,特别是如果有超过 10 万个节点那么多。使用推送栈方法可能需要一整天的时间来完成 MLM'ers 认为是一个小百万节点层次结构的转换。
我想我会通过提出一种方法将 Celacency List 转换为嵌套集合,以一种看似不可能的速度给 Celko 带来一些竞争。这是 i5 笔记本电脑上推送栈方法的性能。
Duration for 1,000 Nodes = 00:00:00:870
Duration for 10,000 Nodes = 00:01:01:783 (70 times slower instead of just 10)
Duration for 100,000 Nodes = 00:49:59:730 (3,446 times slower instead of just 100)
Duration for 1,000,000 Nodes = 'Didn't even try this'
这是新方法的持续时间(在括号中使用推送堆栈方法)。
Duration for 1,000 Nodes = 00:00:00:053 (compared to 00:00:00:870)
Duration for 10,000 Nodes = 00:00:00:323 (compared to 00:01:01:783)
Duration for 100,000 Nodes = 00:00:03:867 (compared to 00:49:59:730)
Duration for 1,000,000 Nodes = 00:00:54:283 (compared to something like 2 days!!!)
对,那是正确的。在不到一分钟的时间内转换了 100 万个节点,在 4 秒内转换了 100,000 个节点。
您可以阅读有关新方法的信息,并从以下 URL 获取代码的副本。 http://www.sqlservercentral.com/articles/Hierarchy/94040/
我还使用类似的方法开发了 “预聚合” 层次结构。 MLM'ers 和制作材料清单的人将对本文特别感兴趣。 http://www.sqlservercentral.com/articles/T-SQL/94570/
如果你停下来看看这两篇文章,请跳到 “加入讨论” 链接,让我知道你的想法。
这是对你的问题的非常局部的答案,但我希望仍然有用。
Microsoft SQL Server 2008 实现了两个对管理分层数据非常有用的功能:
在 MSDN 上查看 Kent Tegels 的“使用 SQL Server 2008 建模您的数据层次结构”以获取启动。另请参阅我自己的问题: SQL Server 2008 中的递归同表查询
此设计尚未提及:
虽然它有局限性,但如果你能承受它,那就非常简单而且效率很高。特征:
下面是一个例子 - 鸟类的分类树,所以层次结构是 Class / Order / Family / Genus / Species - 物种是最低级别,1 行 = 1 个分类单元(对应于叶子节点的物种):
CREATE TABLE `taxons` (
`TaxonId` smallint(6) NOT NULL default '0',
`ClassId` smallint(6) default NULL,
`OrderId` smallint(6) default NULL,
`FamilyId` smallint(6) default NULL,
`GenusId` smallint(6) default NULL,
`Name` varchar(150) NOT NULL default ''
);
以及数据的例子:
+---------+---------+---------+----------+---------+-------------------------------+
| TaxonId | ClassId | OrderId | FamilyId | GenusId | Name |
+---------+---------+---------+----------+---------+-------------------------------+
| 254 | 0 | 0 | 0 | 0 | Aves |
| 255 | 254 | 0 | 0 | 0 | Gaviiformes |
| 256 | 254 | 255 | 0 | 0 | Gaviidae |
| 257 | 254 | 255 | 256 | 0 | Gavia |
| 258 | 254 | 255 | 256 | 257 | Gavia stellata |
| 259 | 254 | 255 | 256 | 257 | Gavia arctica |
| 260 | 254 | 255 | 256 | 257 | Gavia immer |
| 261 | 254 | 255 | 256 | 257 | Gavia adamsii |
| 262 | 254 | 0 | 0 | 0 | Podicipediformes |
| 263 | 254 | 262 | 0 | 0 | Podicipedidae |
| 264 | 254 | 262 | 263 | 0 | Tachybaptus |
这很好,因为只要内部类别不改变树中的级别,这种方式就可以非常简单的方式完成所有需要的操作。