原文链接:www.pilishen.com/posts/an-in…

此文档是 nestedset-无限分类正确姿势的扩展阅读

本文翻译自维基百科Nested set model

nested set model(嵌套集合模型)是一种在关系型数据库中表示nested sets(嵌套集合) 的特殊技术。[nested sets]通常指的是关系树或者层级关系。这个术语是由 Joe Celko清晰的提出来的,还有人使用不同的术语来描述这一技术。

诱因

该技术的出现解决了标准关系代数和关系演算以及基于它们的SQL操作不能直接在层次结构上表示所有期望操作的问题。层级可以用parent-child relation (父子关系)术语来表示 - Celko称之为 [adjacency list model],但是如果可以有任意的深度,这种模型不能用来展示类似的操作比如比较两个元素的层级或者确定一个元素是否位于另一个元素的子层级,当一个层级结构是固定的或者有固定的深度,这种操作必须通过每一层的 relational join (关系连接)来实现。但是这将很低效。这通常被称为物料清单问题。

通过切换到图形数据库,可以很容易地表达层次结构。另外在一些关系型数据库系统中存在并提供了这种关系模型的解决方案:

  • 支持专门的层级结构数据类型,比如SQL的hierarchical query facility(层级查询工具)。
  • 使用层级操作扩展关系型语言,比如 nested relational algebra。
  • 使用transitive closure扩展关系型语言,比如SQL的CONNECT语句;这可以在parent-child relation 使用但是执行起来比较低效。
  • 层级结构查询可以在支持循环且包裹关系的操作的语言中实现。比如 PL/SQL, T-SQL or a general-purpose programming language

当这些解决方案没被提供或不容易实现,就必须使用另一种方法

技术

嵌套集模型是根据树遍历来对节点进行编号,遍历会访问每个节点两次,按访问顺序分配数字,并在两次访问中都分配。这将为每个节点留下两个数字,它们作为节点两个属性存储。这使得查询变得高效:通过比较这些数字来获得层级结构关系。但是更新数据将需要给节点重新分配数字,因此变得低效。尽管很复杂但是可以通过不使用整数而是用有理数来改进更新速度。

例子

在衣服库存目录中,衣服可能会更加层级机构来分类:

处于层级结构顶端的Clothing分类包含所有的子类,因此它的左值和右值分别赋值为1和22,后面的值即这里的22是展现的所有节点总数的两倍。下一层级包含Men's和Women's两子类,各自包含必须被计算在内的层级。每一层的节点都根据它们包含的子层级来给左值和右值赋值。如上表所示。

表现

使用nested sets 将比使用一个遍历adjacency list的储存过程更快,对于天生缺乏递归的查询结构也是更快的选择。比如MySQL.但是递归SQL查询语句也能提供类似“迅速查询后代”的语句并且在其他深度搜索查询是更快,所以也是对于提供这一功能的数据库的更快选择。例如 PostgreSQL,[5]  Oracle,[6]  and Microsoft SQL Server.[7]

缺点

The use case for a dynamic endless database tree hierarchy is rare. The Nested Set model is appropriate where the tree element and one or two attributes are the only data, but is a poor choice when more complex relational data exists for the elements in the tree. Given an arbitrary starting depth for a category of 'Vehicles' and a child of 'Cars' with a child of 'Mercedes', a foreign key table relationship must be established unless the tree table is naively non-normalized. Attributes of a newly created tree item may not share all attributes with a parent, child or even a sibling. If a foreign key table is established for a table of 'Plants' attributes, no integrity is given to the child attribute data of 'Trees' and its child 'Oak'. Therefore, in each case of an item inserted into the tree, a foreign key table of the item's attributes must be created for all but the most trivial of use cases. If the tree isn't expected to change often, a properly normalized hierarchy of attribute tables can be created in the initial design of a system, leading to simpler, more portable SQL statements; specifically ones that don't require an arbitrary number of runtime, programmatically created or deleted tables for changes to the tree. For more complex systems, hierarchy can be developed through relational models rather than an implicit numeric tree structure. Depth of an item is simply another attribute rather than the basis for an entire DB architecture. As stated in SQL Antipatterns:[8]

