桶模式
这种模式在处理物联网、实时分析或通用时间序列数据时特别有效。通过将数据放在一起,我们可以更容易地将数据组织成特定的组,它具有很大的可伸缩性,它减少了集合中的文档总数,节省索引大小,提高了索引性能,并且通过预聚合简化了数据访问。
此模式的一个很好的用例是时间序列数据。
桶模式案例
场景
共享单车每分钟记录一次位置信息并将数据存储在一个名为 locations 的集合中
行模式
每一分钟创建一条新的记录,一个小时 60 条
数据存储结构如下:
随着我们的应用程序在数据和索引大小上的扩展,这可能会带来一些问题。例如,我们可能最终不得不对每次请求的的 source_id 和 timestamp 进行索引,实现以内存为代价的快速访问
数据在一段时间内持续流入,索引及集合很快就变得庞大。例如:在一个月时间内,索引建立总次数:129600 集合大小:43200
桶模式
但利用文档数据模型,我们可以按时间将这些数据“以桶的方式”储存到特定时间片 GPS 信息的文档中。我们还可以通过编程方式向每一个“桶”中添加附加信息。
使用桶模式,我们从每小时 60 个文档减少到一个文档。对于索引,我们现在可以索引 start_timestamp 而不是,timestamp 因此大小要少 60 倍。
对比分析
桶模式下分页查询
使用 limit 和 skip
使用 limit 和 skip 进行分页查询如 MongoDB 文档中所述,它需要先扫描所有以前的文档,然后才能找到所需的文档,因此随着偏移量的增加,它变得越来越慢。因此,响应时间随着页码的增加而减少。
官方文档: https://docs.mongodb.com/manual/reference/method/cursor.skip/
db.collectionName.find().limit(number).skip(number)
翻第 2 页(每页 50 条)
翻第 10 页(每页 50 条)
翻第 100 页(每页 50 条)
键集分页
每一次查询时,获取上一次分页最后一条数据的_id,当作过滤条件,但是不能跳页查询。
db.collectionName.find({ _id: { $lt: end_offset } }).limit(number).skip(number)
翻第 2 页(每页 50 条)
翻第 10 页(每页 50 条)
翻第 100 页(每页 50 条)
桶分页
在桶中做一个数量的标记,借助程序计算出需要查询对应分页展示的数据
分页查询性能优化
使用索引字段先进行排序后在进行分页操作