在创建表时可以选择搜索引擎,如InnoDB、MyISAM、NDB等等。下面主要介绍InnoDB和MyISAM。【说明:下面的mysql的B+树结构,网上有说是另一种B+升级结构,只有微小的差异,本博客重点是理解思想,所以采用自己熟知的B+结构进行分析。勿介意!!!】
一、搜索引擎的对比
二、InnoDB
选择InnoDB的缘由:
支持ACID事务,实现事务提交和回滚;
支持外键、崩溃修复能力;
不错的并发控制;
频繁更新、删除操作;
一般创建表时就指定搜索引擎,目前默认是InnoDB。创建一个表时自动会生成.frm文件。
.frm文件:存储数据表的框架结构,文件名和表名相同,每个表对应一个同名frm文件,无论什么操作系统或存储引擎,都有这个文件。
同时添加数据时,下面几个文件会变化。
innoDB数据库文件:如ibdata1、ibdata2等系统表空间文件,存储InnoDB系统信息和用户数据库表数据和索引;
日志文件【redo log文件】:如ib_logfile1和ib_logfile0。
1、存储结构
InnoDB存储引擎表由共享表空间、日志文件组(更准确地说是Redo文件组)、表结构定义文件组成。
表空间
默认情况下InnoDB存储引擎有一个共享表空间ibdata1,即所有数据都放在这个表空间内。如果我们启用了参数innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内。
对于启用了innodb_file_per_table的参数选项,需要注意的是,每张表的表空间内存放的只是数据、索引和插入缓冲,如撤销(Undo)信息,系统事务信息,二次写缓冲等还是存放在共享表空间中。
segment段
常见的段有数据段、索引段、回滚段等,在InnoDB存储引擎中,对段的管理都是由引擎自身所完成的。
extent区
区是由连续的页组成的空间,无论页的大小怎么变,区的大小默认总是为1MB。InnoDB一次从磁盘申请4-5个区。
InnoDB页大小默认是16KB,那么一个区有1MB/16KB=64个连续的页。一个段开始,先有32页大小的碎片页来存放数据,使用完后才有64个连续页的申请。【对于小表,可以节省磁盘开销】
page页
页是InnoDB磁盘管理的最小单位,默认大小是16KB。
常见的页类型有:
数据页
Undo页
系统页
事务数据页
插入缓冲位图页
插入缓冲空闲列表页
未压缩的二进制大对象页
压缩的二进制大对象页
row行
每个页存放的行记录也是有硬性定义的,最多允许存放16KB/2-200行的记录,即7992行记录。InnoDB页大小默认是16KB。
2、索引和数据关系
InnoDB引擎采用的是B+树结构【B+见博客另外的文章】,那么聚簇索引和非聚簇索引(或辅助索引、二级索引)是怎么存储数据的?只有了解存储原理,那么才会合理写sql。
下面先是聚簇索引的图示
再是二级索引的图示
------结论:从上面可以看出,对于InnoDB的主键索引【以<id,row>方式存储】的叶子节点保存的是真正的数据。非聚簇索引【以<index,id>方式存储】的叶子节点的数据区保存的是主键索引关键字的值。所以,非聚簇索引一般需要进行二次查询【后面介绍】。
三、MyISAM
选择InnoDB的缘由:
提供高速存储和检索, 以及全文搜索能力;
表主要用于插入和读取操作;
对并发性要求不高;
一个表设置了MyISAM引擎,那么会生成三个不同后缀的文件。
.frm文件:记录表的信息,包含创建时间、表名等信息(类似书的封面、前言和介绍)
.MYD文件:表的所有数据内容(类似书的正文内容)
.MYI文件:表的所有索引(类似书的目录) 【除聚簇索引,其他索引也会在这个文件中】
1、索引和数据关系
叶子节点是 关键字值、数据行地址;
非叶子节点是 关键字值、子节点引用。
------从上面可以看出,主键索引和非聚簇索引的叶子节点中存放“数据行指针”,一旦数据发生改变,那么所有的索引都会发生变化。