数据库
相关源文件
本页介绍数据库系统及其在可扩展系统设计中的作用。它解释了关系型数据库和 NoSQL 数据库技术、复制策略、扩展方法以及不同用例的选择标准。有关数据库缓存的详细信息,请参阅缓存。
概述
数据库是数据的结构化集合,包含存储、检索和管理机制。在系统设计中,数据库作为持久化存储层,对应用程序的可扩展性、性能和可靠性起着至关重要的作用。
来源:README.md:809-815, README.md:816-827, README.md:994-1001
关系型数据库管理系统 (RDBMS)
关系型数据库将数据组织成包含行和列的表。它使用 SQL(结构化查询语言)来定义、操作和查询数据。
ACID 特性
RDBMS 实现遵循 ACID 特性以确保可靠的事务处理
| 属性 | 描述 |
|---|
| 原子性 | 每个事务都是全有或全无 |
| 一致性 | 任何事务都将数据库从一个有效状态转换为另一个有效状态 |
| 隔离性 | 并发执行事务与串行执行事务的结果相同 |
| 持久性 | 一旦事务提交,它将永久保持提交状态 |
来源:README.md:818-826
扩展技术
随着数据和查询量的增长,可以采用各种技术来扩展关系型数据库。
主从复制
在主从复制中
- 主库处理读写操作,并将写操作复制到从库
- 从库只处理读操作
- 如果主库发生故障,系统将以只读模式运行,直到从库被提升为主库或配置了新的主库
- 可以添加额外的从库以提高读取的可扩展性
优点
- 通过添加更多从库实现读取可扩展性
- 从库可以位于不同的地理区域
- 提高读取操作的可用性
缺点
- 写操作仍然集中在主库上
- 如果主库在复制之前发生故障,可能导致数据丢失
- 读副本可能存在复制延迟
- 增加了系统架构的复杂性
来源:README.md:829-843, README.md:861-867
主主复制
在主主复制中
- 多个主库处理读写操作
- 主库之间协调写操作
- 如果一个主库发生故障,系统仍能继续运行
优点
- 提高写入可用性
- 写操作的负载均衡
- 写能力的地理分布
缺点
- 冲突解决的复杂性增加
- 潜在的一致性问题
- 更高的同步开销
- 更复杂的故障恢复
来源:README.md:844-860
联邦
联邦(或功能分区)按功能拆分数据库
- 你不再使用单一的整体式数据库,而是为不同功能(用户、产品、订单)创建单独的数据库
- 每个数据库处理更少的读写操作
- 应用程序逻辑将查询定向到相应的数据库
优点
- 更小的数据库更适合内存
- 并行写入不同的数据库
- 减少复制延迟
- 更好的缓存局部性
缺点
- 需要跨数据库连接的模式变得复杂
- 应用程序必须跟踪哪个数据库处理哪些数据
- 跨数据库的事务很复杂
- 增加了硬件和操作复杂性
来源:README.md:874-890
分片
分片将数据分布到多个数据库中,每个数据库只管理数据的一个子集
- 数据通过分片键(例如,用户 ID、地理位置)进行分区
- 每个分片包含完整的模式,但只包含部分数据
- 随着数据增长,可以添加更多分片
优点
- 减少每个分片的索引大小
- 提高查询性能
- 支持跨分片的并行写入
- 允许水平扩展
缺点
- 跨多个分片的查询很复杂
- 数据分布不均(热点)
- 重新平衡数据具有挑战性
- 跨分片的事务很难实现
- 增加了操作复杂性
来源:README.md:896-916
优化技术
反范式化
反范式化涉及添加冗余数据以避免昂贵的连接操作
- 以牺牲写入性能为代价提高读取性能
- 在表之间创建冗余数据副本
- 避免复杂的连接操作,尤其是在分片或联邦之后
反范式化有帮助的情况
- 读密集型系统(读写比为 100:1 或更高)
- 当连接操作昂贵且频繁使用时
- 当数据分布在多个数据库中时
缺点
- 数据重复增加了存储需求
- 引入数据不一致风险
- 更新需要修改多个副本
- 更高的维护开销
来源:README.md:924-936
SQL 调优
SQL 调优涉及通过精心设计的查询、索引策略和模式优化来优化数据库性能
模式优化
- 使用适当的数据类型(
CHAR vs VARCHAR,INT vs DECIMAL)
- 在适用时设置
NOT NULL 约束
- 对大内容使用
TEXT 并正确存储 BLOB
索引策略
- 在频繁查询的列上创建索引
- 平衡索引的优点与对写入性能的影响
- 理解 B 树结构以进行最优索引设计
查询优化
- 避免昂贵的连接操作
- 使用高效的 WHERE 子句
- 优化子查询性能
- 在适当时候使用查询提示
其他技术
- 对热点数据进行表分区
- 适当配置查询缓存
- 统计信息维护
- 定期进行 EXPLAIN 计划分析
来源:README.md:942-989
NoSQL 数据库系统
NoSQL 数据库提供了关系模型的替代方案,通常牺牲 ACID 合规性以换取可扩展性和性能。它们通常遵循 BASE 原则
- 基本可用 - 系统保证可用性
- 软状态 - 状态可能在没有输入的情况下改变
- 最终一致性 - 系统随着时间推移变得一致
来源:README.md:992-999
键值存储
键值存储提供基于键的简单、快速的存储和检索
- 数据以键值对形式存储
- 类似于哈希表数据结构
- 通常是内存型,带有持久化选项
- 通常是 O(1) 读/写操作
示例:Redis, Memcached, DynamoDB(部分)
用例
优点
- 简单的数据模型
- 极高的性能
- 高可扩展性
- 灵活的模式
缺点
- 有限的查询能力
- 不支持关系
- 某些实现中存在值大小限制
- 缺乏标准化的查询语言
来源:README.md:1003-1018
文档存储
文档存储将数据组织为灵活的半结构化文档
- 文档(通常是 JSON、XML 或 BSON)包含对象的所有数据
- 同一集合中的文档可以有不同的字段
- 支持嵌套数据结构
- 提供文档数据的查询能力
示例:MongoDB, CouchDB, DocumentDB
用例
- 内容管理系统
- 用户资料
- 产品目录
- 事件日志
- 实时分析
优点
- 模式灵活性
- 分层数据存储
- 原生支持 JSON/文档格式
- 无需复杂的连接
缺点
- 对于高度关系型数据效率较低
- 查询可能比 SQL 更复杂
- 事务通常有限或不符合 ACID
- 索引可能更复杂
来源:README.md:1020-1038
宽列存储
宽列存储将数据组织成表、行和动态列
- 基本单位是列(名称/值对)
- 列被分组到列族中
- 行由行键标识
- 每个值都包含一个时间戳用于版本控制
- 列可以动态添加并因行而异
示例:Cassandra, HBase, Google Bigtable
用例
- 时间序列数据
- 传感器数据
- 事务日志
- 推荐引擎
- 计数器和统计数据
优点
- 大型数据集的高可扩展性
- 快速写入和扫描
- 面向列用于分析查询
- 可调一致性
缺点
- 复杂的数据建模
- 对即席查询的支持有限
- 开发人员的学习曲线
- 可能不适用于高事务性工作负载
来源:README.md:1039-1061
图数据库
图数据库擅长处理高度连接的数据
- 数据存储为节点和关系(边)
- 节点和关系可以具有属性
- 针对遍历关系进行了优化
- 支持关系查询
示例:Neo4j, ArangoDB, Amazon Neptune, FlockDB
用例
- 社交网络
- 知识图谱
- 推荐引擎
- 网络和 IT 运营
- 欺诈检测
优点
- 连接数据的自然表示
- 高效的关系遍历
- 灵活的模式
- 复杂的关系查询
缺点
- 更陡峭的学习曲线
- 不如其他数据库类型成熟
- 对于简单数据模型可能过于复杂
- 水平扩展可能具有挑战性
来源:README.md:1062-1081
SQL vs NoSQL:选择标准
在 SQL 和 NoSQL 之间进行选择需要评估你的具体需求
| 标准 | SQL | NoSQL |
|---|
| 数据结构 | 结构化、定义明确的模式 | 半结构化、灵活的模式 |
| 扩展模型 | 垂直扩展,复杂的水平扩展 | 为水平扩展设计 |
| ACID 事务 | 完全支持 | 因数据库而异;通常为性能而牺牲 |
| 查询复杂度 | 复杂连接,高级查询 | 更简单的查询模型,数据库特定的查询语言 |
| 用例 | 金融系统、库存、ERP | 大数据、实时 Web 应用、高吞吐量系统 |
| 开发速度 | 模式更改可能很慢 | 采用灵活模式可加快开发速度 |
| 一致性 | 强一致性 | 因数据库而异;通常是最终一致性 |
选择 SQL 的情况
- 数据结构化且关系明确
- 需要复杂的查询和事务
- ACID 合规性是必需的
- 数据完整性至关重要
选择 NoSQL 的情况
- 模式快速演变或不可预测
- 水平扩展是优先事项
- 需要非常高的写入吞吐量
- 数据本身是文档型、图型等
- 预计将达到极致规模(TB/PB)
来源:README.md:1090-1131
系统设计中常见的数据库架构模式
在大型系统中,数据库通常采用以下模式部署
- 缓存层:通过缓存常见查询来减少数据库负载
- 读副本:通过主从复制扩展读取流量
- 写分片:将写入负载分布到多个数据库服务器
- 数据分区:垂直或水平划分数据以管理规模
- 连接池:高效管理和重用数据库连接
来源:README.md:1132-1139, README.md:829-843, README.md:896-916
结论
选择合适的数据库技术是影响系统可扩展性、性能和可维护性的关键架构决策。现代系统通常采用多种数据库技术来满足其数据管理的不同需求,在多语言持久化架构中充分利用 SQL 和 NoSQL 数据库的优势。
有关相关主题的更多信息,请参阅
来源:README.md:1090-1131, README.md:1135-1139