文档型数据库设计模式-如何存储树形数据
在數(shù)據(jù)庫中存儲樹形結(jié)構(gòu)的數(shù)據(jù),這是一個非常普遍的需求,典型的比如論壇系統(tǒng)的版塊關(guān)系。在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫中,就已經(jīng)產(chǎn)生了各種解決方案。
此文以存儲樹形結(jié)構(gòu)數(shù)據(jù)為需求,分別描述了利用關(guān)系型數(shù)據(jù)庫和文檔型數(shù)據(jù)庫作為存儲的幾種設(shè)計模式。
A.關(guān)系型數(shù)據(jù)庫設(shè)計模式1
| id | name | parent_id |
| 1 | A | NULL |
| 2 | B | 1 |
| 3 | C | 1 |
| 4 | D | 2 |
上圖表示了傳統(tǒng)的設(shè)計方法之一,就是將樹形結(jié)構(gòu)的每一個結(jié)點作為關(guān)系型數(shù)據(jù)庫中的一行進(jìn)行存儲,每一個結(jié)點保存一個其父結(jié)點的指針。
- 優(yōu)點:結(jié)構(gòu)簡單易懂,插入修改操作都很簡單
- 缺點:如果要獲取某個結(jié)點的所有子結(jié)點,將是一件很惡心的事
B.關(guān)系型數(shù)據(jù)庫設(shè)計模式2
| id | name | parent_id | left | right |
| 1 | A | NULL | 1 | 8 |
| 2 | B | 1 | 2 | 5 |
| 3 | C | 1 | 6 | 7 |
| 4 | D | 2 | 3 | 4 |
上圖在模式1的基礎(chǔ)上多了兩列,left和right,相當(dāng)于btree中的左右分支,分別存儲了左右分支結(jié)點的最大值和最小值。
- 優(yōu)點:要查找一個結(jié)點的子結(jié)點很容易,只需要做一個范圍查詢就行了(比如B節(jié)點的子結(jié)點,只需要查詢 id >=2 && id<=5)
- 缺點:由于樹結(jié)構(gòu)存在在這里面了,所以添加或修改已存在結(jié)點將可能產(chǎn)生連鎖反應(yīng),操作過于復(fù)雜
C.文檔型數(shù)據(jù)庫設(shè)計模式1
{"name": "A","children": [{"name": "B", "children": [{"name": "D"}]},{"name": "C"}] }將整個樹結(jié)構(gòu)存成一個文檔,文檔結(jié)構(gòu)既樹型結(jié)構(gòu),簡明易懂。
- 優(yōu)點:簡明易懂
- 缺點:文檔會越來越大,對所有結(jié)點的修改都集中到這一個文檔中,并發(fā)操作受限
D.文檔型數(shù)據(jù)庫設(shè)計模式2
{"_id": "A", "children": ["B", "C"]} {"_id": "B", "children": ["D"]} {"_id": "C"} {"_id": "D"}將每個結(jié)點的所有子結(jié)點存起來
- 優(yōu)點:結(jié)構(gòu)簡單,查找子結(jié)點方便
- 缺點:查找父結(jié)點會比較麻煩
E.文檔型數(shù)據(jù)庫設(shè)計模式3
{"leaf": "A","children": [{"leaf": "B", "children": [{"leaf": "D"}] },{"leaf": "C"}] } {"_id": "A", ...} {"_id": "B", ...} {"_id": "C", ...} {"_id": "D", ...}充分利用文檔型存儲schema-less的優(yōu)點,先利用上面C方案存存儲一個大的樹形文檔,再將每一個結(jié)點的其他信息單獨存儲。
- 優(yōu)點:操作方便,結(jié)構(gòu)上的操作可以直接操作大的樹形文檔,數(shù)據(jù)上的操作也只需要操作單條數(shù)據(jù)
- 缺點:對所有結(jié)點的修改都集中到這一個文檔中,并發(fā)操作受限
英文原文鏈接:Modeling a Tree in a Document Database
轉(zhuǎn)載于:https://www.cnblogs.com/martinjinyu/articles/3825459.html
總結(jié)
以上是生活随笔為你收集整理的文档型数据库设计模式-如何存储树形数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android4.4源码编译(Ubunt
- 下一篇: 连续处理函数reduce