MySQL数据库——存储引擎

1. MySQL体系结构

MySQL数据库——存储引擎_第1张图片


MySQL的体系结构主要包括以下四个层次:

  1. 连接层
    • 这是最上层,负责处理客户端与服务器之间的连接。
    • 包括本地套接字通信和基于TCP/IP的远程通信。
    • 主要功能包括连接处理、用户身份验证、权限检查以及安全方案实施,如SSL加密连接。
    • 在这一层引入了线程池的概念,为已通过认证的客户端分配线程,提高服务效率。
  1. 服务层
    • 第二层是核心服务层,实现大部分关键功能。
    • 包括SQL接口、查询缓存、SQL解析和优化,以及部分内置函数的执行。
    • 跨存储引擎的功能也在这一层实现,例如存储过程和函数。
    • 在这一层,服务器将接收的SQL语句解析成内部解析树,并进行优化,如确定表的查询顺序和是否使用索引。
    • 对于SELECT语句,服务器会查询内部的查询缓存,如果缓存命中,可以显著提高系统性能。
  1. 引擎层
    • 存储引擎层负责数据的实际存储和检索。
    • 服务器通过API与存储引擎进行通信。
    • MySQL支持多种存储引擎,每种引擎具有不同的特性和功能,可以根据实际需求选择合适的存储引擎。
    • 索引是在存储引擎层实现的,不同的存储引擎可能使用不同的索引结构和算法。
  1. 存储层
    • 数据存储层位于最底层,负责在文件系统上存储和管理数据。
    • 数据包括但不限于重做日志(redolog)、回滚日志(undolog)、实际数据、索引、二进制日志、错误日志、查询日志、慢查询日志等。
    • 存储层与存储引擎交互,确保数据的正确存储和访问。

2. MySQL存储引擎

存储引擎在数据库系统中扮演着至关重要的角色,可以将其比喻为数据库的“发动机”。就像不同类型的机械设备(如舰载机、直升机、火箭)需要配备适合其特性和需求的引擎一样,MySQL数据库也需要选择合适的存储引擎来优化数据的存储、访问和管理。

存储引擎是数据库系统中负责数据存储、索引构建、数据更新和查询等核心操作的具体实现技术。它是基于表级别的,也就是说,每个表都可以选择使用不同的存储引擎,而不是在整个数据库级别统一决定。

在MySQL中,我们在创建表的时候可以选择指定使用的存储引擎,如果没有明确指定,系统会使用默认的存储引擎。不同的存储引擎有其独特的特性,适用于不同的应用场景。例如,有些存储引擎擅长处理读密集型的工作负载,提供快速的查询性能;而有些引擎则专注于事务处理和数据一致性,适合在需要频繁更新和多用户并发访问的环境中使用。


  1. 建表时设置存储引擎
CREATE TABLE 表名(
字段1 字段1类型 [ COMMENT 字段1注释 ] ,
......
字段n 字段n类型 [COMMENT 字段n注释 ]
) ENGINE = INNODB [ COMMENT 表注释 ] ;
  1. *查询当前数据库支持的存储引擎
show engines;

示例:

  • 查询建表语句 --- MySQL默认存储引擎: InnoDB
show creat table 表名

MySQL数据库——存储引擎_第2张图片

当初在创建表account的时候是没有指定存储引擎的,但MySQL会默认指定InnoDB为存储引擎

  • 查询当前数据库支持的存储引擎
show engines;

MySQL数据库——存储引擎_第3张图片


3. *存储引擎分类

