处理数据库中的层次结构数据

2023-12-20

我很想知道在数据库设计方面处理层次结构的最佳方法(最佳实践)是什么。这是我通常如何处理它们的一个小例子。

节点表

NodeId int PRIMARY KEY
NodeParentId int NULL
DisplaySeq int NOT NULL
Title nvarchar(255)

祖先表

NodeId int
AncestorId int
Hops int

在 NodeId、AncestorId、Hops 上有索引

表格如下所示:

节点表

NodeId    NodeParentId    DisplaySeq    Title
1         NULL            1             'Root'
2         1               1             'Child 1'
3         1               2             'Child 2'
4         2               1             'Grandchild 1'
5         2               2             'Grandchild 2'

祖先表

NodeId    AncestorId    Hops
1         NULL          0
1         1             0
2         1             1
2         2             0
3         1             1
3         3             0
4         1             2
4         2             1
4         4             0
5         1             2
5         2             1
5         5             0

通过这种设计,我发现对于大型层次结构,我可以通过加入 AncestorId = 目标 NodeId 的 Ancestor 表来非常快速地获取层次结构的整个部分,例如:

SELECT *
FROM Node n
INNER JOIN Ancestor a on a.NodeId=n.NodeId
WHERE a.AncestorId = @TargetNodeId

获得直系孩子也很容易

SELECT *
FROM Node n
INNER JOIN Ancestor a on a.NodeId=n.NodeId
WHERE a.AncestorId = @TargetNodeId
AND Hops = 1

我有兴趣知道您可能还使用过哪些其他解决方案来解决此类问题。根据我的经验,层次结构可能会变得非常复杂,任何优化其检索的方法都非常重要。


有一些特定于供应商的扩展可以做到这一点,但我最喜欢的数据库中立方式来自 Joe Celko - 谷歌“Joe Celko Trees and Hierarchies”或购买这本书:链接文本 https://rads.stackoverflow.com/amzn/click/com/1558609202

这是一种非常聪明的基于集合的方法。易于查询层次结构。我添加了“parentID”字段,只是因为我经常询问“直接子代”和“父代”问题,这会加快这些问题的速度。但这是获取“祖先”或“后代”查询的好方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

处理数据库中的层次结构数据 的相关文章

