在关系数据库中存储分层数据有哪些选项?
良好的概述
一般而言,您正在快速读取时间(例如,嵌套集)或快速写入时间(邻接列表)之间做出决定。 通常情况下,您最终会得到最适合您需求的选项组合。 以下内容提供了一些深入的解读:
选项
我知道的和一般特征:
LEFT(lineage, #) = '/enumerated/path'
) 数据库特定注释
MySQL的
神谕
PostgreSQL的
SQL Server
我最喜欢的答案是这个主题中的第一句话提示。 使用邻接列表来维护层次结构并使用嵌套集来查询层次结构。
迄今为止的问题是,从Adjacecy List到Nested Sets的覆盖方法一直非常缓慢,因为大多数人使用称为“Push Stack”的极端RBAR方法进行转换,并且被认为是成本昂贵的方式通过邻接列表以及Nested Sets的卓越性能来达到Nirvana的简单维护。 结果,大多数人最终不得不为其中一个或另一个而定居,特别是如果有不止十万个节点等左右的情况。 使用推式堆栈方法可能需要一整天时间来对MLM人员认为是小型百万节点层级的转换进行转换。
我想我会给Celko一点点竞争力,想出一种将邻接列表转换成嵌套集合的方法,其速度看起来不可能。 以下是我的i5笔记本电脑上的push stack方法的性能。
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/
我还使用类似的方法开发了“预先聚合”的层次结构。 传销人员和制作物料清单的人对本文特别感兴趣。 http://www.sqlservercentral.com/articles/T-SQL/94570/
如果您确实停下来看看这两篇文章,请跳到“加入讨论”链接,让我知道您的想法。
这是你的问题的一个非常部分的答案,但我希望仍然有用。
Microsoft SQL Server 2008实现了两个对于管理分层数据非常有用的功能:
查看Kent Tegels在MSDN上为启动“使用SQL Server 2008建模您的数据层次结构”。 另请参阅我自己的问题:SQL Server 2008中的递归同表查询
此设计尚未提及:
多谱系列
虽然它有局限性,但如果你能承受它,它非常简单而且非常高效。 特征:
下面是一个例子 - 鸟类的分类树,所以层次结构是类别/顺序/家族/属/物种 - 物种是最低级别,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 |
这非常棒,因为只要内部类别不会在树中改变它们的级别,您就可以非常简单的方式完成所有需要的操作。
链接地址: http://www.djcxy.com/p/2735.html上一篇: What are the options for storing hierarchical data in a relational database?