您的位置:首页 > 数据库 > Mongodb

MongoDB权威指南-第8章

2016-02-25 10:59 281 查看
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不支持这么做,以后也可能不支持.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: