我们希望在 SQL Server 2012 中存储一个简单的 Web 导航菜单。这将为多个客户端完成,这就是我们需要存储它的原因。菜单项还需要有一个顺序,以便可以按照客户想要的方式排序。我一直在阅读 SQL Server 的 HierarchyId 数据类型,但我发现的几乎所有教程都使用员工或公司层次结构的示例,其中一个根节点位于顶部。经过几个小时的阅读和测试后,我有一种感觉,HierarchyId 可能不是简单的链接导航菜单的最佳工具。我已经厌倦了这种感觉吗?
我注意到 HierarchyId 让我担心的主要一点是你只能有一个具有 HierarchyId 的根节点。但是对于导航菜单,显然有多个顶级“根节点”可以生 child 的。由于根节点没有顺序(它们只是“/”),我们的客户将无法移动其顶级菜单链接。
因此,显而易见的选择是有一个虚拟根节点,并将所有顶级菜单链接都放在该根节点下。但根据 至 this SO question 、 marc_s 和 Jeremy 看起来似乎不寻常(或者根据 HierarchyId 的正常用法) 创建一个人工“über-root”节点,只是为了拥有多个 一级节点。通过执行这个“über-root”节点,我不也是 抛弃 SQL Server 的 GetLevel() 函数,因为 “顶级”节点现在将显示为级别 1 而不是 0?
我正在考虑采用在每行中存储 ParentId 的方法,并在 C# 中使用递归来构建菜单层次结构。我这样做会错吗? HierarchyId 数据类型真的适用于这种情况吗?我只是遗漏了一些东西?
最佳答案
我认为我不会担心有一个“虚拟”根节点 - 你显然不必显示它(并且在某些方法中,你甚至不必将根节点存储在数据库中,如果你对你的询问很谨慎)。
任何有根树都需要一个根,并且任何有根树都可以分解为单独的有根树,即
A
/ \
B C => B C
/ \ \ / \ \
D E F D E F
换句话说,您始终可以通过引入公共(public)根来组合多个树。
我相信您问题的核心是如何在数据库中存储分层数据。
共有三种“经典”方法:
- “邻接列表”(我相信这就是您提到“在 C# 中使用递归”时所暗示的内容
- “层次结构路径”(这是您通过 sql server 层次结构 ID 获得的内容)
- “嵌套集”(包含基于集合的 sql 方法)
其中任何一个都适合存储分层数据 - 它们在不同类型查询的性能和表示的方便性方面有不同的权衡。
引用文献:
关于sql-server - SQL Server HierarchyId 和存储简单的 Web 导航菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17934299/