Skip to content

28 · 数据库与存储选型

一句话点题:数据库不是「MySQL 还是 PostgreSQL」这么小的问题,而是「这份数据的读写模式、一致性要求、查询形态、增长速度和失败代价是什么」。选存储,先画数据生命周期;工具名排在后面。


🧰 技术栈选型篇第 2 章 · 本章只练一件事

05 章 说过:系统真正难的不是逻辑,是数据。语言可以换,服务可以拆,但数据一旦放错地方,迁移成本会非常高。本章把数据库、缓存、搜索、对象存储、向量库放到同一张选型地图里看。


开场:别用一个数据库扛所有问题

很多系统一开始长这样:

   App ──▶ 一个关系型数据库
             ├─ 交易数据
             ├─ 报表查询
             ├─ 搜索筛选
             ├─ 文件附件
             └─ AI 检索向量

MVP 这样做没错。问题是,随着业务长大,这些数据的访问方式完全不同:

  • 订单要强一致,不能丢。
  • 报表要扫大量历史数据,不能拖垮主库。
  • 搜索要相关性排序,不是简单 LIKE
  • 图片、视频、附件要便宜存、能走 CDN(内容分发网络)。
  • RAG(检索增强生成)要向量召回和权限过滤。

**架构判断:**不是「哪个数据库最好」,而是「哪类数据,该用哪种存储模型承载」。一个系统常常需要多种存储,但每增加一种,都会增加一致性、同步、运维和排障成本。


一、先画数据生命周期

选数据库之前,先把一类数据从出生到归档画出来:

   写入 ──▶ 校验 ──▶ 事务提交 ──▶ 查询/检索 ──▶ 分析/报表 ──▶ 归档/删除
     │        │          │             │              │              │
   谁写?    怎么验?    要多一致?      怎么查?        多久查一次?     保留多久?

然后回答五个问题:

问题为什么重要
写多还是读多?决定是否需要读写分离、缓存、索引模型
事务边界在哪里?决定能不能用关系型数据库的事务兜住
查询形态是什么?主键查、范围查、全文搜索、向量相似度,完全不同
数据增长速度多快?决定分区、冷热分层、归档策略
错了会怎样?决定一致性、备份、审计、恢复等级

这一步和 07 章 的信封背面估算是一回事:先算数据量、读写比、保留周期,再谈工具。


二、主存储:关系型数据库仍然是默认起点

如果你不知道该选什么,大多数业务系统默认从关系型数据库开始:

类型适合不适合
关系型数据库(如 PostgreSQL、MySQL)交易、订单、权限、租户、账务、需要事务的数据极大规模分析、全文搜索、海量非结构化文件
文档数据库(Document DB,如 MongoDB)结构经常变化、文档整体读写、弱关系数据强事务、多表复杂关联、严格报表
键值存储(Key-Value,如 DynamoDB、Redis 持久化形态)按 key 高速读写、结构简单、超大规模临时复杂查询、灵活关联
列式/分析数据库(OLAP,在线分析处理)报表、聚合、日志分析、行为分析高频小事务写入

**默认建议:**先用关系型数据库把核心交易数据放稳。等报表、搜索、日志、向量检索真的变成独立压力,再把对应读模型拆出去。不要一上来为了「现代」把每类数据都塞进不同数据库。


三、读模型:搜索、分析、向量不是主库的附属品

当查询形态开始偏离主库擅长的方向,就要考虑读模型:

需求常见存储/引擎关键取舍
全文搜索Elasticsearch、OpenSearch、Meilisearch相关性强,但索引同步和最终一致要处理
报表分析ClickHouse、BigQuery、Snowflake扫描聚合快,但不是交易主库
对象存储S3、OSS、GCS存文件便宜可靠,但不能当数据库做复杂查询
向量数据库(Vector DB)Milvus、Qdrant、pgvector相似度检索强,但权限过滤、召回质量和成本要评估
时序数据库(Time Series DB)Prometheus、InfluxDB指标时间线查询强,但不适合普通业务对象

这里最容易犯的错是把读模型当成事实源:

   正确:
   主库 = 事实源(Source of Truth)
   搜索/分析/向量库 = 从主库或对象存储同步出来的读模型

   错误:
   用户改了资料 → 只改搜索索引 → 主库不知道

