良好的概述
一般来说,你要在快速读取时间(例如,嵌套集)或快速写入时间(相邻列表)之间做出决定。通常,你最终会得到以下最适合你需求的选项组合。以下提供了一些深入的阅读:
选项
我所知道的和一般特征:
- 邻接表:
- 列:ID,父母ID
- 易于实施。
- 廉价的节点移动、插入和删除。
- 寻找等级,祖先和后代,路径的成本很高
- 在支持它们的数据库中通过常用表表达式避免N+1
- 嵌套集合(a. k. a修改的预排序树遍历)
- 列:左,右
- 廉价的祖先,后代
- 由于易失性编码,非常昂贵的
O(n/2)
移动、插入、删除
- 桥接表(又名闭包表 /w触发器)
- 使用具有祖先、后代、深度的单独连接表(可选)
- 廉价的祖先和后代
- 写入成本
O(log n)
(子树的大小)用于插入、更新、删除 - 标准化编码:适用于连接中的RDBMS统计和查询规划器
- 每个节点需要多行
- 宗族柱(又名物化路径,路径枚举)
- 列:血统(例如/父母/子女/孙子/等…)
- 通过前缀查询的廉价后代(例如
LEFT(lineage, #) = '/enumerated/path'
) - 写入成本
O(log n)
(子树的大小)用于插入、更新、删除 - 非关系:依赖于数组数据类型或序列化字符串格式
- 嵌套区间
- 类似于嵌套集,但使用true/浮点数/十进制,因此编码不易失性(廉价的移动/插入/删除)
- 有真实/浮点数/十进制表示/精度问题
- 矩阵编码变体为“自由”添加了祖先编码(物化路径),但增加了线性代数的复杂性。
- 平板
- 修改后的邻接列表,向每个记录添加级别和等级(例如排序)列。
- 廉价的迭代/分页
- 昂贵的移动和删除
- 良好使用:线程讨论-论坛/博客评论
- 多个沿袭列
- 列:每个血统级别一个,指的是所有的父母,直到根,从项目的级别向下的级别设置为NULL
- 便宜的祖先,后代,水平
- 廉价的插入、删除、移动叶子
- 内部节点的昂贵插入、删除、移动
- 严格限制等级制度可以有多深
数据库特定注释
mysql
Oracle
PostgreSQL
SQL服务器
- 概述
- 2008提供了层级名称数据类型,似乎有助于使用沿袭列方法并扩展可以表示的深度。