一个数据库管理系统(DBMS)是一种高度复杂的系统,设计用于管理大量数据,同时提供高效的只索引扫描和布隆过滤器等数据访问、存储和修改机制。下面是对架构的详细概述,其中包含了诸如布隆过滤器等概念。
1. 传输层.传输层(Transport Layer)是用户/应用程序与数据库管理系统(DBMS,Database Management System)之间的接口。它负责安全通信,并管理客户端会话(session)。
职责:
- 会话管理: 建立并维护客户端连接,具备连接池等功能。
- 认证与权限管理: 使用TLS/SSL等协议验证用户凭证和权限,确保安全连接。
- 通信协议支持: 支持SQL over TCP/IP或REST API等通信协议。
- 流量分配: 将客户端流量分配到各个节点,以达到最佳性能。
- 实际应用示例:
- PostgreSQL 支持 SSL/TLS 加密和负载均衡,以提供高可用性。
- MongoDB Atlas 提供智能路由,根据客户端位置减少延迟。
查询处理程序将用户的查询请求转换为高效的执行方案。
组件:
- 查询解析器: 验证语法并确保查询正确(例如,列和表是否存在)。
- 查询重写器: 通过重写查询来简化或优化查询过程(例如,展开视图或合并子查询)。
- 查询优化器:
- 生成执行计划并选择最经济高效的一个,使用:
- 基于成本的优化(CBO): 根据磁盘 I/O、内存和 CPU 使用情况估算成本。
- 此外,启发式优化: 应用规则,如将过滤器推向更接近数据源的位置以减少处理。
- 示例:
- 查询:
SELECT name FROM employees WHERE department = 'HR'
- 优化器可能会选择利用
department
的索引来避免全表扫描。
执行引擎
执行器是数据库中负责运行查询计划并高效返回结果的组件。
重要任务:
1. 本地操作
• 在一台机器上运行查询。
2. 远程运行:
将查询拆分并发送到分布式系统中的其他机器,然后收集并合并这些机器的结果。
3. 并行执行:
将工作拆分成可以同时进行的小任务,从而使整个过程更快。
高级的功能:
- 基于编译的执行:
• 不是一步一步地执行查询,而是直接将查询执行计划转换成快速的编译代码。
• 这样可以减少不必要的工作,比如频繁的函数调用,从而提高处理速度。
- 适应性执行:
• 根据执行过程中出现的情况(比如数据量或系统负载的变化)动态调整查询的运行方式。
- 向量化执行:
• 一次可以处理多行数据,而不是逐行处理。
• 这对于过滤或汇总大量数据的任务来说非常有帮助。
4. 动态代码生成
• 即时动态生成并运行自定义代码,以特定任务为目标进行优化。
Apache Spark 示例:
• 将查询拆分成可以在集群中的多台计算机上并行运行的小任务。
• 利用内存快速处理数据,减少磁盘读写的时间。
• 简单的例子:
比如这样的查询。
SELECT * FROM A WHERE x > 5
该查询从表A中选择所有x大于5的行。
• 一个基本的引擎会逐行进行检查;而编译型引擎则生成像这样的快速定制代码。
对于A中的每行row,如果row.x大于5,就将row添加到输出中。
这样做避免了不必要的步骤,运行速度更快。
存储引擎负责数据的存储、访问和修改。
组件:
- 数据保存:
• 管理磁盘和内存中的数据物理存储。
• 使用行式存储或列式存储等格式,例如行式存储或列式存储。
2. 索引管理:
• 创建并维护索引,以加快数据检索。
• 支持多种索引类型,例如B树、哈希和倒排索引。
3. 缓存池(缓存):
• 将频繁访问的数据保留在内存中以减少磁盘 I/O。
• 采用缓存策略(例如,LRU — 最近最少使用),以优化数据访问。
4. 事务协调器
• 确保ACID特性(原子性,一致性,隔离性,持久性)。
• 处理锁定、回滚以及提交等操作。
5. 日志记录和恢复
• 维护日志来跟踪更改,以实现崩溃恢复。
• 使用诸如写前日志(WAL)等技术来确保数据完整性。
6. 数据压缩
• 通过压缩数据而不丢失信息来减小存储空间。
7. 并发性控制
• 管理多个用户同时访问数据库的能力。
• 实现锁定或使用多版本并发控制(MVCC,多版本并发控制技术)。
8. 存储方式 :
根据数据库类型,可以处理不同的数据格式,例如二进制文件、JSON 或 CSV。
真实世界的例子如下:
- MySQL的InnoDB引擎使用聚集索引来高效地查找主键值。
- Amazon Aurora将计算和存储分离以实现可扩展性。
- Postgres使用内置存储引擎,具有MVCC和全文搜索等高级特性。
访问方法定义了数据库如何在执行查询期间高效地检索数据的方式。它们决定了用于定位和获取数据的具体技术。
关键访问方式
- 索引驱动的检索:
• 使用B树或哈希索引这样的结构可以提高查找效率。
• 适用于索引列上的查询。
示例:查询 id = 101 的行,使用 B 树索引。
2. 全表扫描查询 :
• 如果没有合适的索引,会扫描表中每一行。
• 适合小表或需要查询大部分行的情况。
3. 位图索引
• 将索引值压缩成位图,以实现高效过滤。
• 最适合用于低基数的列(例如“性别”或“状态”)。
• 例如:筛选状态为‘active’的行。
高级的概念
- 仅索引扫描方式:
• 它是什么:直接从索引中获取数据,无需访问主表即可。
• 它是怎么工作的:
• 如果查询需要的所有列都在索引里,则数据库会跳过查找表。
• 示例:
- PostgreSQL的可见性映射功能确保索引能够反映表的当前状态。
• 这使仅索引扫描成为可能,特别是在只读查询时。
• 查询:.
SELECT COUNT(*) FROM users WHERE status = 'active' (索引中读取)。
2. 布隆过滤器:
• 它是什麼:
• 一种概率数据结构,用于快速判断一个值是否可能存在于某个集合里。
• 它是如何工作的:
• Bloom过滤器将值哈希到比特数组中。
• 未能通过Bloom过滤器检查的值将被跳过,从而避免不必要的读写操作。
• 示例:
• 以下 SQL 查询:SELECT * FROM orders WHERE product_id IN (1001, 1002, 1003)
基于 product_id
的布隆过滤器可以删除肯定不符合条件的行,从而加快查询。
了解更多关于布隆过滤器的细节,可以看看这篇文章1
6. 缓冲区管理缓冲管理器通过缓存经常访问的数据来减少磁盘 I/O。
关键职责
- 缓存常访问的数据
• 将数据页存储在内存(缓冲池)中,以减少磁盘读写操作。
• 确保对相同数据的重复查询可以从内存中快速响应,而不是每次都从磁盘读取。
2.**页面替换规则**:
当内存满时,决定移除哪些数据(页)。常用的策略包括LRU、FLU等策略。
3. 脏页管理:
• 脏页就是那些在缓冲区里修改了但还没写回磁盘的数据页。
• 缓冲管理器会在后台把这些脏页悄悄写回磁盘:
• 确保在系统崩溃时数据仍然一致。
• 避免缓冲区满了之后产生性能瓶颈。
4. 预加载:
• 预测下一步会用到的数据,然后提前加载到缓冲区。
• 提高顺序扫描或重复模式的性能。
5. 并发控制
• 确保多个用户或查询可以安全地访问缓冲区,避免冲突。
• 使用锁定或闩锁机制来管理同时访问,以确保安全。
6. 缓冲区大小调整与分区:
• 为不同的数据类型(如索引和表)预留一部分内存。
• 平衡内存使用以优化各种工作负载下的查询性能。
示例:
PostgreSQL 使用共享缓冲区来缓存表页,从而提高查询性能。
Redis 采用全内存运行,从而实现极低延迟的数据访问。
恢复管理器在出现故障时保证数据库的一致性。
关键职责
- 使用日志来跟踪更改:
• 事务日志:
• 记录在事务过程中对数据库的所有改动。
• 日志类型:
• 重做日志文件:用于在系统故障后重新应用已提交事务的更改。
• 回滚日志(Undo Logs):用于回滚未完成的事务,以保持系统的状态一致性。
2. 检查点设置 :
• 定期将数据库的当前状态信息保存到磁盘。
• 有助于减少恢复时需要处理的数据。
示例:恢复过程从最后一个检查点开始,而不是从头开始重放所有的日志。
3. 系统崩溃恢复:
• 使用日志和检查点将数据库恢复到失败前的一致状态。
步骤如下:
• 重做阶段:重新执行所有已提交事务的更改。
• 撤销阶段:撤回未完成事务的更改。
4. 耐用性 :
一旦交易提交,其更改会被永久保存,即使遇到崩溃也不受影响。
安全层确保数据的保密性、数据完整性和合规性。
主要特点
- 身份验证。
• 确认尝试访问数据库的用户身份。
• 常见方法:
• 密码:基本但很常用。
• OAuth:允许用户通过受信任的第三方(如Google或Facebook)登录账号。
• 证书:安全地识别用户或系统。
- 加密,
• 确保未经授权的用户无法读取数据:
• 静止时:加密存储的数据,例如文件或备份中的数据。
• 示例:Oracle 的透明数据加密(TDE)会自动加密存储的数据。
• 传输中:在数据传输过程中加密(例如,使用 TLS/SSL)。
3. 审计:
• 记录访问数据库的人以及他们所进行的操作。
• 用途如下:
• 符合规定:证明符合规定和法律。
• 法医调查:帮助调查可疑行为或安全漏洞。
如下查询: SELECT COUNT(*) FROM 订单 WHERE status = 'shipped';
- 目标: 计算状态为'shipped'的订单数量。
负责数据传输的计算机网络中的一个层次
- 输入: 接收来自客户端的查询。
- 处理: 确认客户端身份,并将查询发送到查询处理程序。
- 输出: 将其发送给查询处理程序。
- 解析器:
- 验证查询语法的正确性并检查表和列是否存在。
- 生成抽象语法树(AST)。
- 优化器:
- 识别到
status
上的索引,并决定执行索引-only扫描。 - 创建执行计划,通过索引获取行,而不需要扫描整个表。
- 任务调度:
- 将查询拆分成更小的任务。
- 分配任务以实现并行处理。
- 输出结果: 将任务发送给存储引擎。
- 访问方法: 使用
status
索引执行仅索引扫描,直接统计行数。 - 缓冲管理器: 从内存中获取索引数据,如未缓存则从磁盘读取。
- 记录操作,以确保持久性保障。
- 将结果发送到结果汇总器。
- 汇总各个任务的分布式结果(如有必要)。
- 输出最终计数结果。
- 将结果格式化并返回客户端 (
COUNT(*) = 452
)。
- 高效的数据检索: 使用只读索引扫描和位图索引等技术减少不必要的磁盘 I/O。
- 可扩展设计: 分布式执行和 Bloom 过滤器等功能在大规模系统中优化性能。
- 可靠的恢复和安全功能: 恢复管理器和加密确保数据的一致性和保密。
共同學習,寫下你的評論
評論加載中...
作者其他優質文章