文檔型數據庫設計模式-如何存儲樹形數據

在數據庫中存儲樹形結構的數據,這是一個很是廣泛的需求,典型的好比論壇系統的版塊關係。在傳統的關係型數據庫中,就已經產生了各類解決方案。sql

此文以存儲樹形結構數據爲需求,分別描述了利用關係型數據庫和文檔型數據庫做爲存儲的幾種設計模式。數據庫

A.關係型數據庫設計模式1

id name parent_id
1 A NULL
2 B 1
3 C 1
4 D 2

上圖表示了傳統的設計方法之一,就是將樹形結構的每個結點做爲關係型數據庫中的一行進行存儲,每個結點保存一個其父結點的指針。設計模式

  • 優勢:結構簡單易懂,插入修改操做都很簡單
  • 缺點:若是要獲取某個結點的全部子結點,將是一件很噁心的事

B.關係型數據庫設計模式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的基礎上多了兩列,left和right,至關於btree中的左右分支,分別存儲了左右分支結點的最大值和最小值。併發

  • 優勢:要查找一個結點的子結點很容易,只須要作一個範圍查詢就好了(好比B節點的子結點,只須要查詢 id >=2 && id<=5)
  • 缺點:因爲樹結構存在在這裏面了,因此添加或修改已存在結點將可能產生連鎖反應,操做過於複雜

C.文檔型數據庫設計模式1

{
  "name": "A",
  "children": [
    {"name": "B", "children": [{"name": "D"}]},
    {"name": "C"}
  ]
}

將整個樹結構存成一個文檔,文檔結構既樹型結構,簡明易懂。less

  • 優勢:簡明易懂
  • 缺點:文檔會愈來愈大,對全部結點的修改都集中到這一個文檔中,併發操做受限

D.文檔型數據庫設計模式2

{"_id": "A", "children": ["B", "C"]}
{"_id": "B", "children": ["D"]}
{"_id": "C"}
{"_id": "D"}

將每一個結點的全部子結點存起來nosql

  • 優勢:結構簡單,查找子結點方便
  • 缺點:查找父結點會比較麻煩

E.文檔型數據庫設計模式3

{
  "leaf": "A",
  "children": [
    {"leaf": "B", "children": [{"leaf": "D"}] },
    {"leaf": "C"}
  ]
}
{"_id": "A", ...}
{"_id": "B", ...}
{"_id": "C", ...}
{"_id": "D", ...}

充分利用文檔型存儲schema-less的優勢,先利用上面C方案存存儲一個大的樹形文檔,再將每個結點的其餘信息單獨存儲。數據庫設計

  • 優勢:操做方便,結構上的操做能夠直接操做大的樹形文檔,數據上的操做也只須要操做單條數據
  • 缺點:對全部結點的修改都集中到這一個文檔中,併發操做受限
相關文章
相關標籤/搜索