数据库选型基础:关系型 vs 非关系型、ACID vs BASE、CAP理论在交易系统中的应用

做量化交易系统,数据库选型是地基。地基没打好,后面全是坑。

我记得刚入行那会儿,带我的老大哥说过一句话:「交易系统里,数据就是钱。你存数据的方式,决定了你赚钱的速度和赔钱的风险。」这话我到现在都记着。

今天咱们就聊聊数据库选型的三个核心概念。说白了,就是搞清楚你的交易系统到底需要什么样的数据库。

关系型 vs 非关系型:两种思维模式

先问个问题:你手头有一笔订单数据,你会怎么存?

关系型数据库(比如 PostgreSQL、MySQL)的思维是:把数据拆成一张张表,用外键关联起来。订单表、用户表、产品表、持仓表……每张表都规规矩矩的。

非关系型数据库(比如 MongoDB、Redis)的思维是:把数据当成一个整体存进去。一个订单就是一个 JSON 文档,里面包含了用户信息、产品信息、状态信息,全塞一块儿。

我的经验是:交易系统的核心数据(订单、成交、持仓)用关系型。缓存、实时行情、日志这些用非关系型。别混着用,也别只用一种。

举个例子。我在做期货交易系统时,订单数据必须用 PostgreSQL。为什么?因为订单需要强一致性。你下了单,系统必须保证「要么成交,要么不成交」,不能出现「好像成交了但又没完全成交」这种状态。

但实时行情数据呢?我用 Redis。每秒几千笔行情进来,关系型数据库根本扛不住。Redis 的 List 结构,直接往队列里推,消费端慢慢处理,完美。

维度 关系型(SQL) 非关系型(NoSQL)
数据结构 表、行、列 文档、键值、图、列族
一致性 强一致性 最终一致性
扩展方式 垂直扩展为主 水平扩展为主
适用场景 订单、持仓、风控 行情、日志、缓存
典型代表 PostgreSQL, MySQL MongoDB, Redis, Cassandra

ACID vs BASE:交易系统的生死线

ACID 和 BASE 是两种截然不同的哲学。

ACID 是关系型数据库的基石。原子性、一致性、隔离性、持久性。这四个特性保证了你的交易数据不会乱。

BASE 是非关系型数据库的哲学。基本可用、软状态、最终一致性。说白了就是:系统大部分时间能用,数据偶尔不一致,但最终会一致。

注意:交易系统的资金数据,必须用 ACID。我见过有人用 MongoDB 存订单数据,结果因为最终一致性导致同一笔订单被重复成交。那场面……嗯,不太好看。

我个人习惯是这么分的:

  • 资金、持仓、订单:必须 ACID。用 PostgreSQL 或 MySQL,开启事务隔离级别为可重复读或串行化。
  • 行情、K线、指标:可以 BASE。用 MongoDB 或 Cassandra,允许短暂的不一致。
  • 缓存、会话:BASE 就行。用 Redis,丢了也不怕,重新算一遍就好。

我曾经踩过一个坑。有个策略需要实时读取持仓数据做风控。我图省事,直接从 Redis 缓存里读。结果有一次 Redis 主从切换,缓存数据丢了,风控系统直接放行了一笔超仓订单。还好是模拟盘,不然……

从那以后,所有风控数据我都从数据库读,缓存只做加速,不做决策依据。

CAP理论:你只能选两个

CAP 理论是分布式系统的铁律。一致性、可用性、分区容错性,三者不可兼得。

在交易系统里,这个理论特别有意思。

核心观点:交易系统通常选择 CP(一致性 + 分区容错性),牺牲部分可用性。因为数据错了比系统不可用更可怕。

你想想看,如果交易所的撮合系统出现了网络分区,你是选择继续接受订单(可用性),还是暂停交易保证数据一致(一致性)?

所有正规交易所都选后者。暂停交易,等网络恢复,再继续。因为一旦出现「同一笔资金在两个地方同时下单」的情况,后果不堪设想。

我画了一张图,帮你理解 CAP 在交易系统里的应用:

CAP理论在交易系统中的应用 一致性 (C) 可用性 (A) 分区容错性 (P) CP 订单/持仓/风控 AP 行情展示/日志 CA 单机数据库 交易系统核心数据选CP,非核心数据选AP,单机场景选CA

实际项目中,我一般这么选:

  • 撮合引擎:CP。宁可系统暂停,也不能出现数据不一致。
  • 行情推送:AP。丢几笔行情没关系,但不能让用户等太久。
  • 历史回测:CA。单机跑,不需要分区,追求强一致和高可用。

一个小技巧:别把 CAP 当成死教条。实际系统往往是混合的。比如我用 PostgreSQL 做主库(CP),同时用 Redis 做缓存(AP),再用消息队列做异步同步。这样既保证了核心数据的一致性,又提升了整体性能。

总结一下

数据库选型没有银弹。关系型还是非关系型,ACID 还是 BASE,CP 还是 AP,都得看场景。

我的建议是:

  1. 资金、订单、持仓这些「命根子」数据,用关系型数据库,开事务,保 ACID。
  2. 行情、日志、缓存这些「辅助」数据,用非关系型数据库,追求性能和扩展性。
  3. 分布式场景下,核心链路选 CP,非核心链路选 AP。

记住一句话:交易系统里,数据错了就是钱错了。宁可慢一点,不能错一点。


公众号:蓝海资料掘金营,微信deep3321