MySQL的体系结构主要包括以下四个层次:
存储引擎在数据库系统中扮演着至关重要的角色,可以将其比喻为数据库的“发动机”。就像不同类型的机械设备(如舰载机、直升机、火箭)需要配备适合其特性和需求的引擎一样,MySQL数据库也需要选择合适的存储引擎来优化数据的存储、访问和管理。
存储引擎是数据库系统中负责数据存储、索引构建、数据更新和查询等核心操作的具体实现技术。它是基于表级别的,也就是说,每个表都可以选择使用不同的存储引擎,而不是在整个数据库级别统一决定。
在MySQL中,我们在创建表的时候可以选择指定使用的存储引擎,如果没有明确指定,系统会使用默认的存储引擎。不同的存储引擎有其独特的特性,适用于不同的应用场景。例如,有些存储引擎擅长处理读密集型的工作负载,提供快速的查询性能;而有些引擎则专注于事务处理和数据一致性,适合在需要频繁更新和多用户并发访问的环境中使用。
CREATE TABLE 表名(
字段1 字段1类型 [ COMMENT 字段1注释 ] ,
......
字段n 字段n类型 [COMMENT 字段n注释 ]
) ENGINE = INNODB [ COMMENT 表注释 ] ;
show engines;
示例:
show creat table 表名
当初在创建表account的时候是没有指定存储引擎的,但MySQL会默认指定InnoDB为存储引擎
show engines;
show variables like 'innodb_file_per_table';
如果该参数开启,代表对于InnoDB引擎的表,每一张表都对应一个ibd文件。 我们直接打开MySQL的数据存放目录: C:\ProgramData\MySQL\MySQL Server 8.0\Data , 这个目录下有很多文件夹,不同的文件夹代表不同的数据库
(如果没有找到,你可能需要关掉隐藏文件夹的设置)
一个表就代表一个 .ibd文件
ibd文件中不仅存放表结构、数据,还会存放该表对应的索引信息。 而该文件是基于二进制存储的,不能直接基于记事本打开,我们可以使用mysql提供的一个指令 ibd2sdi ,通过该指令就可以从ibd文件中提取sdi信息,而sdi数据字典信息中就包含该表的表结构。
ibdata1
),所有表的数据和索引都会存储在这个表空间内。innodb_file_per_table
选项,这样每个InnoDB表的数据和索引将存储在各自的表空间文件中,文件名通常是.ibd
格式。这个逻辑存储结构的设计使得InnoDB能够有效地管理数据和索引,提供高速的查询性能和良好的数据一致性。同时,通过合理的空间分配和管理,InnoDB还能有效利用磁盘空间并减少碎片。
用一个简单的例子解释就像一个图书馆:
假设我们有一个大型的图书馆,这个图书馆的管理可以类比为InnoDB的存储引擎。
在这个例子中,当你查找一本书时,图书馆管理员会首先查看目录(相当于主键索引),找到书所在的书架和位置(相当于数据页)。如果书架上有多个同类别的书籍(相当于二级索引),管理员还会进一步查找具体的书籍。
MyISAM 是 MySQL 中的一个早期的存储引擎,虽然现在已经被 InnoDB 引擎广泛取代,但在某些特定场景下,由于其一些特性,仍然可能被选择使用。
MyISAM 是 MySQL 最初的默认存储引擎之一,它以其简单和快速的数据读取性能而闻名。尽管在许多现代应用中,由于其功能限制,MyISAM 已不再作为首选引擎,但在一些读取密集型且对事务处理要求不高的场景中,MyISAM 可能仍具有一定的优势。
不支持事务:这意味着在 MyISAM 中,无法实现原子性、一致性、隔离性和持久性(ACID)的事务操作。如果在执行一系列操作过程中发生错误或中断,无法通过回滚恢复到事务开始前的状态。
不支持外键:MyISAM 不支持外键约束,这限制了在表间建立参照完整性的能力。在需要确保数据一致性和引用关系的情况下,可能需要在应用程序层面进行额外的检查和控制。
支持表锁:在 MyISAM 中,当一个查询正在执行时,会对整个表进行锁定,阻止其他并发的写入操作。这种锁定机制在读取密集和写入较少的环境中可以提供良好的性能,但在高并发写入的场景下可能会导致性能瓶颈和锁竞争问题。
访问速度快:由于其简单的设计和优化,MyISAM 在读取操作上通常比 InnoDB 等支持复杂特性的引擎更快。尤其是在只读或者大部分是读取操作的应用中,MyISAM 的性能表现往往更优。
MyISAM 将每个表的数据和索引存储在三个不同的物理文件中:
xxx.frm:这个文件存储了表的结构信息,包括列名、数据类型、索引等元数据。
xxx.MYD:这个文件用于存储实际的数据内容,即表中的行记录。
xxx.MYI:这个文件包含了表的索引信息,用于加速数据的查找和排序操作。
这样的设计允许数据和索引分别存储和管理,有助于在特定情况下优化磁盘I/O和提高查询性能。然而,这也意味着在进行备份或者复制时,需要同时处理这三个文件以确保数据的一致性。此外,由于不支持事务和崩溃恢复机制,MyISAM 表在遇到系统崩溃或其他意外情况时可能存在数据丢失的风险。
Memory(也称为 HEAP)是 MySQL 中的一个存储引擎,其主要特点是将表的数据存储在内存中。由于数据完全驻留在内存中,Memory 引擎提供了非常快的数据访问速度,特别适合用于临时数据的存储、高速缓存或者需要频繁读写但对持久性要求不高的场景。
然而,由于 Memory 表的数据仅存在于内存中,它存在一些限制和风险。硬件问题、系统崩溃或断电等情况可能导致内存中的数据丢失。因此,Memory 表通常不用于存储需要长期保留或对数据完整性要求严格的重要数据。相反,它们更适合用作中间结果的暂存区、高速计算的临时表,或者用于缓存经常查询但变化不频繁的数据。
内存存放:Memory 表的数据和索引都存储在服务器的内存中,这使得对数据的访问速度极快,因为内存的访问速度远超过磁盘。
hash 索引(默认):Memory 表默认使用哈希索引(hash index),这是一种基于哈希函数的索引结构。哈希索引对于等值查询(如 WHERE column = value
)的性能非常优秀,因为可以直接通过哈希函数快速定位到数据。但是,哈希索引不支持范围查询(如 WHERE column BETWEEN value1 AND value2
)和排序操作。
在 Memory 存储引擎中,表的结构信息存储在一个名为 xxx.frm 的文件中,这个文件与其它存储引擎(如 InnoDB 和 MyISAM)中的 frm 文件作用相同,用于保存表的结构定义,包括列名、数据类型、索引等元数据。
需要注意的是,由于 Memory 表的数据存储在内存中,当 MySQL 服务器关闭时,这些数据会丢失。如果希望在服务器重启后恢复 Memory 表的内容,可以启用 Memory 表的持久化选项(例如,使用 MEMORY-storage-engine
参数的 persistent
选项)。这将在磁盘上创建一个文件来存储 Memory 表的数据,但是请注意,这种持久化机制并不提供事务安全性和崩溃恢复功能,只能作为数据的部分备份。在实际应用中,应根据具体需求权衡 Memory 表的使用和可能的风险。
特点 | InnoDB | MyISAM | Memory |
存储限制 | 64TB | 有 | 有 |
事务安全 | 支持 | - | - |
锁机制 | 行锁 | 表锁 | 表锁 |
B+tree索引 | 支持 | 支持 | 支持 |
Hash索引 | - | - | 支持 |
全文索引 | 支持(5.6版本之后) | 支持 | - |
空间使用 | 高 | 低 | N/A |
内存使用 | 高 | 低 | 中等 |
批量插入速度 | 低 | 高 | 高 |
支持外键 | 支持 | - | - |
在选择数据库的存储引擎时,应根据你的应用系统的特性和需求来做出合适的选择。
对于复杂的应用系统,可以根据不同表的功能和使用情况灵活选择和组合多种存储引擎,以优化系统性能和满足各种特定需求。例如,可以使用InnoDB处理需要事务和并发控制的核心数据,同时使用MyISAM存储读取密集型的静态数据,以及使用MEMORY作为临时数据或缓存区域。这样的组合可以最大化地发挥各存储引擎的优点,提高整个应用系统的效率和稳定性。