Nested Sets is a clever solution – maybe too clever. It also fails to support referential integrity. It’s best used when you need to query a tree more frequently than you need to modify the tree.[9]

The model doesn't allow for multiple parent categories. For example, an 'Oak' could be a child of 'Tree-Type', but also 'Wood-Type'. An additional tagging or taxonomy has to be established to accommodate this, again leading to a design more complex than a straightforward fixed model. Nested sets are very slow for inserts because it requires updating left and right domain values for all records in the table after the insert. This can cause a lot of database stress as many rows are rewritten and indexes rebuilt. However, if it is possible to store a forest of small trees in table instead of a single big tree, the overhead may be significantly reduced, since only one small tree must be updated. The nested interval model does not suffer from this problem, but is more complex to implement, and is not as well known. It still suffers from the relational foreign-key table problem. The nested interval model stores the position of the nodes as rational numbers expressed as quotients (n/d). [1](//www.sigmod.org/publications/sigmod-record/0506/p47-article-tropashko.pdf)

变体

使用上面描述的nested set modal 在一些特定的树遍历操作上有性能限制。比如根据父节点查找直接子节点需要删选子树到一个指定的层级如下所示:

SELECT Child.Node, Child.Left, Child.Right
FROM Tree as Parent, Tree as Child
WHEREChild.Left BETWEEN Parent.Left AND Parent.RightAND NOT EXISTS (    -- No Middle NodeSELECT *FROM Tree as MidWHERE Mid.Left BETWEEN Parent.Left AND Parent.RightAND Child.Left BETWEEN Mid.Left AND Mid.RightAND Mid.Node NOT IN (Parent.Node AND Child.Node))AND Parent.Left = 1  -- Given Parent Node Left Index
复制代码

或者:

SELECT DISTINCT Child.Node, Child.Left, Child.Right
FROM Tree as Child, Tree as Parent
WHERE Parent.Left < Child.Left AND Parent.Right > Child.Right  -- associate Child Nodes with ancestors
GROUP BY Child.Node, Child.Left, Child.Right
HAVING max(Parent.Left) = 1  -- Subset for those with the given Parent Node as the nearest ancestor复制代码

当查询不止一层深度的子节点的时候,查询将更加的复杂,为了突破限制和简化遍历树,在模型上增加一个额外的字段来维护树内节点的深度:

在这个模型中,找到指定父节点的紧跟直接子节点可以使用下面的SQL语句实现:

SELECT Child.Node, Child.Left, Child.Right
FROM Tree as Child, Tree as Parent
WHEREChild.Depth = Parent.Depth + 1AND Child.Left > Parent.LeftAND Child.Right < Parent.RightAND Parent.Left = 1  -- Given Parent Node Left Index
复制代码

