回答

收藏

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

技术问答 技术问答 436 人阅读 | 0 人回复 | 2023-09-14

我很好奇,关于数据库设计,什么是处理层次结构的最佳方法(最佳实践)。这是我通常如何处理它们的一个小例子。
5 a3 ]5 d; a! N9 v9 x节点表" R, l' o5 k, t3 @" V
NodeId int PRIMARY KEY" p) N. @' K, _5 p3 G  e3 d7 Q
NodeParentId int NULL
4 a! i; j4 L  c. U1 k5 W% JDisplaySeq int NOT NULL, s5 c9 Z) c3 R! x: H
Title nvarchar(255)
% a- y* Q) m3 Z# q* P3 q祖先表1 V- H% l9 v6 A9 p- X/ b* a; s* g
NodeId int" K4 A3 ]. ]+ _7 h
AncestorId int
6 k' i; J& O( M  oHops int
& d6 i( r+ b/ N* _在NodeId,AncestorId,Hops上具有索引  y+ \8 r5 [7 w0 A  k% {
表格如下所示:8 B# l4 [# h" j' V/ }
节点表
" u. Y5 b) B: oNodeId    NodeParentId    DisplaySeq    Title
3 G, J- O( u8 |+ V8 {6 v& _$ _* p1         NULL            1             'Root'7 n3 c5 w) I" a6 t) k3 j7 b& M5 W
2         1               1             'Child 1'
6 V5 J. F( l  \( @% X. Y  n) H3         1               2             'Child 2'
( u  w8 J3 x; n" q% r) m; a4         2               1             'Grandchild 1'
, D6 k! p3 p' \+ l0 z1 c# c4 b9 L5         2               2             'Grandchild 2'
2 C$ U* t5 \; ]祖先表
' e# n0 \1 y) v( R0 B" g+ T/ @5 ?NodeId    AncestorId    Hops% J0 O5 u3 H1 g- l7 d' i& M
1         NULL          0% s8 W. F" ]9 i% q) e! B
1         1             0
! g& S/ O' R8 m" G) A* ^8 y8 B( I2         1             1
* N  _0 R3 {- S( i- A2         2             0. x8 M+ Y; B8 R% r4 y4 C
3         1             1
# G$ P1 B2 P: k1 W3         3             0
: e- i% |( M  R0 H; H( }4         1             2. S) _, V7 s. W
4         2             1
, A6 X9 u. S1 c  U4         4             0# ~8 \1 v( R; Q; Z
5         1             2/ n) }+ `+ b8 h& U& `5 o5 q
5         2             1
5 h. y% B6 [1 X( l$ t5         5             0
7 m7 a5 ?0 q) o' _, I通过这种设计,我发现在大型层次结构中,通过加入AncestorId = target0 L& G) D' i& m! ~9 }8 ?: t
NodeId的Ancestor表,可以非常快速地获得层次结构的整个部分,例如:
5 M/ }) e* N' Y+ _/ E! ~; jSELECT *2 g. S1 {/ |9 S
FROM Node n
9 u% k& B" y& Q. N8 gINNER JOIN Ancestor a on a.NodeId=n.NodeId6 C& _8 X! }( k; r, v4 k( z8 F; o
WHERE a.AncestorId = @TargetNodeId
: s! H7 H. e% R, [也很容易找到直系孩子
1 a+ ^, o! N, OSELECT *9 T4 {) \/ N) p/ g# [4 R% N
FROM Node n
+ B" {; K0 j* M# H& ~INNER JOIN Ancestor a on a.NodeId=n.NodeId/ b; O( n$ d/ `% e0 c
WHERE a.AncestorId = @TargetNodeId1 x1 C$ }1 w5 b& c
AND Hops = 1
: ?+ q% v  o( J( s$ I4 H我有兴趣知道您可能还针对此类事情使用了哪些其他解决方案。以我的经验,层次结构可能会变得很繁琐,而任何优化其检索的方法都非常重要。' `; z+ l" h$ {. U' q. J
                ; V$ {) N& V( C6 c0 {% Q8 {2 ?  A
解决方案:0 z% S9 N2 T7 O  u' W. e
               
5 [5 E5 m9 {) B, R) L6 f2 F  @7 y- i* e# p( k" [: _

- g: r" q' Y+ L: P0 [5 R                正如MarkusQ和n8wrl所指出的那样,Joe1 P8 w8 ~: L+ [4 n
Celko在这方面有一些不错的东西。我要补充一点,有多种方法可以对层次结构进行建模(Joe的书包含了许多我相信的内容,而不仅仅是他认为“最好”的一种方法)。您的最终决定将希望考虑您自己的特定需求。对它进行建模的一些不同方法更适合于写密集型操作,而其他一些方法则适合于频繁或快速地上下读取层次结构。只需记住您的系统将使用它做什么。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则