局部性原理:取一个数据的同时,计算机认为你马上会去取相邻的数据,所以为了节约磁盘Io,计算机会一次取出一页数据,这里有个 “页” 的概念,这样其实去数据的同时会把相邻的数据也取出来放到内存中去,如果下一次取得数据符合这个理论,那好,这样就不需要从磁盘中取了。
操作系统有个 页的单位,大约4kb大小。
所以,mysql 也同样,InnoDb利用局部性原理,有页的概念。那么InnoDb默认的页的大小是16kb
SHOW GLOBAL STATUS LIKE 'Innodb_page_size';
InnoDB 页
数据库不光数据会用页的单位存储,索引,日志,也会使用页来存储。
UserRecords,用户记录
FreeSpace 空闲空间
PageDirectory
InnoDb 行格式
- 一行记录可以 以不同的格式存在InnoDB中,行格式分别是Compact,Redundant,Dynamic,和Compressed行格式,我们可以在创建或修改表中指定行格式
- Create table 表 (列) ROW_FORMAT=行格式名称
- Alter table 表 ROW_FORMAT=行格式名称
- 变长字段长度列表:行内如果有varchar字段等长度可变字段,会在一行的头部记录下所有的可变字段的长度信息,按照字段的顺序记录对应起来。
- Null标志(站一个字节):如果字段不是not null 的话 ,按照下面的例子,一行记录4个字段,第一条都有值,第二条中间两个字段没有值这样数据容易错乱,
例子:如果
1111
23
用一个标志位来占用空间,(假如标志位是&),
1111
2&&3
可是这样我们,本来没有值,却加了一个数值来代替,有点浪费空间,不可取
所以使用NULL标志位,来记录字段的控制,想象null标志位存储一个key:value,key对应字段, value对应当前字段是否存数据,0代表没有,1代表有数据。所以null标志位里面存储的是每个字段是否有值,和是否为空null。因为字段是有顺序的,所以key可以没有,只存value
比如第一条数据1111 ,第二条数据1001, 一个数组记录null的标志位 。
当然如果所有字段都是标志 not null,那么null标志位就可以去掉。
同样如果字段都是不可变长度的 那么变长字段长度列表也可以去掉。
变长字段长度列表+ Null标志位,在每行中占用3个字节,下面提到。
行益出数据
- 每行数据的大小限制,加起来不能超过65535个字节,但是除开BLOBs ,这个字段不统计,
- 也就是说所有字段加起来,空间大小不能超过65535个字节,
- 例如:
- create table varchar_size_demo(
- c VARCHAR(65535)
- ) CHARSET=ascii ROW_FORMAT=Compact
- 这个sql报错
- The maximum row size for the used table type, not counting BLOBs, is 65535.
- This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs,
- 就是说,一行数据 除了BLOBs字段以外的所有字段,大小不能超过65535个字节,但是没有超过也报错了,因为一行数据,还有变长字段长度列表+ Null标志位,占用了3个字节
- create table varchar_size_demo(
- c VARCHAR(65532)
- ) CHARSET=ascii ROW_FORMAT=Compact
- 修改成这样就不会报错了,
- 那么Null标志位占用了多少个字节?
- create table varchar_size_demo(
- c VARCHAR(65533) NOT NULL
- ) CHARSET=ascii ROW_FORMAT=Compact
- 如果写NOT NULL 就没有了Null标志位,在加一个字节,也能执行成功,
- 所以 Null标志位占用1个字节,那么变长字段长度列表就占用2个字节。
总结:定义字段大小的时候,不知道多少合适,就可以根据这个参照,来定义字段的大小。
开始就讲到,我们一页可以存16384个字节,
那么我一行最多能存65535个字节那么:
可能出现这样的情况,一页都容不下一行的数据这个就是行益处。
那么我就把一行数据拆分成多个,过个页来存储,,第一页的那行记录里
有部分数据+下一页地址
这个就是Compact行格式的做法
还有别方法Dynamic和Compressed行格式
根Compact行格式类似,只不过在行益处数据有分歧。
Compressed行格式会采用压缩算法对页面压缩。
这种是在第一页只存每行记录的下一页的地址,不存用户数据,下一页在存用户数据,如果不够存,在根据刚才方法。
这样第一页只存一个地址,很小,就可以存很多条数据了,索引使用。
这一篇是理解索引的基础