存储引擎
实际执行对数据库数据的存取。目前 MySQL 默认使用 InnoDB 引擎。相比于过去使用 MyISAM 引擎,有以下几个优势:
- 索引:数据文件本身是主索引。
- 外键:支持外键。
- 事务:添加本地日志,支持安全恢复;支持行级锁,提高并发度。
- 并发:支持多版本并发控制,提升性能。
索引
存储结构
MySQL 数据库使用以下两种数据结构存储和查找数据:
- B+ 树:(默认)适用于连续查询多条数据。
- 哈希表:适用于查询单条数据。
索引类型
索引名称|索引类型|字段类型|备注 -|-|- PRIMARY KEY|主索引|主键|字段值不能重复,也不能为空。 INDEX|普通索引|自定义字段|无,效率低。 UNIQUE|唯一索引|自定义字段|字段值不能重复,效率高。 FULLTEXT|文本索引|自定义字段|无,用于文本检索。
- 主索引
在 InnoDB 存储引擎中数据文件本身就是主索引(聚簇索引):数据以 B+ 树形式存储,根据主键值进行排序。
我们可以为其他字段建立辅助索引(非聚簇索引),以提高对字段的查询速度,但同时会降低表的更新速度。在辅助索引中记录主键值而不是字段地址:根据辅助索引查找后,仍需要根据主键值在主索引中查询数据。
- 组合索引
索引内可以包含多个字段,N 个字段的组合索引实际建立了 N 个索引。
对 a/b/c 三个字段建立的组合索引,实际会先在 a 索引中查找,再到 a/b 索引中查找,最后在 a/b/c 索引中查找。
视图
视图是一个虚拟表,不实际存储数据。其内容会通过查询其他表得到,在引用视图时动态生成。
- 权限管理:表的权限管理不能限制到具体的行和列,但通过视图则可以限制用户能得到的结果集。
- 数据独立:表的结构发生变化,不会对用户使用视图查询到的数据产生影响。
外键
从表通过外键关联到主表的主键,建立数据表之间的关系。
- 优点:保障数据的一致性和完整性。
- 缺点:增加数据之间的耦合度,难以集群。因此不推荐使用外键。
删除策略
对主表的数据进行 UPDATE/DELETE 操作时,将会会影响到关联的从表。
外键模式 | 删除策略 |
RESTRICT | (默认)从表有相关数据时,主表不能更新/删除。 |
CASCADE | 主表记录更新/删除时,从表相关记录也会被更新/删除。 |
SET NULL | 主表数据更新/删除时,从表相关记录的外键值被设为 NULL。 |
NO ACTION | 啥也不做 |
日志
当数据库数据发生更改时,用日志记录数据库操作。当发生错误或者冲突时,可以进行回滚。保证数据的一致性。
bin log 归档日志
最开始 MySQL 并没与 InnoDB 引擎,其他存储引擎只有通用的 bin 日志用来归档(位于 server 层)。
InnoDB 引擎完成主存数据更新后向执行器提交,由 bin 日志记录操作。如果主存数据已更新,且 bin 日志没有被写入时数据库崩溃,后续进行机器备份的时候就会丢失原有数据。这导致数据没有安全恢复的能力:一旦数据库发生异常重启,之前提交的记录都会丢失。
redolog 重做日志
MySQL 引入 InnoDB 引擎后,自带了 redo 日志。用于数据库发生异常重启时系统记录的恢复。
- InnoDB 引擎完成主存数据更新但还未提交时,由 redo 日志记录操作并进入 prepare 状态。
- InnoDB 引擎向执行器提交时,由 bin 日志记录操作。
- 提交完成后执行器通知 InnoDB 引擎,redo 日志进入 commit 状态。
如果 bin 日志没有被写入时数据库崩溃,后续进行机器备份的时候就会按照 redo 日志恢复数据。
如果 bin 日志已经写完但 redo 日志还处于 prepare 状态时数据库崩溃。MySQL 会判断 redo 日志是否完整,如果完整就立即提交。否则再判断 bin 日志是否完整,如果完整就提交 redo 日志,不完整就回滚事务。这样就解决了数据一致性的问题。