使用MongoDB TimeSeries集合存储日级加密货币数据是否合适及schema设计咨询
结论先行
你的场景使用MongoDB TimeSeries集合是非常合适的选择,不属于过度设计。两种Schema设计各有适用场景,没有绝对的优劣,只需要匹配你的查询习惯即可。
TimeSeries集合适用性说明
你不需要担心granularity参数没有day级选项的问题,官方允许granularity设置值大于实际数据的时间粒度,你的日级数据直接将granularity设置为hours即可,不会出现适配问题。
使用TimeSeries集合你可以直接获得以下收益,且几乎没有额外使用成本:
- 内置的自动分桶能力,不需要自己实现分桶逻辑,开发成本更低
- 默认开启的列式存储压缩,存储成本相比普通集合可降低60%~80%
- 针对时间范围查询、元数据过滤的内置查询优化,相比普通集合的同场景查询性能有1.5~3倍提升
你本身已经有MongoDB使用经验,不需要额外学习新的时序数据库技术栈,完全不存在过度设计的问题。
两种Schema设计的合理性分析
方案1:单币种单条文档
{ _id: ...., date: ISODate(), price: 100, symbol: 'btc' } { _id: ...., date: ISODate(), price: 120, symbol: 'eth' }
- 合理性:适配绝大多数通用查询场景,是优先推荐的设计方案。使用TimeSeries集合时,将timeField设为
date、metaField设为symbol即可,MongoDB会自动按照币种+时间范围做分桶优化。 - 适用场景:如果你的查询需求以单币种/少量币种的跨时间范围趋势查询为主(比如查询BTC过去2年的每日价格、计算ETH的季度均价),该方案的查询、聚合逻辑最简单,性能最优。
方案2:同日期多币种合并存储
{ _id: ..., date: ISODate(), prices: [ { symbol: 'btc', price: 100 }, { symbol: 'eth', price: 120 } ] }
- 合理性:属于针对性优化的设计方案,仅在特定查询场景下有更高效率。
- 适用场景:如果90%以上的查询都是按日期拉取全量币种的当日价格,该方案只需一次查询即可返回全量数据,IO开销远低于方案1。但如果你需要频繁做单币种的跨时间范围查询,该方案需要额外遍历数组过滤对应币种数据,聚合复杂度和性能都会弱于方案1,同时如果后续币种数量持续增加,单文档体积也会不断膨胀,维护成本更高。
选型建议
没有特殊高频按天拉全量数据需求的前提下,优先选择方案1配合MongoDB TimeSeries集合使用,灵活性和综合性能更高。
内容的提问来源于stack exchange,提问作者ecirish
相关产品推荐
相关产品推荐