嵌套集合模型(Nested set model)介绍相关推荐

  1. 用集合return多个值_Laravel + Nestedset 扩展:嵌套集合模型实现无限级分类

    一.两种分层数据模型 分层数据(Hierarchical Data),比如无限级分类菜单.省市区分级等,类似于树型数据结构,在 MySQL 等关系型数据库中不能很自然的展示这种父-子关系,常见的实现模 ...

  2. Stata:嵌套Logit模型(NestedLogit)

    原文链接:https://www.lianxh.cn/news/d5e00bfb17a7c.html 致谢: 这篇推文的核心内容主要来自陈强老师编著的<高级计量经济学及 Stata 应用> ...

  3. R语言贝叶斯广义线性混合(多层次/水平/嵌套)模型GLMM、逻辑回归分析教育留级影响因素数据...

    全文下载链接:http://tecdat.cn/?p=24203 本教程使用R介绍了具有非信息先验的贝叶斯 GLM(广义线性模型) (点击文末"阅读原文"获取完整代码数据). 当前 ...

  4. 聚类(1)——混合高斯模型 Gaussian Mixture Model

    聚类系列: 聚类(序)----监督学习与无监督学习 聚类(1)----混合高斯模型 Gaussian Mixture Model 聚类(2)----层次聚类 Hierarchical Clusteri ...

  5. CSS的盒子模型(Box Model)

    盒子模型(Box Model)是 CSS 的核心,现代 Web 布局设计简单说就是一堆盒子的排列与嵌套,掌握了盒子模型与它们的摆放控制,会发现再复杂的页面也不过如此. 然而,任何美好的事物都有缺憾,盒 ...

  6. nested set model应用系列文章-基于后根跳跃遍历的规则匹配算法

    红猪,饿了么资深PHP,专注后端搬砖 前言 本篇文章是<nested set model应用系列文章>的第一篇文章,更多nested set model应用相关的文章,欢迎持续关注我们的专 ...

  7. 模型思维-THE MODEL THINKER

    序言这本书是怎样写成的 Part1为什么需要模型思维 01做一个多模型思考者 使用模型来思考能够带给你的,远远不仅仅是工作绩效的提高.它还会使你成为一个更优秀的人,让你拥有更强的思考能力.你将更擅长评 ...

  8. 基于R语言混合效应模型(mixed model)案例研究

    全文链接: http://tecdat.cn/?p=2596 在本文中,我们描述了灵活的竞争风险回归模型.回归模型被指定为转移概率,也就是竞争性风险设置中的累积发生率(点击文末"阅读原文&q ...

  9. 什么是扩散模型(Diffusion Model)?

    扩散模型是什么?如何工作以及他如何解决实际的问题 在计算机视觉中,生成模型是一类能够生成合成图像的模型(文本生成图像[DALL2.Stable Diffusion].图像生成图像[Diffusion- ...

最新文章

  1. 【spring框架】spring整合hibernate初步
  2. [architecture]-ARMV7架构下SecureMonitor双系统切换时保存和恢复哪些寄存
  3. 经典C语言程序100例之六三
  4. # XAMPP 配置密码大全修改默认密码
  5. php if多条件_通过几个案例掌握shell编程条件分支结构
  6. 如何修改VS编译器的背景图:快来换属于你的背景图!!!!!
  7. redis和sqlserver数据同步_数据库和redis同步数据
  8. 2015再谈游戏同步
  9. 服务器网卡支持热插拔吗,HDMI接口能“热插拔”吗?这篇告诉你
  10. build/envsetup.sh 简介
  11. Junit4 initializationError初始化错误 终于解决了!!!
  12. Java 中Calendar的使用
  13. 台式计算机能不能安装蓝牙驱动,台式电脑蓝牙驱动安装失败怎么办?台式电脑蓝牙驱动安装失败解决办法...
  14. vnr光学识别怎么打开_小区安装家用防盗报警系统方案
  15. OpenCV——PS 滤镜, 浮雕效果
  16. Shell最全大括号{}、中括号[]、小括号()用法实例
  17. 搜索计算机文件夹的记录怎么删除,怎样删除电脑最近打开的文件或文件夹?
  18. .php on line 0,PHP Fatal error: Could not queue new timer in Unknown on line 0
  19. 白加黑过360启动项工具源码发布 多文件过启动项代码
  20. 看漫画学python下载_用 Python 下载漫画

热门文章

  1. android 无线视频,Android系统无线视频流媒体的接收、解码与播放
  2. linux新建samba账户,ubuntu上创建账户和samba用户
  3. 【算法系列之十四】最大子序和
  4. 关于mysql的cpu占用高的问题
  5. composer升级_Composer-命令简介
  6. Java JUC工具类--Future
  7. 安卓布局参数类LayoutParams
  8. 深度卷积神经网络CNNs的多GPU并行框架及其应用
  9. 加入初创企业需要想清楚的几个问题
  10. 解决:XXX类存在 却报错 Unkonwn class:‘XXX‘ 、@Autoeired 注入失败