随机推荐

  • 如何将压缩的 (gz) CSV 文件读入 dask Dataframe 中?

    有没有办法读取通过 gz 压缩到 dask 数据帧中的 csv 文件 我直接尝试过 import dask dataframe as dd df dd read csv Data gz 但出现 unicode 错误 可能是因为它正在解释压缩
  • 调用方法后按钮变量变为 null

    在我的主要活动中 我有以下片段 MainActivity class private Button btnx10 Override protected void onCreate Bundle savedInstanceState supe
  • Font Awesome、Bootstrap 和屏幕阅读器辅助功能

    我想知道使用 Twitter Bootstrap 框架和 FontAwesome 图标字体的屏幕阅读器可访问性 我正在考虑两种不同的图标情况 1 该图标具有屏幕阅读器将拾取的帮助文本 a href class btn btn default
  • 为什么 Visual Studio 2008 在 Firefox 中运行缓慢?

    我正在使用 Microsoft Visual Web Developer 2008 Express 我创建了一个 ASP NET MVC 站点 其中 Site Master 文件的 HEAD 元素中有 6 个 CSS 文件和 6 个 Jav
  • 如何使用开始/停止谓词对列表的连续元素进行分组?

    假设我有一个类似的列表 def data a b c d e f g h b d x 和谓词如 defn start x x b defn stop x x d 标记子序列的第一个和最后一个元素 我想返回一个包含子组的列表 如下所示 par
  • 有什么方法可以控制 SqlEntityConnection 上的 AutoDetectChanges 吗?

    本文 http ilmatte wordpress com 2013 01 01 entity framework code first always disable autodetectchanges when importing dat
  • C# EF Linq 按位问题

    好的 例如 我按位使用如下 星期一 1 星期二 2 星期三 4 星期四 8 等 我正在使用业务实体框架类 我正在使用一个类并传递一个像 7 这样的值 星期一 星期二 星期三 我想返回与这些日子匹配的记录 public List
  • C# 回调接收UTF8字符串

    我有一个 C 函数 一个回调 从用 C 编写的 Win32 DLL 调用 调用者给了我一个UTF8字符串 但我无法正确接收它 所有匈牙利特殊字符都出错了 UnmanagedFunctionPointer CallingConvention
  • 如何在ionic 2/3中处理数据库异步操作

    我正在 ionic 中使用数据库 我调用一个 API 该 API 返回一些记录 我必须将这些记录插入数据库以及插入操作何时完成then我想从数据库中调用选择记录 问题是异步行为 在插入操作完成之前调用从数据库中选择记录 谁能帮我解决这个问题
  • 在 PHP 中验证电子邮件地址[重复]

    这个问题在这里已经有答案了 可能的重复 如何在 PHP 中验证电子邮件地址 https stackoverflow com questions 12026842 how to validate an emailaddress in php
  • 如何按工作日顺序(如日历周)而不是按字母顺序(在 C# 中)排序?

    我无法弄清楚如何按日期对独立存储中的 XML 文件中的查询输出进行排序 该日期是 xml 文件中的值 我的意思是它将按当天的第一个字母排序 因此它将返回星期五作为第一个字母 因为其中有 F 但这不是我想要的 相反 它们应该按工作日的顺序排序
  • 从 File.OpenRead() 返回流

    我正在编写一个 WCF 服务 该服务将允许 ASP Net 网站检索文件 基于本文 http msdn microsoft com en us library ms789010 aspx Y912 我的问题是 当我返回流时 它是空白的 为简
  • WordPress wp_localize_script 是做什么的? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有人可以解释一下吗wp localize script 做 即使我在 WP Codex 中读过它 我一开始也不明白它的作用 它允许您通过打
  • 如何在使用插件时将域添加到 next.config.js 的“next/image”

    这是我当前的设置 next config js const withImages require next images module exports withImages webpack config options return con
  • 使用 Promise 在 Node.js + Express 中进行错误处理

    使用 Node js Express 4 Mongoose 使用 Promise 而不是回调 我不知道如何整理我的错误处理 我得到的 相当简化的 是 app get xxx id function request response Xxx
  • 使用reduce在Javascript中构建过滤函数

    在一次采访中 有人向我提出了一个让我摸不着头脑的问题 我不想花周末担心结果 而是想尝试解决问题 但我无法弄清楚 使用下面的reduce函数 构建一个过滤函数 该函数将一个数组和一个测试函数作为参数 并返回一个新数组 该数组已根据测试函数过滤
  • SQL ORDER BY(序列)[重复]

    这个问题在这里已经有答案了 我有一个我想要的sql语句ORDER BY特定的顺序 SELECT FROM UserDB ORDER BY Role 我怎样才能将数据带到我的GridView表从顶部的 管理员 列出 然后是 用户 和 来宾 所
  • 如何在程序中获取 _GLOBAL_OFFSET_TABLE_ 地址?

    我想在我的程序中获取 GLOBAL OFFSET TABLE 的地址 一种方法是使用nm http linux about com library cmd blcmdl1 nm htmLinux 中的命令 可能会将输出重定向到文件并解析该文
  • 传递结构数组时遇到问题

    我一生都无法弄清楚如何在整个程序中传递这个结构数组 有人可以帮忙吗 现在我在 main 中收到一个错误 内容是 标记之前预期的主要表达式 Header ifndef HEADER H INCLUDED define HEADER H INC
  • 处理数据库中的层次结构数据

    我很想知道在数据库设计方面处理层次结构的最佳方法 最佳实践 是什么 这是我通常如何处理它们的一个小例子 节点表 NodeId int PRIMARY KEY NodeParentId int NULL DisplaySeq int NOT