第 10 章 · 数据库核心概念 数据库是系统的记忆。选型错误、设计失误的代价往往要数年才显现。本节系统梳理数据库的核心概念:SQL 与 NoSQL 的适用边界、ACID 与 CAP 的取舍逻辑、索引与范式的代价、分片与复制的区别,以及慢查询排查的标准方法,帮助你建立数据侧的完整认知地图。 学习目标 对比 SQL 与 NoSQL 的适用场景,能根据业务做出选型判断 解释 ACID 四性质,能区分 ACID 的 C 与 CAP 的 C 说出索引为什么加速查询又有维护代价,理解范式与反范式 区分分片与复制,掌握慢查询排查三步法 记住主流数据库的默认端口与典型场景 一、SQL 与 NoSQL 关系型数据库(SQL)与非关系型数据库(NoSQL)不是先进与落后,而是不同取舍: 维度 | SQL(如
数据库是系统的记忆。选型错误、设计失误的代价往往要数年才显现。本节系统梳理数据库的核心概念:SQL 与 NoSQL 的适用边界、ACID 与 CAP 的取舍逻辑、索引与范式的代价、分片与复制的区别,以及慢查询排查的标准方法,帮助你建立数据侧的完整认知地图。
关系型数据库(SQL)与非关系型数据库(NoSQL)不是先进与落后,而是不同取舍:
| 维度 | SQL(如 PostgreSQL/MySQL) | NoSQL(如 MongoDB/Redis/Cassandra) |
|---|---|---|
| 数据模型 | 表 + 行 + 列,强约束 Schema | 灵活:文档、键值、宽列、图 |
| Schema | 固定,需迁移 | 灵活可变,天然适配迭代 |
| 事务 | 强 ACID 事务 | 多数弱化或放弃跨文档事务 |
| 扩展方式 | 纵向为主,读可加副本 | 天然横向扩展(分片) |
| 一致性 | 强一致优先 | 多数最终一致 |
| 适用场景 | 金融、订单、库存等强一致性业务 | 海量数据、高并发、灵活模型、缓存 |
选型铁律:先用 SQL。绝大多数业务用关系型数据库都能解决;只有当出现明确的信号——海量数据水平扩展需求、极其灵活的模型、超高读写吞吐、缓存场景——才考虑 NoSQL。
事务(Transaction)是一组要么全部成功、要么全部失败的操作。ACID 是事务的四个性质:
| 性质 | 含义 | 反例说明 |
|---|---|---|
| A 原子性 Atomicity | 事务内的操作全部执行或全部不执行 | 转账扣款成功、入账失败 → 必须回滚 |
| C 一致性 Consistency | 事务前后数据始终满足约束与业务规则 | 余额不能为负;账户总额不变 |
| I 隔离性 Isolation | 并发事务互不干扰 | 两个事务同时改同一行不互相覆盖 |
| D 持久性 Durability | 事务提交后数据永久保存,不因宕机丢失 | 提交成功即落盘/WAL |
隔离级别由低到高:读未提交 → 读已提交 → 可重复读 → 串行化。级别越高并发越安全、性能越差。MySQL 默认可重复读,PostgreSQL 默认读已提交。隔离不足会引发脏读、不可重复读、幻读三类问题。
重点辨析:ACID 的 C(一致性)与 CAP 的 C(一致性)不是一回事。ACID 的一致性指数据库内部约束与业务规则;CAP 的一致性指分布式系统中各节点数据对外一致可见(线性一致性)。两者名字相同,含义完全不同。
CAP 定理:分布式系统中,网络分区(Partition)发生时,你必须在一致性(Consistency)与可用性(Availability)之间二选一,最多同时满足两个。
理解要点:CAP 只在网络分区这个前提下讨论,平时系统可以同时保证两者;分区恢复后,AP 系统通过补偿、对账等手段达到最终一致。
索引(Index) 是数据库为加速查询建立的数据结构(如 B+ 树)。
设计建议:索引建在查询频繁的列上;避免在选择性很低的列(如性别只有两个值)建索引;不要给每列都建索引。
范式(Normalization) 是消除数据冗余的设计规范,常见到第三范式(3NF):消除传递依赖,即"每个非主键列只依赖主键"。反范式(Denormalization) 则是故意引入冗余,用空间换时间——把频繁联表查询的数据冗余存储,避免大表 JOIN。实践中:OLTP 系统(交易类)通常适度规范化保证写入正确性;读多写少、报表类场景常做反范式设计。
分片(Sharding)与复制(Replication) 是两个不同的东西,常被混淆:
连接池(Connection Pool):建立数据库连接开销大,池化后复用连接,避免每次请求都新建/销毁。参数两个核心:池大小与等待超时。
连接泄漏(Connection Leak):应用拿到连接后未归还/未关闭,池被耗尽,新请求全部阻塞超时。典型症状:系统"突然"大量超时,数据库端连接数满。排查方向:检查是否有异常分支未释放连接、是否设置了合理的空闲回收。
慢查询排查标准三步:
NoSQL 按数据模型分四类:
| 类型 | 代表 | 典型场景 |
|---|---|---|
| 键值存储 Key-Value | Redis、Memcached | 缓存、会话、计数器 |
| 文档存储 Document | MongoDB、CouchDB | 灵活模型、内容类业务 |
| 宽列存储 Wide-Column | Cassandra、HBase | 海量时序/日志/物联网数据 |
| 图存储 Graph | Neo4j | 社交关系、推荐、反欺诈 |
常用数据库速查表(默认端口是常见面试点):
| 数据库 | 类型 | 默认端口 | 典型场景 |
|---|---|---|---|
| PostgreSQL | 关系型 | 5432 | 复杂查询、强一致性业务,功能最全的开源关系库 |
| MySQL | 关系型 | 3306 | Web 应用主流关系库 |
| MongoDB | 文档型 | 27017 | 灵活模型、快速迭代 |
| Redis | 键值型 | 6379 | 缓存、限流、分布式锁 |
| Cassandra | 宽列型 | 9042 | 海量写入、多数据中心 |
数据仓库(Data Warehouse) 与业务库(OLTP)不同:OLTP 面向交易,强调低延迟增删改查;数据仓库(如 ClickHouse、Snowflake、BigQuery)面向分析(OLAP),按列存储、批量导入、处理海量历史数据的聚合查询,为报表与 BI 服务。
数据库解决了"存得下",最后一节解决"传得动":消息队列在系统之间传递数据与事件。Kafka 作为事实标准的分布式事件流平台,它的 Topic 与 Partition 如何组织数据?Consumer Group 如何做到负载均衡又保证不重复消费?Offset 提交如何决定"丢消息"还是"重复消费"?下一节《消息队列与Kafka》收束本章。