3.1. *InnoDB

  1. InnoDB介绍
    InnoDB是一种强大的存储引擎,设计目标是提供高可靠性和高性能。自从MySQL 5.5版本之后,InnoDB成为默认的存储引擎选择。它被广泛应用于各种场景,特别是那些需要处理大量数据、确保数据一致性和并发访问的环境。

  1. InnoDB特点(事务、外键、行级锁)
  • DML操作遵循ACID模型,支持事务:InnoDB引擎保证了数据的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。在进行数据插入(INSERT)、更新(UPDATE)或删除(DELETE)等操作时,可以使用事务来确保这些操作要么全部成功,要么全部失败,从而维护数据的完整性。
  • 行级锁,提高并发访问性能:InnoDB采用行级锁机制,这意味着在执行数据修改操作时,只会锁定涉及到的具体行,而不是整个表。这种锁机制极大地提高了在多用户并发访问环境下的系统性能,因为不同用户可以同时修改不同的行,而不会互相阻塞。
  • 支持外键FOREIGN KEY约束,保证数据的完整性和正确性:InnoDB支持定义外键约束,这可以确保引用完整性,即只允许在外键列中插入已存在于主键列中的值。通过实施这种约束,InnoDB能够防止出现不符合业务规则的数据,保证了数据的准确性和一致性。

  1. 文件
  • xxx.ibd文件在InnoDB存储引擎中代表特定表的数据和索引存储。这里的"xxx"是指具体的表名。每个InnoDB表都会有一个对应的.ibd文件,除非数据库配置为使用共享表空间(innodb_file_per_table设置为OFF)。
  • 在InnoDB中,表结构信息以前是存储在.frm文件中的,这是MySQL用来存储表定义的通用格式,包括列类型、约束等元数据。然而,对于InnoDB引擎,从MySQL 8.0开始,表结构信息改为存储在.sdi文件中,这是一种新的二进制格式,旨在提高表定义的读取和写入性能。
  • xxx.ibd文件包含了表的实际数据和索引,这些数据和索引在物理上组织为页(Pages),并且可能进一步组织为区(Extents)和段(Segments)。这些底层的存储结构有助于InnoDB实现其行级锁定、事务处理和其他高性能特性。

show variables like 'innodb_file_per_table';

MySQL数据库——存储引擎_第4张图片

如果该参数开启,代表对于InnoDB引擎的表,每一张表都对应一个ibd文件。 我们直接打开MySQL的数据存放目录: C:\ProgramData\MySQL\MySQL Server 8.0\Data , 这个目录下有很多文件夹,不同的文件夹代表不同的数据库

MySQL数据库——存储引擎_第5张图片

(如果没有找到,你可能需要关掉隐藏文件夹的设置)

MySQL数据库——存储引擎_第6张图片

一个表就代表一个 .ibd文件

MySQL数据库——存储引擎_第7张图片

ibd文件中不仅存放表结构、数据,还会存放该表对应的索引信息。 而该文件是基于二进制存储的,不能直接基于记事本打开,我们可以使用mysql提供的一个指令 ibd2sdi ,通过该指令就可以从ibd文件中提取sdi信息,而sdi数据字典信息中就包含该表的表结构。

MySQL数据库——存储引擎_第8张图片

  1. 逻辑存储结构

MySQL数据库——存储引擎_第9张图片

  1. 表空间(Tablespace)
    • 表空间是InnoDB逻辑存储的最高层,它是数据和索引的实际容器。
    • 默认情况下,InnoDB有一个共享的系统表空间(通常名为ibdata1),所有表的数据和索引都会存储在这个表空间内。
    • 从MySQL 5.6.7版本开始,可以启用innodb_file_per_table选项,这样每个InnoDB表的数据和索引将存储在各自的表空间文件中,文件名通常是.ibd格式。
  1. 段(Segment)
    • 表空间是由多个段组成的,每个段代表了表的一部分数据或索引。
    • 主要的段类型包括数据段(Data Segment)、索引段(Index Segment)和回滚段(Rollback Segment)。
    • 数据段包含了表的数据页,即B+树的叶子节点;索引段包含了表的索引页,即B+树的非叶子节点。
  1. 区(Extent)
    • 区是由连续的页组成的空间,每个区的大小固定为1MB。
    • 为了保证页的连续性,InnoDB会一次性从磁盘申请4-5个区。
    • 默认情况下,InnoDB的页大小为16KB,所以一个区包含64个连续的页。
  1. 页(Page)
    • 页是InnoDB存储的基本单位,也是磁盘I/O操作的最小单位。
    • 每个页的大小默认为16KB,可以在配置文件中修改。
    • 页中包含了行数据和一些额外的信息,如页头、行溢出数据、空闲空间等。
  1. 行(Row)
    • 在数据页中,实际的数据以行的形式存储。
    • InnoDB使用聚集索引,这意味着表中的数据按照主键的顺序物理地存储在数据页中。
  1. 其他组件
    • 回滚段(Undo Logs):用于存储事务回滚所需的旧版本数据,以便在发生事务回滚时能够恢复到事务开始前的状态。
    • 插入缓存索引页(Insert Buffer):用于处理非唯一二级索引的插入操作,减少随机写磁盘的次数。

