在InnoDB中,数据存储在磁盘上,处理数据时需要先将数据从磁盘读取,再写到内存。InnoDB采用局部性原理加载。
一、局部性原理 从磁盘读取数据时,不需要一行一行读取,而是以页为单位读取,操作系统中一页4kb,InnoDB中一页16kb。 二、InnoDB页结构 页是InnoDB管理存储空间的基本单位,一个页的大小默认是16KB。三、InnoDB行格式
我们可以在创建或修改表的语句中指定行格式:
CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称 ALTER TABLE 表名 ROW_FORMAT=行格式名称1、Compact行格式:
(1)变长字段长度列表
MySQL支持一些变长的数据类型,比如VARCHAR(M)、VARBINARY(M)、TEXT类型,BLOB类型,这些数据类型修饰列称为变长字段。变长字段长度列表即所有变长字段的真实数据占用的字节长度构成的列表。
VARCHAR(M),M代表最大能存多少个字符。
(2)NULL标志位(列表) Compact行格式会把可以值为NULL的列统一管理起来,存一个二进制标记(1为NULL,0不为NULL)在NULL标志位中,如果表中没有允许存储 NULL 的列,则 NULL值列表也不存在了。如:第一行没有null:11111
第二行前三位null:22 (null标志位:11100)
(3)记录头信息
记录头信息用于描述记录,它是由固定的5个字节组成。 5个字节也就是40个二进制位,不同的位代表不同的意思,如图:
(4)记录的真实数据
记录的真实数据除了我们自己定义的列的数据以外,还会有三个隐藏列:
2.行溢出数据
VARCHAR(M)类型的列最多可以占用65535个字节。 如果我们使用 ascii字符集的话,一个字符就代表一个字节。但是VARCHAR(65535)会报错:
原因:存储一个VARCHAR(M)类型的列,其实需要占用3部分存储空间: 1. 真实数据 2. 变长字段真实数据的长度 3. NULL值标识
因此,如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为变长字段的长度占用 2个字节,NULL值标识需要占用1个字节。
3.行过长导致的页溢出
一个页的大小一般是16KB,也就是16384字节,而一个VARCHAR(M)类型的列就最多可以存储65533个字节,这 样就可能出现一个页存放不了一条记录。
(1)在Compact和Reduntant行格式中,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分 数据,把剩余的数据分散存储在几个其他的页中,然后记录的真实数据处用20个字节存储指向这些页的「地址和字节数」,从而可以找到剩余数据所在的页。
...
(2)在Dynamic和Compressed行格式中,它们不会在记录的真实数据处 存储一部分数据,而是把所有的数据都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。
...
4.Dynamic和Compressed行格式
这两种行格式类似于COMPACT行格式,只不过在处理行溢出数据时有点区别,如上。另外, Compressed行格式会采用压缩算法对页面进行压缩。