樹結(jié)構(gòu)
網(wǎng)站的回復評論,這是一種典型的樹形結(jié)構(gòu)望忆,擁有層級關(guān)系
create table comments{
comment_id,
parent_id,
comment,
forenign key(parent_id) references comments(comment_id)
}
這是一種常見的設計模式罩阵,添加parent_id 來表示層級關(guān)系竿秆。
這種方式很容易查詢一個節(jié)點的直接后代,但是沒有辦法查詢這個節(jié)點下的所有后代稿壁。
查詢直接后代
select c1.*,c2.* from comments c1 left join comments c2 on c2.parent_id = c1.comments_id;
如果要查詢多層節(jié)點 需要擴展一個聯(lián)結(jié)
select c1.* ,c2.*,c3.*,c4.*
from comments c1 ---- 第一層
left join comments c2
on c2.parent_id = c1.comment_id ---- 第二層
left join comments c3
on c3.parent_id = c2.comment_id -----第三層
left join comments c4
on c4.parent_id = c3.comment_id; -----第四層
sql查詢聯(lián)結(jié)次數(shù)是有上限幽钢,上面只能查詢4層,無法查詢跟多傅是,層次太多匪燕,執(zhí)行聚合函數(shù)比如count ()也非常困難。
解決方案
1:路徑枚舉
comment_id,
path,
comment,
}
comment_id | path | comment |
---|---|---|
1 | 1/ | 好 |
2 | 1/2/ | 不錯 |
3 | 1/2/3 | 奶茶 |
4 | 1/4 | naice |
如果我們要查詢節(jié)點7的祖父
select * from comments as c
where '1/4/6/7' like c.path || '%'
|| 是字符串連接符
匹配路徑為 1/4/6/% 1/4/% 1/%
將查詢路徑反過來 獲取節(jié)點的所有后代
缺點:數(shù)據(jù)庫自身無法保證路徑格式總是正確的以及路徑中的節(jié)點確實存在喧笔,需要依賴應用程序邏輯代碼維護谎懦。長度存在限制。
表設計的時候可以綜合考慮使用 鄰接表 parent_id和路徑 path(1/2/7/)