聊聊 MongoDB 数据库的设计

我是创始人李岩:很抱歉!给自己产品做个广告,点击进来看看。  

聊聊 MongoDB 数据库的设计

作者: 敖天羽

自从正式使用了 MongoDB 之后,不止一次吐槽过 MongoDB 的各种垃圾设定,包括但不仅限于:

  • 没有事务
  • 没有表连接(新版支持了,但估摸着性能堪忧)

也就是说,同样的操作,在 SQL 下通过 JOIN 控制原子性的,通过 MongoDB 可能就不得不去查个两次,而且原子性不可保证——MongoDB 官方也是非常实诚,人家在选型的时候就说了,如果贵系统对并发性(Concurrency)有强要求,那么 MongoDB 可能就不是你的菜了。

在 MongoDB 初窥 中我们也简单的介绍了锁机制,如有需要可以阅读。

前两天无聊接着看《MongoDB 权威指南》的时候看到一些观点,觉得给 MongoDB 数据库设计起到了一定指导和参考作用,故作此文(笔记):

首先我们了解两个概念:

  1. 范式化:将数据分散到不同的集合,多个集合之间可以相互引用,这样要修改这部分数据,只要修改这部分数据所在的文档,其他区域与数据内容无关。
  2. 反范式化:每个文档所需的数据都存储在文档内部,每个文档都拥有自己的数据副本。如果要修改这部分数据,需要修改这块数据对应的每一个文档。

对于我们前文所说的,由于没有「连接」,范式化意味着我们要取出完整所需的数据可能要进行多次查询,而反范式化则只要一次查询即可。从写入的角度,我们可以看到,范式化写入的消耗更少,配合锁机制,对于拥有 subdocument 概念的 MongoDB,我们需要根据自己的实际需求去权衡。

在 SQL 中,我们经常会提起:一对一,一对多,多对多,而在 MongoDB 这样的数据库中,我们可以分为新的类型:少和多,之后我们会根据少和多进行一些数据库设计的详细分析,先来简单根据之前的介绍引用一下《MongoDB 权威指南》中的表格:

更适合内嵌 更适合引用
子文档较小 子文档较大
数据不会定期改变 数据经常改变
最终数据一致即可 中间阶段的数据必须一致
文档数据小幅增加 文档数据大幅增加
数据通常需要执行二次查询才能获得 数据通常不包含在结果中
快速读取 快速写入

通常来说,「少」的关系对于内嵌更为合适,「多」则对于引用更加合适:比如文章和标签的关系可能是多对少,文章和评论的关系可能是一(少)对多。

所以我们的 Tags 可以内嵌,而评论则使用引用更好。

由于 MongoDB 的文档会自动扩充大小,如果太过频繁的让 MongoDB 产生文档移动,将会造成性能问题,在设计阶段,可以预留足够的空间,提高写入速度。

根据这一设计原理,结合 MongoDB 的一些限制,可以在一定程度上解决以下问题,而不是看心情靠玄学去进行设计:

  • 我该不该用 MongoDB?
  • 我该用引用还是 SubDocument?

End.

转载请注明来自36大数据(36dsj.com): 36大数据 » 聊聊 MongoDB 数据库的设计

随意打赏

mongodb数据库
提交建议
微信扫一扫,分享给好友吧。