数据库
相关源文件
介绍
本文档全面概述了后端架构中的数据库系统。内容涵盖关系数据库理论、MySQL 内部机制、NoSQL 数据库,以及在生产环境中设计、优化和维护数据库系统的基本知识。
有关数据库缓存策略的信息,请参阅缓存系统。有关分布式数据库架构,请参阅分布式系统设计。有关数据库中间件,请参阅数据管理。
来源: README.md187-201
数据库分类
来源: README.md187-201
数据库基础
关系数据库理论
关系数据库基于关系模型,将数据组织成行和列的表。它们使用 SQL(结构化查询语言)进行数据操作和查询。
- 第一范式 (1NF): 每列必须包含原子值(不可再分的值)
- 第二范式 (2NF): 必须满足 1NF,并且所有非主键属性必须完全依赖于主键
- 第三范式 (3NF): 必须满足 2NF,并且不允许存在传递依赖(非主键属性依赖于其他非主键属性)
来源: README.md1372-1376
数据一致性模型
来源: README.md584-596
事务 ACID 特性
- 原子性(Atomicity): 事务是全有或全无的操作
- 一致性(Consistency): 事务维护数据库完整性
- 隔离性(Isolation): 并发事务不应相互影响
- 持久性(Durability): 已提交的事务即使在系统故障时也能持久存在
来源: README.md584-585
隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 描述 |
|---|
| Read Uncommitted(读未提交) | 是 | 是 | 是 | 允许读取未提交的更改(最低级别) |
| Read Committed(读已提交) | 否 | 是 | 是 | 仅允许读取已提交数据(许多数据库中的默认值) |
| Repeatable Read(可重复读) | 否 | 否 | 是 | 同一查询在事务中返回相同结果(MySQL InnoDB 默认) |
| 可序列化 | 否 | 否 | 否 | 完全隔离(事务如同串行运行) |
来源: README.md587-596
MySQL
MySQL 是最流行的开源关系数据库管理系统之一。它提供多种具有不同特性的存储引擎。
架构和组件
来源: README.md1380-1386
存储引擎比较
| 功能 | InnoDB | MyISAM |
|---|
| 事务 | 是 | 否 |
| 外键 | 是 | 否 |
| 锁定 | 行级 | 表级 |
| ACID | 是 | 否 |
| 全文搜索 | 是 (MySQL 5.6+) | 是 |
| 聚簇索引 | 是 | 否 |
| 自动恢复 | 是 | 否 |
来源: README.md1383-1384
InnoDB
InnoDB 是 MySQL 的默认存储引擎,提供符合 ACID 特性的事务功能、外键支持和行级锁定。
MVCC(多版本并发控制)
InnoDB 实现了 MVCC 来管理并发数据访问
- 每行包含用于创建时间和删除时间的隐藏列
- 事务只操作与其快照相关的行版本
- 主要用于可重复读隔离级别
- 更新期间可能导致幻读问题
来源: README.md605-616
索引
来源: README.md1394-1426
聚簇索引与非聚簇索引
- 聚簇索引: 基于键值物理组织表数据;每张表只有一个聚簇索引(通常是主键)
- 非聚簇索引: 创建一个独立的结构指向数据行;一张表可以有多个非聚簇索引
在 InnoDB 中,表按主键(聚簇索引)组织,而 MyISAM 对包括主键在内的所有索引都使用非聚簇索引。
来源: README.md1406-1412
复合索引
复合索引跨多个列。MySQL 使用最左前缀匹配原则
- 如果索引建立在 (col1, col2, col3) 上,那么查询可以在以下情况使用:
- col1
- col1 AND col2
- col1 AND col2 AND col3
- 只根据 col2 或 col3 过滤而不使用 col1 的查询将无法有效使用复合索引
来源: README.md1413-1421
使用 EXPLAIN 进行查询优化
EXPLAIN 命令揭示了 MySQL 如何执行查询,显示:
- 涉及的表
- 访问类型(range, index, ALL)
- 使用的索引
- 检查的行数
- 额外操作(排序、临时表)
来源: README.md1427-1429
MySQL 优化最佳实践
- 正确地为 WHERE 子句和 JOIN 中使用的列建立索引
- 避免使用 SELECT *,只请求所需的列
- 对于大型结果集使用 LIMIT
- 优化模式设计并适当范式化
- 对大型表进行分区
- 定期分析和优化表
- 使用预处理语句
- 适当配置 MySQL 缓冲区大小
来源: README.md1392-1402
NoSQL 数据库
NoSQL(“不仅仅是 SQL”)数据库提供了传统关系模型的替代方案,专为特定的数据模型和用例而设计。
来源: README.md1430-1452
MongoDB
MongoDB 是一种面向文档的 NoSQL 数据库,以灵活的类 JSON 文档形式存储数据。
主要特性
- 无模式设计,具有动态文档结构
- 高写入吞吐量
- 通过分片实现内置水平扩展
- 支持复杂的嵌套数据结构
- 内嵌 GridFS 用于文件存储
- 弱一致性(最终一致性)
局限性
- 有限的事务支持(在新版本中有所改进)
- 比关系数据库占用更多磁盘空间
- 与关系型数据库管理系统 (RDBMS) 相比,管理工具不够成熟
来源: README.md1432-1438
HBase
HBase 是一个分布式、列族 NoSQL 数据库,模仿谷歌的 BigTable。
主要特性
- 列式存储,针对稀疏数据集进行优化
- 建立在 Hadoop 生态系统之上
- 线性可伸缩性
- 自动分片
- 行操作内部的强一致性
- 专为大型数据集上的高吞吐量而设计
- 空值不占用存储空间
行键设计考量
- 键按字典顺序排序
- 智能键设计对性能至关重要
- 可以使用加盐/哈希来防止热点问题
- 顺序访问比随机访问更高效
来源: README.md1439-1452
关系型数据库 (RDBMS) 与 NoSQL 比较
| 功能 | 关系型数据库 (RDBMS) | NoSQL |
|---|
| 数据模型 | 固定模式的结构化表 | 多样:文档、键值、列、图 |
| 模式 | 强制固定模式 | 模式灵活或无模式 |
| 扩展 | 主要为垂直扩展(向上扩展) | 主要为水平扩展(向外扩展) |
| 事务 | 符合 ACID | BASE(基本可用性、软状态、最终一致性) |
| 查询语言 | SQL | 数据库特定 API 和查询语言 |
| 一致性 | 强一致性 | 通常是最终一致性(因数据库而异) |
| 用例 | 结构化数据、复杂事务 | 大数据、实时 Web 应用、高吞吐量 |
来源: README.md1432-1452
数据结构考量
数据库索引中的 B+ 树
B+ 树索引是现代数据库系统的基础,尤其在 MySQL 的 InnoDB 中
- 叶子节点包含数据指针并形成一个链表用于范围扫描
- 非叶子节点仅用于导航
- 平衡树结构确保一致的性能
- MySQL 的 InnoDB 对聚簇索引和二级索引都使用 B+ 树
来源: README.md418-424
LSM 树
日志结构合并树(Log-Structured Merge Trees,LSM)是一种替代索引结构,用于 HBase 和 LevelDB 等数据库
- 针对写密集型工作负载进行了优化
- 数据首先写入内存结构,随后刷新到磁盘
- 多个小型树最终会合并成大型树
- 读取操作需要搜索多个树(通过布隆过滤器等技术缓解)
- 牺牲部分读取性能以换取写入性能
来源: README.md424-436
数据库设计最佳实践
- 遵循范式化原则,以避免数据冗余和异常
- 根据您的工作负载选择正确的数据库类型(关系型数据库 vs. NoSQL)
- 根据查询模式设计有效的索引策略
- 使用适当的数据类型以优化存储和性能
- 从一开始就规划扩展性(分片、复制)
- 实施适当的安全措施(身份验证、授权、加密)
- 设计模式和索引时考虑数据访问模式
- 记录您的数据库设计决策和模式
来源: README.md1372-1452
数据库扩展策略
读写分离
来源: README.md1860-1866
数据库分库分表
常见分片策略
分片挑战
- 跨分片 JOIN
- 分布式事务
- 模式变更
- 数据重平衡
来源: README.md1870-1880
结论
数据库系统是任何后端架构的基本组成部分。有效的数据库设计、选择和管理需要理解各种数据库技术的理论原则和实际实现细节。无论是使用传统关系数据库还是现代 NoSQL 解决方案,架构师都必须根据具体的用例、性能要求和可伸缩性需求做出明智的决策。