K线历史数据存储方案分享
K线历史数据存储方案分享
在数字货币交易领域,K线图是分析市场走势的重要工具。如何高效、准确地存储和管理大量K线历史数据,是一个值得探讨的技术问题。本文将分享一种基于MongoDB的K线数据存储方案,该方案能够支持多个交易所的数据,并通过合理的数据库设计和索引策略,实现高性能的数据读写和查询。
一年前,作者在一家数字货币培训公司工作,负责通过知名交易所(如火币、币安、OKEx)提供的免费API接口获取数据,并将其存储起来供前端K线页面展示。以下是作者当时设计的存储方案:
首先是交易对的存储,作者将它们放在一个名为 "kline" 的数据库中,然后再按照交易所创建各自的交易对信息表,例如 "symbol_hb"、"symbol_bian"、"symbol_okex"。
K线的历史数据存储在MongoDB中,同样,每个交易所都创建各自的MongoDB数据库,例如 "kline_hb"、"kline_bian"、"kline_okex"。
K线的历史数据包含多种时间周期:1min、3min、5min、10min、15min、30min、1hour、2hour、4hour、6hour、12hour、1day、3day、1week、1month、1year。作者根据这些周期创建了相应的MongoDB集合:
// K线历史数据MongoDB集合
// 1min集合64个
db.createCollection("min1_0");
db.createCollection("min1_63");
// 3min集合32个
db.createCollection("min3_0");
db.createCollection("min3_31");
// 5min集合32个
db.createCollection("min5_0");
db.createCollection("min5_31");
// 10min集合16个
db.createCollection("min10_0");
db.createCollection("min10_15");
// 15min集合16个
db.createCollection("min15_0");
db.createCollection("min15_15");
// 30min集合8个
db.createCollection("min130_0");
db.createCollection("min130_7");
// 1hour集合8个
db.createCollection("hour1_0");
db.createCollection("hour1_7");
// 2hour集合4个
db.createCollection("hour2_0");
db.createCollection("hour2_3");
// 4hour集合4个
db.createCollection("hour4_0");
db.createCollection("hour4_3");
// 6hour集合1个
db.createCollection("hour6_0");
// 12hour集合1个
db.createCollection("hour12_0");
// 1day集合1个
db.createCollection("day1_0");
// 3day集合1个
db.createCollection("day3_0");
// 1week集合1个
db.createCollection("week1_0");
// 1month集合1个
db.createCollection("month1_0");
// 1year集合1个
db.createCollection("year1_0");
集合索引设计:
- 交易对ID与开盘时间戳组合唯一索引
- 集合分片方式:交易对ID 作为片键
- 使用副本集架构,一主一从一仲裁
分片集群部署参考MongoDB官方文档:Deploy a Sharded Cluster
为什么创建这么多集合?主要是为了提高接口的响应速度和数据准确性。K线历史数据在采集过程中可能会出现同一开盘时间的收盘价、成交额不一致的情况,因此需要随时更新数据。由于数据的实时性和更新需求,没有使用时序数据库。
值得一提的是,通过处理K线数据存储,作者深刻理解了MongoDB组合唯一索引的重要性以及副本集群部署的必要性。此外,K线的热数据缓存方案和即时价格(WebSocket)消息广播等话题,将在后续文章中继续探讨。