回答

收藏

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

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

我很好奇,关于数据库设计,什么是处理层次结构的最佳方法(最佳实践)。这是我通常如何处理它们的一个小例子。! {. R8 L, q" i; D* M7 \
节点表8 B& w0 B; H( l9 b$ x
NodeId int PRIMARY KEY
* e5 ~- J1 n0 GNodeParentId int NULL0 }& E1 U0 H, Q5 \) {, @6 {, b
DisplaySeq int NOT NULL
' A) z2 Y/ Y' r, b% [Title nvarchar(255)' c6 d3 v7 @" L' V7 O
祖先表
6 [  V, z. J9 J( Y6 ~+ _NodeId int) S; i; p' Y4 |9 j5 A, \& w
AncestorId int0 z( ^' E" R. P
Hops int2 U5 ]6 p" q! n. j, A
在NodeId,AncestorId,Hops上具有索引
2 }/ q9 H2 h6 ?" ^2 Z" h+ [0 b6 R表格如下所示:3 M! X  t, J0 y6 ^
节点表
9 V/ g2 R- B6 }, y8 |. ~0 ~NodeId    NodeParentId    DisplaySeq    Title
. z7 ]5 M9 X" W2 [3 v" a8 o- N8 c: q1         NULL            1             'Root'
0 I( [- f/ y% O# D2 W7 x9 U. e2         1               1             'Child 1'5 y- T7 m5 q; Q  W! O/ P4 y
3         1               2             'Child 2'4 ~$ L7 j: d1 S) O9 ~
4         2               1             'Grandchild 1'
# [4 l6 z+ I3 p, K0 r2 L$ q6 p- _( U5         2               2             'Grandchild 2'
4 `/ p! [# O6 D$ T1 g& t祖先表5 n& e& ~/ X% N. B- M8 N
NodeId    AncestorId    Hops# h: k$ j" X, |% O
1         NULL          0
, U8 h* E% t- i$ n1         1             04 E; d5 G* _: i  |! Q+ W6 q
2         1             1
# `) g: r" g' [$ N" \2         2             04 F9 }3 E* h- B" N% E' e9 F' d
3         1             1! F( {7 U9 S! J2 n8 a4 W6 j: K. M/ r
3         3             0+ `! g" r; g) H, F' `3 }& U  P$ V
4         1             2
, k8 n% `0 B2 a4         2             1
7 D" O+ ^% r, O, U  Y; e4         4             0
4 ^- p% |. z: }) h5         1             27 }& M+ l. f$ ^% H
5         2             1, b, K2 m- x/ J$ l
5         5             0
* X/ g# B, K9 n' r2 l0 h6 Q通过这种设计,我发现在大型层次结构中,通过加入AncestorId = target6 l2 y3 w, N# j4 o# o+ D/ ^
NodeId的Ancestor表,可以非常快速地获得层次结构的整个部分,例如:
: g* ^/ e4 I+ @. V& lSELECT *+ E3 s4 s; T7 _# z/ W
FROM Node n8 M$ s" v3 b- U) ]/ q5 l6 k: v6 f
INNER JOIN Ancestor a on a.NodeId=n.NodeId. M( u% p0 T3 r7 X3 C) Z6 j
WHERE a.AncestorId = @TargetNodeId' X% a4 M, \+ w
也很容易找到直系孩子
' \! n: P. I. ISELECT *! E( R4 s0 R  s/ q7 L1 p: O9 D
FROM Node n
7 X; _. X7 n5 A# m: J& pINNER JOIN Ancestor a on a.NodeId=n.NodeId
# x% p$ [2 u- l4 J1 p9 U1 aWHERE a.AncestorId = @TargetNodeId8 z/ L1 B& l8 u* d7 ?+ P
AND Hops = 1  r* z7 U. @" }& n5 x- o- L, p
我有兴趣知道您可能还针对此类事情使用了哪些其他解决方案。以我的经验,层次结构可能会变得很繁琐,而任何优化其检索的方法都非常重要。
' t( K2 v+ A- o' n7 ^8 |% ?: c                1 y! M- d2 M" y' `* U5 ?' ~
解决方案:
. ]; D$ `! V1 P. X9 c: E                2 V5 b5 c: a4 U4 m, Y- ?( P

9 m! m! @1 V; D+ G
+ E; y( |9 k" Y$ e( H* w5 X                正如MarkusQ和n8wrl所指出的那样,Joe7 b+ t: Q% X( c% a
Celko在这方面有一些不错的东西。我要补充一点,有多种方法可以对层次结构进行建模(Joe的书包含了许多我相信的内容,而不仅仅是他认为“最好”的一种方法)。您的最终决定将希望考虑您自己的特定需求。对它进行建模的一些不同方法更适合于写密集型操作,而其他一些方法则适合于频繁或快速地上下读取层次结构。只需记住您的系统将使用它做什么。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则