云开发数据设计浅析该文转自以下链接,如需了解详情,请猛戳↓↓↓↓
聊聊 MongoDB 数据库的设计
https://www.codesky.me/archives/talk-about-mongodb-collection-design.wind
转发原因
由于下面文章来自个人网站,具有不可访问的因素,我转到社区
自从正式使用了 MongoDB 之后,不止一次吐槽过 MongoDB 的各种垃圾设定,包括但不仅限于:
- 没有事务
- 没有表连接(新版支持了,但估摸着性能堪忧)
也就是说,同样的操作,在 SQL 下通过 JOIN 控制原子性的,通过 MongoDB 可能就不得不去查个两次,而且原子性不可保证——MongoDB 官方也是非常实诚,人家在选型的时候就说了,如果贵系统对并发性(Concurrency)有强要求,那么 MongoDB 可能就不是你的菜了。
在 MongoDB 初窥 中我们也简单的介绍了锁机制,如有需要可以阅读。
前两天无聊接着看《MongoDB 权威指南》的时候看到一些观点,觉得给 MongoDB 数据库的设计起到了一定指导和参考作用,故作此文(笔记):
首先我们了解两个概念:
- 范式化:将数据分散到不同的集合,多个集合之间可以相互引用,这样要修改这部分数据,只要修改这部分数据所在的文档,其他区域与数据内容无关。
- 反范式化:每个文档所需的数据都存储在文档内部,每个文档都拥有自己的数据副本。如果要修改这部分数据,需要修改这块数据对应的每一个文档。
对于我们前文所说的,由于没有「连接」,范式化意味着我们要取出完整所需的数据可能要进行多次查询,而反范式化则只要一次查询即可。从写入的角度,我们可以看到,范式化写入的消耗更少,配合锁机制,对于拥有 subdocument
概念的 MongoDB,我们需要根据自己的实际需求去权衡。
在 SQL 中,我们经常会提起:一对一,一对多,多对多,而在 MongoDB 这样的数据库中,我们可以分为新的类型:少和多,之后我们会根据少和多进行一些数据库设计的详细分析,先来简单根据之前的介绍引用一下《MongoDB 权威指南》中的表格:
更适合内嵌更适合引用子文档较小子文档较大数据不会定期改变数据经常改变最终数据一致即可中间阶段的数据必须一致文档数据小幅增加文档数据大幅增加数据通常需要执行二次查询才能获得数据通常不包含在结果中快速读取快速写入
通常来说,「少」的关系对于内嵌更为合适,「多」则对于引用更加合适:比如文章和标签的关系可能是多对少,文章和评论的关系可能是一(少)对多。
所以我们的 Tags 可以内嵌,而评论则使用引用更好。
由于 MongoDB 的文档会自动扩充大小,如果太过频繁的让 MongoDB 产生文档移动,将会造成性能问题,在设计阶段,可以预留足够的空间,提高写入速度。
根据这一设计原理,结合 MongoDB 的一些限制,可以在一定程度上解决以下问题,而不是看心情靠玄学去进行设计:
- 我该不该用 MongoDB?
- 我该用引用还是 SubDocument?