这个逻辑存储结构的设计使得InnoDB能够有效地管理数据和索引,提供高速的查询性能和良好的数据一致性。同时,通过合理的空间分配和管理,InnoDB还能有效利用磁盘空间并减少碎片。


用一个简单的例子解释就像一个图书馆:

假设我们有一个大型的图书馆,这个图书馆的管理可以类比为InnoDB的存储引擎。

  1. 表空间(Tablespace)
    • 整个图书馆可以看作是一个表空间,它是所有书籍和目录的实际容器。
  1. 段(Segment)
    • 图书馆中的每个书架可以看作是一个段,每个书架上存放的是某一类别的书籍或者是一套丛书。
  1. 区(Extent)
    • 每个书架上的每一排书架可以看作是一个区,这一排书架上放的是连续的一系列书籍。
  1. 页(Page)
    • 每本书可以看作是一个页,它是图书馆管理的基本单位。
  1. 行(Row)
    • 在每本书中,具体的内容(如章节、段落等)可以看作是行。
  1. 其他组件
    • 回滚日志(Undo Logs):类似于图书馆的借阅记录,记录了书籍被借出和归还的状态,以便在需要时恢复到之前的状况。
    • 插入缓存索引页(Insert Buffer):类似于新进书籍的临时存放区域,新书先放在这个区域,然后在合适的时间(比如整理书架时)再将其放入对应的书架。

在这个例子中,当你查找一本书时,图书馆管理员会首先查看目录(相当于主键索引),找到书所在的书架和位置(相当于数据页)。如果书架上有多个同类别的书籍(相当于二级索引),管理员还会进一步查找具体的书籍。


3.2. MyISAM

MyISAM 是 MySQL 中的一个早期的存储引擎,虽然现在已经被 InnoDB 引擎广泛取代,但在某些特定场景下,由于其一些特性,仍然可能被选择使用。

  1. 介绍

MyISAM 是 MySQL 最初的默认存储引擎之一,它以其简单和快速的数据读取性能而闻名。尽管在许多现代应用中,由于其功能限制,MyISAM 已不再作为首选引擎,但在一些读取密集型且对事务处理要求不高的场景中,MyISAM 可能仍具有一定的优势。

  1. 特点

不支持事务:这意味着在 MyISAM 中,无法实现原子性、一致性、隔离性和持久性(ACID)的事务操作。如果在执行一系列操作过程中发生错误或中断,无法通过回滚恢复到事务开始前的状态。

不支持外键:MyISAM 不支持外键约束,这限制了在表间建立参照完整性的能力。在需要确保数据一致性和引用关系的情况下,可能需要在应用程序层面进行额外的检查和控制。

支持表锁:在 MyISAM 中,当一个查询正在执行时,会对整个表进行锁定,阻止其他并发的写入操作。这种锁定机制在读取密集和写入较少的环境中可以提供良好的性能,但在高并发写入的场景下可能会导致性能瓶颈和锁竞争问题。

访问速度快:由于其简单的设计和优化,MyISAM 在读取操作上通常比 InnoDB 等支持复杂特性的引擎更快。尤其是在只读或者大部分是读取操作的应用中,MyISAM 的性能表现往往更优。

  1. 文件

MyISAM 将每个表的数据和索引存储在三个不同的物理文件中:

xxx.frm:这个文件存储了表的结构信息,包括列名、数据类型、索引等元数据。

xxx.MYD:这个文件用于存储实际的数据内容,即表中的行记录。

xxx.MYI:这个文件包含了表的索引信息,用于加速数据的查找和排序操作。

这样的设计允许数据和索引分别存储和管理,有助于在特定情况下优化磁盘I/O和提高查询性能。然而,这也意味着在进行备份或者复制时,需要同时处理这三个文件以确保数据的一致性。此外,由于不支持事务和崩溃恢复机制,MyISAM 表在遇到系统崩溃或其他意外情况时可能存在数据丢失的风险。


3.3. Memory

  1. 介绍