读模型可以落后,但要说清楚能落后多久怎么补偿怎么重建。这就是 11 章 的一致性工程。


四、RAG 场景:向量库不是唯一答案

RAG 企业知识库(案例 03 DocuMind)很容易被简化成:

   文档切块 ──▶ 向量库 ──▶ topK ──▶ LLM 回答

真实系统更像:

   原文对象存储 ──▶ 解析/切块 ──▶ 元数据主库
         │                          │
         ├────────▶ 关键词索引 ◀────┤
         ├────────▶ 向量索引   ◀────┤
         └────────▶ 权限/租户过滤 ◀──┘

选型时要问:

  • 权限过滤是在检索前做,还是检索后过滤?后过滤可能召回不够。
  • 只做向量召回,还是混合检索(Hybrid Search,关键词 + 向量)?
  • 原文和引用存在哪里?向量库不应该是唯一事实源。
  • 索引坏了能不能从原文和元数据重建?
  • 成本能不能随文档量和查询量线性增长?

向量库解决的是「相似度召回」,不是权限、事实源、引用、评测的全部问题。不要把一个 RAG 系统压扁成一个库。


五、什么时候该拆存储

拆存储的触发信号要具体:

信号说明可能动作
报表查询拖慢交易库OLTP(在线事务处理)和 OLAP(在线分析处理)互相干扰同步到分析库
搜索相关性差、LIKE 扫描慢查询形态变成全文搜索建搜索索引
附件/图片撑爆数据库二进制文件不该塞主库迁到对象存储 + CDN
单表增长导致索引和备份变慢数据生命周期没有分层分区、归档、冷热分离
RAG 召回质量不稳单一向量召回不够混合检索 + 重排 + eval

也要记住反面:

如果当前数据量小、团队少、故障代价低,一套关系型数据库 + 合理索引 + 定期备份,往往比过早引入五种存储更健康。


六、写一条存储选型 ADR

md
### ADR-028:报表查询从交易库拆到 ClickHouse

- 背景:工单列表和状态流转依赖主库,但月度报表开始扫描 2 亿行历史事件,导致交易库 P99 从 120ms 升到 900ms。
- 选择:主库继续作为事实源;通过 Outbox 事件同步到 ClickHouse,报表只查分析库。
- 放弃:放弃报表的强实时性,允许 1 分钟以内延迟。
- 换来:交易链路与报表链路隔离,报表聚合性能提升,主库负载稳定。
- 复审条件:如果报表必须秒级实时,或同步延迟超过业务可接受范围,重新评估流式同步和预聚合。

这条 ADR 的关键是:它没有说「ClickHouse 很快」,而是说清楚了哪个读模型拖垮了哪个事实源


🎯 随堂检验

🤔一个电商系统的订单、支付、库存状态需要强一致的状态推进。默认最适合作为事实源的是?
  • A关系型数据库,用事务、约束和状态机守住核心交易数据
  • B全文搜索引擎,因为查询很灵活
  • C对象存储,因为便宜
🤔关于搜索索引、分析库、向量库和主库的关系,正确的是?
  • A它们都应该各自成为事实源,这样最灵活
  • B主库或原始对象存储通常是事实源,搜索/分析/向量库是为特定查询形态同步出来的读模型
  • C只要用了向量库,就不需要元数据和权限库了

本章小结

  • 选存储先画数据生命周期:写入、校验、事务、查询、分析、归档,每一步都有约束。
  • 关系型数据库仍是多数业务系统的默认事实源:先稳住核心交易数据,再拆读模型。
  • 搜索、分析、向量库是不同查询形态的读模型:它们强在特定查询,弱在事务和事实源。
  • RAG 不是一个向量库:还包括原文、元数据、权限、混合检索、重排、引用和 eval。
  • 拆存储要靠触发信号:报表拖垮主库、搜索变慢、附件撑爆库、召回质量不稳,这些才是升级理由。

承上启下:主存储解决「事实放在哪里」。但系统一旦有热点、洪峰、异步协作,就会遇到缓存、消息队列和事件系统。下一章 29 · 缓存、消息队列与事件系统选型,我们专门讲这些「很有用,也很容易被误用」的中间层。


相关链接

💬 评论