回答

收藏

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

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

我很好奇,关于数据库设计,什么是处理层次结构的最佳方法(最佳实践)。这是我通常如何处理它们的一个小例子。
+ a4 v& j! ^( ]* k+ w6 B' W7 `节点表* X& M0 h5 V& l6 M% S: A
NodeId int PRIMARY KEY, v* p' v0 L! V" o6 O6 r
NodeParentId int NULL
0 J7 J0 b5 p- V! lDisplaySeq int NOT NULL
( N6 L5 s$ J6 y1 V8 z) @Title nvarchar(255)7 b5 |( x7 W5 T/ Z2 Z7 c# s
祖先表! N+ q4 g& E# w# A
NodeId int
+ d+ T; n; \( o2 a( x8 XAncestorId int6 R3 l# I9 ]. Q* I9 F$ Q( U
Hops int
+ K1 e/ R% A  y在NodeId,AncestorId,Hops上具有索引1 p6 c$ E' L+ S+ F# M, a7 p
表格如下所示:0 F# I1 q  W/ c0 c( d& y. ~
节点表
& L9 _+ w# ?+ V" r2 q( `NodeId    NodeParentId    DisplaySeq    Title6 z2 S& L0 ]& h7 _
1         NULL            1             'Root'# j+ L; n6 y5 G" a( n
2         1               1             'Child 1'
' I7 P& q2 y) J" ]3         1               2             'Child 2'
+ S8 R% }+ h: ]4         2               1             'Grandchild 1'8 u; e; `5 I( k$ y2 [9 V2 O: Y. a1 \
5         2               2             'Grandchild 2'. J8 E( g2 t, B/ y# C( w8 {  I
祖先表
+ t. ~/ h: ]+ \+ E! R& gNodeId    AncestorId    Hops- b1 }) I2 W* C* R2 a8 p
1         NULL          0
5 Q6 l9 h" D& ?  H6 o6 ]1         1             09 `2 k2 J1 A$ k5 `( @/ i( U
2         1             1
, d9 n6 Z% \( J& |+ H1 o# v2         2             0) f+ J0 p6 ]0 n6 v9 \& d) Q
3         1             1) W: r' ~- f+ Y4 K6 Z3 W# d
3         3             0
0 }0 [1 _4 I6 M4 ^4         1             2
/ L$ x" |; e/ G9 W% _4         2             1* M0 a/ c; W2 z* |) `" ?- B% z
4         4             0
1 m1 P+ p6 S1 F0 l  R2 k6 N6 H5         1             2. x0 c/ p% o- m/ p6 Q! y6 G7 U
5         2             1
" L% z, ?" {" e5         5             0
% S; s* r# P* |8 a0 ^3 r2 a) }通过这种设计,我发现在大型层次结构中,通过加入AncestorId = target1 D3 m0 h' D/ r2 @0 y: @# \
NodeId的Ancestor表,可以非常快速地获得层次结构的整个部分,例如:
) n4 s; r# i$ P7 [8 e1 ZSELECT *
3 j3 I2 O+ ?( e$ N3 PFROM Node n& N- L+ Z. ^+ J. V! \! f9 f5 k
INNER JOIN Ancestor a on a.NodeId=n.NodeId' I3 c" E7 X% g" D& x$ z8 M3 f
WHERE a.AncestorId = @TargetNodeId7 u, v7 m* y4 O7 d/ g6 m
也很容易找到直系孩子1 \; Q1 ]5 k3 O, G( f5 G
SELECT *) S) R  u1 g! B5 \' [0 `0 P
FROM Node n
! P' w$ x2 _# l. e* bINNER JOIN Ancestor a on a.NodeId=n.NodeId
0 |: A! W) X4 }WHERE a.AncestorId = @TargetNodeId
1 Q/ x# I4 I0 E) H( MAND Hops = 1, j& m4 m; i5 a! u
我有兴趣知道您可能还针对此类事情使用了哪些其他解决方案。以我的经验,层次结构可能会变得很繁琐,而任何优化其检索的方法都非常重要。( q$ Z" Q4 O4 k: P
                " B" I- m2 G( s$ f
解决方案:
- {6 Q+ s' }! L9 y$ }' L; X                " x+ \  N' r# v% J2 i
+ [7 H0 `' O5 \- h* j/ E- o

5 X" c2 q& u  k, \- G. e6 {7 G) S                正如MarkusQ和n8wrl所指出的那样,Joe
/ Y/ _; B  H7 Y# ]5 d! a1 tCelko在这方面有一些不错的东西。我要补充一点,有多种方法可以对层次结构进行建模(Joe的书包含了许多我相信的内容,而不仅仅是他认为“最好”的一种方法)。您的最终决定将希望考虑您自己的特定需求。对它进行建模的一些不同方法更适合于写密集型操作,而其他一些方法则适合于频繁或快速地上下读取层次结构。只需记住您的系统将使用它做什么。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则