Memory(也称为 HEAP)是 MySQL 中的一个存储引擎,其主要特点是将表的数据存储在内存中。由于数据完全驻留在内存中,Memory 引擎提供了非常快的数据访问速度,特别适合用于临时数据的存储、高速缓存或者需要频繁读写但对持久性要求不高的场景。

然而,由于 Memory 表的数据仅存在于内存中,它存在一些限制和风险。硬件问题、系统崩溃或断电等情况可能导致内存中的数据丢失。因此,Memory 表通常不用于存储需要长期保留或对数据完整性要求严格的重要数据。相反,它们更适合用作中间结果的暂存区、高速计算的临时表,或者用于缓存经常查询但变化不频繁的数据。

  1. 特点

内存存放:Memory 表的数据和索引都存储在服务器的内存中,这使得对数据的访问速度极快,因为内存的访问速度远超过磁盘。

hash 索引(默认):Memory 表默认使用哈希索引(hash index),这是一种基于哈希函数的索引结构。哈希索引对于等值查询(如 WHERE column = value)的性能非常优秀,因为可以直接通过哈希函数快速定位到数据。但是,哈希索引不支持范围查询(如 WHERE column BETWEEN value1 AND value2)和排序操作。

  1. 文件

在 Memory 存储引擎中,表的结构信息存储在一个名为 xxx.frm 的文件中,这个文件与其它存储引擎(如 InnoDB 和 MyISAM)中的 frm 文件作用相同,用于保存表的结构定义,包括列名、数据类型、索引等元数据。

需要注意的是,由于 Memory 表的数据存储在内存中,当 MySQL 服务器关闭时,这些数据会丢失。如果希望在服务器重启后恢复 Memory 表的内容,可以启用 Memory 表的持久化选项(例如,使用 MEMORY-storage-engine 参数的 persistent 选项)。这将在磁盘上创建一个文件来存储 Memory 表的数据,但是请注意,这种持久化机制并不提供事务安全性和崩溃恢复功能,只能作为数据的部分备份。在实际应用中,应根据具体需求权衡 Memory 表的使用和可能的风险。


3.4. 区别与特点

特点

InnoDB

MyISAM

Memory

存储限制

64TB

事务安全

支持

-

-

锁机制

行锁

表锁

表锁

B+tree索引

支持

支持

支持

Hash索引

-

-

支持

全文索引

支持(5.6版本之后)

支持

-

空间使用

N/A

内存使用

中等

批量插入速度

支持外键

支持

-

-


3.5. 存储引擎选择

在选择数据库的存储引擎时,应根据你的应用系统的特性和需求来做出合适的选择。

  1. InnoDB:
    • InnoDB是MySQL的默认存储引擎。
    • 它支持事务处理和外键约束,这使得它在需要保证数据完整性和一致性的情况下表现出色。
    • 如果你的应用程序涉及到大量的数据更新、删除操作,并且在高并发环境下对数据的一致性有严格要求,那么InnoDB存储引擎是一个理想的选择。
  1. MyISAM:
    • MyISAM存储引擎更适合那些主要以读取和插入操作为主的应用程序。
    • 如果你的应用中更新和删除操作较少,而且对事务的完整性以及并发处理的要求相对较低,那么MyISAM存储引擎可能是一个更为适合的选择。
  1. MEMORY:
    • MEMORY存储引擎将所有数据存储在内存中,因此其访问速度非常快,特别适合用于需要快速响应的临时表或者作为数据缓存。
    • 然而,MEMORY引擎有一些限制。首先,它对表的大小有限制,如果表数据过大,可能无法全部存储在内存中。其次,由于数据仅存储在内存中,在服务器重启或出现故障时,可能会导致数据丢失,因此它不能保证数据的安全性。

对于复杂的应用系统,可以根据不同表的功能和使用情况灵活选择和组合多种存储引擎,以优化系统性能和满足各种特定需求。例如,可以使用InnoDB处理需要事务和并发控制的核心数据,同时使用MyISAM存储读取密集型的静态数据,以及使用MEMORY作为临时数据或缓存区域。这样的组合可以最大化地发挥各存储引擎的优点,提高整个应用系统的效率和稳定性。


你可能感兴趣的:(数据库技术,数据库,mysql,学习,笔记,sql)