1. 程式人生 > >文件型資料庫設計模式-如何儲存樹形資料

文件型資料庫設計模式-如何儲存樹形資料

在資料庫中儲存樹形結構的資料,這是一個非常普遍的需求,典型的比如論壇系統的版塊關係。在傳統的關係型資料庫中,就已經產生了各種解決方案。

此文以儲存樹形結構資料為需求,分別描述了利用關係型資料庫和文件型資料庫作為儲存的幾種設計模式。

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"}
  ]
}

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

  • 優點:簡明易懂
  • 缺點:文件會越來越大,對所有結點的修改都集中到這一個文件中,併發操作受限

D.文件型資料庫設計模式2

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

將每個結點的所有子結點存起來

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

E.文件型資料庫設計模式3

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

充分利用文件型儲存schema-less的優點,先利用上面C方案存儲存一個大的樹形文件,再將每一個結點的其他資訊單獨儲存。

  • 優點:操作方便,結構上的操作可以直接操作大的樹形文件,資料上的操作也只需要操作單條資料
  • 缺點:對所有結點的修改都集中到這一個文件中,併發操作受限