SQL Server - 如何管理表中的分层数据?

use*_*312 2 sql t-sql sql-server sql-server-2000

我使用SQL Server 2000.

假设我有两个表,如下所示:

Area
----------------------------------
ID| Name   | HierarchyLevel
----------------------------------
1 | World  |     1
2 | America|     2
3 | Europe |     2
4 | Africa |     2
5 | USA    |     3
Run Code Online (Sandbox Code Playgroud)

AreaHierarchy
------------------------
ID | ParentID | ChildID
------------------------
 1 |   1      |    2
 2 |   1      |    3
 3 |   1      |    4
 4 |   2      |    5
Run Code Online (Sandbox Code Playgroud)

哪里

AreaHierarchy.ParentID和AreaHierarchy.ChildID是Area.ID的FK

我怎样才能找到美国的第n位父母?

没有循环可能吗?

可能不是.

Rob*_*nik 5

没有循环,没有递归

最好的办法是在第二个表中添加额外的字段,即调用ie.Parents并将简单地将父ID存储在一个字符串中,如:

AreaHierarchy
------------------------------------
ID | ParentID | ChildID | Parents
------------------------------------
 1 |    1     |    2    | 1/
 2 |    1     |    3    | 1/
 3 |    1     |    4    | 1/
 4 |    2     |    5    | 1/2/
Run Code Online (Sandbox Code Playgroud)

这样,您可以轻松访问分支中的任何父级,而无需递归或任何其他复杂的过程.处理成本非常小,您只需复制父级的Parents值并再添加一个ID.而且,由于您可能需要阅读更多而不是写入/更新,因此这是解决您问题的最佳方案.

如果我是你,我会为你拥有的数据保留一张表.将两个表合并为一个.也可以根据Parentsvarchar值中的计数斜杠计算级别,但我不建议这样做.

您应该注意的额外"捕获"

如果您的数据主要是读/写和更少的更新,这种结构确实非常高效.但是,如果您的表执行的更新比读/写更多,则应避免使用此技术.为什么?想象一下,你有一棵很深的树,有很多孩子.在根附近将某个节点的父节点更改为高位意味着您应该更新Parents整个子树节点.

  • 这是真的,你可以解析应用程序中的字符串.但是你紧紧地将数据库实现绑定到应用程序,这在我的世界中是不好的做法.这完全取决于规模和可维护性. (3认同)