文档型数据库设计模式-如何存储树形数据

在数据库中存储树形结构的数据,这是一个很是广泛的需求,典型的好比论坛系统的版块关系。在传统的关系型数据库中,就已经产生了各类解决方案。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方案存存储一个大的树形文档,再将每个结点的其余信息单独存储。数据库设计

  • 优势:操做方便,结构上的操做能够直接操做大的树形文档,数据上的操做也只须要操做单条数据
  • 缺点:对全部结点的修改都集中到这一个文档中,并发操做受限
相关文章
相关标签/搜索