2021.4.7 星期三 14:37
基础
二、数据库设计技巧和窍门
2.1.规范化存储与非规范化存储
所以在两种存储数据方式之间进行选择之前,先评估一下你的应用数据库的使用方式。
如果您有一个不需要频繁更新的数据,更新的即时一致性不是很重要,但是在读取时需要良好的性能,那么非规范化可能是明智的选择。(比如:我们博客的博文,作者一旦保存之后,几乎就不在进行频繁的修改,但是面临着读者频繁的读取阅读操作)
如果数据库中的文档数据需要不断的更新,并且您希望在写入时具有良好的性能,那么您可能需要考虑规范化存储。(比如:需要频繁修改数据的业务类系统)
2.2. 一对多关系
与RDBMS相比,在MongoDB中对“一对多”关系建模需要进行更细粒度的设计。许多初学者陷入将文档数组嵌入父文档中的陷阱。正如我们在上文中介绍的,知道何时进行规范化存储或非规范化存储是非常重要的。因此设计者需要考虑关系的基数是“一个对少数几个”还是“一个对多个”?每种关系将具有不同的建模方法。
2.3.设计模式可视化
尽管MongoDB是schemaless“无模式的”,但仍然存在将集合collections可视化为图表的方法。能够查看设计图,将对您理解和设计MongoDB的方式上产生重大影响。
DbSchema是可以很好地完成可视化设计工作的一个工具。
2.4.智能索引
为了保持数据库的良好性能,有必要建立智能索引,这将简化写入和读取操作。知道MongoDB的索引优势和局限性非常重要,MongoDB保留用于排序操作的内存限制为32MB。如果你不使用索引,则排序时数据库将被迫将所有排序文档hold在内存里面,如果达到32M的限制,则数据库将返回错误或空集。
内嵌 vs 引用
各种垃圾设定,包括但不仅限于:
没有事务
没有表连接(新版支持了,但估摸着性能堪忧)
在 SQL 中,我们经常会提起:一对一,一对多,多对多,而在 MongoDB 这样的数据库中,我们可以分为新的类型:少和多,之后我们会根据少和多进行一些数据库设计的详细分析,先来简单根据之前的介绍引用一下《MongoDB 权威指南》中的表格:
更适合内嵌 | 更适合引用 |
---|---|
子文档较小 | 子文档较大 |
数据不会定期改变 | 数据经常改变 |
最终数据一致即可 | 中间阶段的数据必须一致 |
文档数据小幅增加 | 文档数据大幅增加 |
数据通常需要执行二次查询才能获得 | 数据通常不包含在结果中 |
快速读取 | 快速写入 |
由于 MongoDB 的文档会自动扩充大小,如果太过频繁的让 MongoDB 产生文档移动,将会造成性能问题,在设计阶段,可以预留足够的空间,提高写入速度。
几个好处
1、一次数据库查询可以得到整条记录。。
2、一条记录的所有信息都书存储在硬盘的的同一片区域,所以一次检索可以可以得到所有数据。
3、插入或更新单条属性时:
4、插入一条新属性不需要在硬盘上移动整条记录,Mongo有一个预留机制,预留出了一部分空间以适应数据对象的增长。也可以预防索引的增长等问题。
Embed vs. Reference
在Mongo数据库设计中关键的一句话是“比起嵌入到其他Collection中做一个子对象,每个对象值得拥有自己的Collection吗?”。在关系数据库中。每个有兴趣的子项目通常都会分离出来单独设计一张表(除非为了性能的考虑)。而在Mongo中,是不建议使用这种设计的,嵌入式的对象更高效。(这句不是很确定Data is then colocated on disk; client-server turnarounds to the database are eliminated)数据是即时同步到硬盘上的,客户端与服务器不必要在数据库上做周转。所以通常来说问题就是“为什么不使用嵌入式对象呢?”
一些规则
1、顶级对象,一般都有自己的Collection
2、线性细节对象,一般作为嵌入式的
3、一个对象和另一个对象是包含关系时通常采用嵌入式设计
4、多对多的关系通常采取引用设计
5、只含有几个简单对象的可以单独作为一个Collection,因为整个Collection可以很快的被缓存在应用程序服务器内存中。
6、在Collection中嵌入式对象比顶级对象更难引用。as you cannot have a DBRef to an embedded object (at least not yet).
7、It is more difficult to get a system-level view for embedded objects. For example, it would be easier to query the top 100 scores across all students if Scores were not embedded.
8、如果将要嵌入的数据量很大(很多M),你可以限制单个对象的大小
9、如果性能存在问题,请使用嵌入式设计