Lesson 0004 · 系统设计 · Phase 2 数据层

数据层:SQL vs NoSQL 与复制

⏱ 预计 30 分钟 🎯 高层设计中「选什么数据库」的决策依据 📖 前置:Lesson 0003
与你的 Mission 的关系

「SQL 还是 NoSQL」是面试深挖环节的必考题,也是工作中最常见的架构分歧。答对的关键不是站队,而是说清决策依据——这恰好也是你在设计评审中说服团队的方式。本课依据 DDIA 复制章节[1]

§1 · 决策框架五个问题定生死

不要问「哪个数据库更好」,问这五个问题:

问题指向 SQL指向 NoSQL
① 数据结构?结构化、关系多(订单-商品-用户)松散、嵌套文档、超简单 KV
② 事务需求?强 ACID(钱、库存)可容忍最终一致(点赞数)
③ 查询模式?任意条件组合、JOIN、聚合按主键/固定模式读写
④ 规模?单机/少量读写分离可扛海量写入、数据量单机装不下
⑤ 演进速度?Schema 稳定字段频繁变化、异构数据

NoSQL 四大家族快速定位:KV(Redis/DynamoDB——按 key 读写,快);文档(MongoDB——JSON 式嵌套对象);宽列(Cassandra——海量写入、按分区键查询);(Neo4j——关系即数据,社交/风控)。

面试高频误区

「数据量大所以用 NoSQL」是错误推理。正确推理是:查询模式 + 事务需求决定类型,规模决定部署形态。很多「大」系统(包括 Amazon 早期)单机 PostgreSQL 就能跑很久——先读写分离,再谈换库。

§2 · 复制一份数据,多台机器

复制的两个动机:读扩展(读分摊到多副本)和高可用(主库挂了从库顶上)[1]。主流拓扑三种:

拓扑机制代价
主从
Leader-Follower
写全走主库,主库把变更日志同步给从库;读可走从库复制延迟 replication lag:从库读到旧数据
多主
Multi-Leader
多个数据中心各有一个主库,互相同步同一数据两地同时改 → 写冲突需要解决
无主
Leaderless
读写打到任意副本,靠多数派仲裁(quorum)判断新旧一致性更弱,冲突协调交给客户端/系统

复制延迟是面试深挖金矿

经典场景:用户改完个人资料刷新页面,头像没变——写主库成功,读请求却被分到还没同步的从库。这叫读己之写read-your-writes)被破坏。标准解法:

主库挂了怎么办

选主leader election):提升一个从库为新主。坑在「脑裂」(split brain)——旧主没死透,出现双主双写。工业界的答案是一致性算法(Raft)做选主,这是 Lesson 0009 的伏笔,可以先玩一下 Raft 可视化[2]

§3 · 把它接回四步框架

第 ③ 步画数据层时,用这套话术出口:「本场景读写比 X:Y、需要/不需要跨表事务、预计数据量 Z,因此选 __;读压力先上 N 个只读副本,写扩展留到数据量达 __ 时再分片(Lesson 0006)。」——每句话都有依据,评审官直接通过。

§4 · 随堂检测

§5 · 检索练习

凭记忆回答:① 选库五问是哪五问?② 复制延迟导致什么用户可见的 bug?至少说两个解法。③ 三种复制拓扑各自的代价?

核对参考答案

① 数据结构 / 事务需求 / 查询模式 / 规模 / 演进速度。② 读己之写被破坏(改完刷新看不到)——解法:关键读走主库、会话粘连(时间戳回退)、单调读。③ 主从:复制延迟;多主:写冲突协调;无主:一致性最弱、靠 quorum。

§6 · 本周行动

行动任务(约 40 分钟)

① 查你公司主库的复制拓扑:几个从库?延迟监控在哪里看?
② 找一处读己之写风险点:修改类操作成功后紧跟的读取,走的是主库还是从库?
③ 用五问法评估:如果明天 DAU 翻 10 倍,你们的库第一个爆掉的是什么?

§7 · 延伸资源

💬 想深聊「你们业务该选什么库」?把读写比和数据量报给我,我们现场推演。