MongoDB权威指南-第8章

本文探讨了MongoDB数据库设计中的范式化与反范式化策略,如何优化数据操作及管理一致性,同时讨论了模式迁移及MongoDB适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MongoDB权威指南
应用程序设计
8.1-范式化与反范式化
简介
normalization范式化是将数据分散到多个不同的集合,不同集合之间可以互相引用数据
MongoDB没有提供连接(join)工具
denormalization反范式化与范式化相反:如果数据发生了变化,那么所有文档都要进行更新
范式化能够提高数据写入速度,反范式化能够提高数据读取速度
8.1.1-数据表示的例子
一种方式是使用一个students集合和一个classes集合,然后第三个结合studentClasses保存学生和课程之间的关系
如果要找到一个学生所选的课程,需要请求3次查询
如果将课程引用嵌入在学生文档中,只需要2次查询
如果要进一步优化查询速度,可以将数据完全反范式化,将课程信息作为内嵌文档保存到学生文档的”classes”字段中
优点是只需要1次查询就可以得到学生的课程信息,缺点是会增加更多的存储空间
也可以混合使用内嵌数据和引用数据,创建一个子文档数组用于保存常用信息,需要更详细信息时通过引用找到实际的文档
信息读取更频繁还是信息读取更频繁?如果这些数据会定期更新,那么范式化是比较好的选择
如果决定使用内嵌文档,更新文档时,需要设置一个定时任务(cron job),以确保所做的每次更新都成功更新了所有文档
评论列表或活动列表等信息应该保存在单独的集合中,不应该内嵌到其他文档中
8.1.2-基数
一个集合中包含的对其他集合的引用数量叫做基数(cardinality)
8.1.3-好友,粉丝及其他的麻烦事项
由于followers数组的大小会经常发生变化,所以可以在这个集合上启用usePowerOf2Sizes,以保证users集合尽可能小
对于比较有名的用户,可能会导致用于保存用户粉丝列表的文档溢出.对于这种情况的一种解决方案是使用”连续的文档”
8.2-优化数据操作
8.2.1-优化文档增长
对写入操作的优化通常包括减少索引数量和尽可能提高更新效率
更新文档时需要明确更新是否会导致文件体积增长,以及增长程度
检查一下填充因子,如果他大约是1.2或者更大,可以考虑手工填充
如果文档中有个字段需要增长,尽可能将这个字段放在文档的最后位置
8.2.2-删除旧数据
3种常见的方式:使用固定集合,使用TTL集合或者定期删除集合
最后一种方法是使用多个集合,ex:每个月的文档单独使用一个集合.对应用程序比较复杂,需要使用动态的集合名称
8.3-数据库和集合的设计
用户集合是最有价值的;保证用户数据安全是非常重要的.社交活动数据需要放在一个大流量集合中,它不如用户集合重要,但比日志集合重要
8.4-一致性管理
MongoDB支持多种不同的一致性级别
服务器为每个数据库连接维护一个请求队列.客户端每次发来的请求都会被添加到队列末尾
每个队列只对应一个连接.如果在其中一个shell中执行插入操作,接着在另一个shell中执行查询操作,新插入的数据可能不会出现在查询结果中.
为了提高效率,驱动程序会建立多个与服务器之间的连接(也就是一个连接池),但是他们有各自的机制来保证一系列请求会被同一个连接处理.
如果你的副本集比较小,可以使用”w”:setSize执行安全写入,如果getLastError没能成功返回,可将后续的读取请求发送给主数据库.
最简单的一种是将所有读取请求都发送到主数据库,这样就可以每次都得到最新最准备的数据,也可以设置一个脚本自动检测副本集是否落后于主数据库.
8.5-模式迁移
最简单的方式就是在应用程序需要时改进数据库模式,以确保应用程序能够支持所有旧版的模式.
MongoDB允许使用动态模式,以避免执行迁移,因为执行迁移会对系统造成很大的压力.
如果MongoDB在执行迁移中崩溃,最终的结果可能是只有一部分数据更新,还有一部分没有更新
8.6-不适合使用MongoDB的场景
MOngoDB不支持事务,对事务有要求的应用程序不建议使用MongoDB
在多个不同维度上对不同类型的数据进行连接,这是关系数据库擅长的事情.MongoDB不支持这么做,以后也可能不支持.
应用程序设计
8.1-范式化与反范式化
简介
normalization范式化是将数据分散到多个不同的集合,不同集合之间可以互相引用数据
MongoDB没有提供连接(join)工具
denormalization反范式化与范式化相反:如果数据发生了变化,那么所有文档都要进行更新
范式化能够提高数据写入速度,反范式化能够提高数据读取速度
8.1.1-数据表示的例子
一种方式是使用一个students集合和一个classes集合,然后第三个结合studentClasses保存学生和课程之间的关系
如果要找到一个学生所选的课程,需要请求3次查询
如果将课程引用嵌入在学生文档中,只需要2次查询
如果要进一步优化查询速度,可以将数据完全反范式化,将课程信息作为内嵌文档保存到学生文档的”classes”字段中
优点是只需要1次查询就可以得到学生的课程信息,缺点是会增加更多的存储空间
也可以混合使用内嵌数据和引用数据,创建一个子文档数组用于保存常用信息,需要更详细信息时通过引用找到实际的文档
信息读取更频繁还是信息读取更频繁?如果这些数据会定期更新,那么范式化是比较好的选择
如果决定使用内嵌文档,更新文档时,需要设置一个定时任务(cron job),以确保所做的每次更新都成功更新了所有文档
评论列表或活动列表等信息应该保存在单独的集合中,不应该内嵌到其他文档中
8.1.2-基数
一个集合中包含的对其他集合的引用数量叫做基数(cardinality)
8.1.3-好友,粉丝及其他的麻烦事项
由于followers数组的大小会经常发生变化,所以可以在这个集合上启用usePowerOf2Sizes,以保证users集合尽可能小
对于比较有名的用户,可能会导致用于保存用户粉丝列表的文档溢出.对于这种情况的一种解决方案是使用”连续的文档”
8.2-优化数据操作
8.2.1-优化文档增长
对写入操作的优化通常包括减少索引数量和尽可能提高更新效率
更新文档时需要明确更新是否会导致文件体积增长,以及增长程度
检查一下填充因子,如果他大约是1.2或者更大,可以考虑手工填充
如果文档中有个字段需要增长,尽可能将这个字段放在文档的最后位置
8.2.2-删除旧数据
3种常见的方式:使用固定集合,使用TTL集合或者定期删除集合
最后一种方法是使用多个集合,ex:每个月的文档单独使用一个集合.对应用程序比较复杂,需要使用动态的集合名称
8.3-数据库和集合的设计
用户集合是最有价值的;保证用户数据安全是非常重要的.社交活动数据需要放在一个大流量集合中,它不如用户集合重要,但比日志集合重要
8.4-一致性管理
MongoDB支持多种不同的一致性级别
服务器为每个数据库连接维护一个请求队列.客户端每次发来的请求都会被添加到队列末尾
每个队列只对应一个连接.如果在其中一个shell中执行插入操作,接着在另一个shell中执行查询操作,新插入的数据可能不会出现在查询结果中.
为了提高效率,驱动程序会建立多个与服务器之间的连接(也就是一个连接池),但是他们有各自的机制来保证一系列请求会被同一个连接处理.
如果你的副本集比较小,可以使用”w”:setSize执行安全写入,如果getLastError没能成功返回,可将后续的读取请求发送给主数据库.
最简单的一种是将所有读取请求都发送到主数据库,这样就可以每次都得到最新最准备的数据,也可以设置一个脚本自动检测副本集是否落后于主数据库.
8.5-模式迁移
最简单的方式就是在应用程序需要时改进数据库模式,以确保应用程序能够支持所有旧版的模式.
MongoDB允许使用动态模式,以避免执行迁移,因为执行迁移会对系统造成很大的压力.
如果MongoDB在执行迁移中崩溃,最终的结果可能是只有一部分数据更新,还有一部分没有更新
8.6-不适合使用MongoDB的场景
MOngoDB不支持事务,对事务有要求的应用程序不建议使用MongoDB
在多个不同维度上对不同类型的数据进行连接,这是关系数据库擅长的事情.MongoDB不支持这么做,以后也可能不支持.
DISSIDIA思维导图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值