菜单

数据库

相关源文件

本页介绍数据库系统及其在可扩展系统设计中的作用。它解释了关系型数据库和 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 VARCHARINT 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 之间进行选择需要评估你的具体需求

标准SQLNoSQL
数据结构结构化、定义明确的模式半结构化、灵活的模式
扩展模型垂直扩展,复杂的水平扩展为水平扩展设计
ACID 事务完全支持因数据库而异;通常为性能而牺牲
查询复杂度复杂连接,高级查询更简单的查询模型,数据库特定的查询语言
用例金融系统、库存、ERP大数据、实时 Web 应用、高吞吐量系统
开发速度模式更改可能很慢采用灵活模式可加快开发速度
一致性强一致性因数据库而异;通常是最终一致性

选择 SQL 的情况

  • 数据结构化且关系明确
  • 需要复杂的查询和事务
  • ACID 合规性是必需的
  • 数据完整性至关重要

选择 NoSQL 的情况

  • 模式快速演变或不可预测
  • 水平扩展是优先事项
  • 需要非常高的写入吞吐量
  • 数据本身是文档型、图型等
  • 预计将达到极致规模(TB/PB)

来源:README.md:1090-1131

系统设计中常见的数据库架构模式

在大型系统中,数据库通常采用以下模式部署

  1. 缓存层:通过缓存常见查询来减少数据库负载
  2. 读副本:通过主从复制扩展读取流量
  3. 写分片:将写入负载分布到多个数据库服务器
  4. 数据分区:垂直或水平划分数据以管理规模
  5. 连接池:高效管理和重用数据库连接

来源:README.md:1132-1139, README.md:829-843, README.md:896-916

结论

选择合适的数据库技术是影响系统可扩展性、性能和可维护性的关键架构决策。现代系统通常采用多种数据库技术来满足其数据管理的不同需求,在多语言持久化架构中充分利用 SQL 和 NoSQL 数据库的优势。

有关相关主题的更多信息,请参阅

来源:README.md:1090-1131, README.md:1135-1139