Innodb的数据存储结构

所有数据存储结构

从小到大排列
行->页->区->段->表空间

行格式

Innodb支持的所有行格式

目前,InnoDB支持4中行记录格式,分别是 Compact、Redundant、Dynamic和Compressed 行格式。Innodb默认的行格式为**Dynamic**

Dynamic行格式

image.png

变长字段长度列表

  1. 对于VARCHAR、TEXT、BLOB等**可变长读存储类型**,需要记录**真实数据中的长度**,从而在获取真实数据时,根据长度获取对应的数据。
  2. 变长字段长度列表中只存储真实**数据不为NULL的长度**,如果值为**NULL的数据****不会存储**在变长字段长度列表中,如果所有的字段都不是变长字段,则变长字段长度列表中没有数据
  3. 变长字段列表的存储顺序是真实数据的**倒序**
  4. 每个字段的长度由1-2个字节存储,Varchar的最大长度为65536即 2的16次方,因此需要两个字节进行长度的存储,2^8 * 2^8 = 2^16
  5. 因为Innodb一页的大小为16kb即16000字节,又因为**一个页****最少存储两个数据字段**,因此会出现一页中放不下一个数据字段的情况。这种情况下会将数据放入溢出页中,当前页的长度记录仅记录存储在本页的长度

NULL值列表

  1. 每个字段由**一个bit**位进行记录,由二进制位代表是否为NULL,可以很大程度上**节省空间**,0为非NULL值,1为NULL值,且顺序为真实数据的**逆序存放**
  2. 如果真实数据中都规定了数据不为NULL,则可以不存在NULL值列表

记录头信息

image.png

真实数据列

  1. 每行的真实数据列中,除了实际存在的数据,还存在 **事务id列**(最后操作该数据行的事务Id),和**回滚指针**(前一个版本的**UndoLog**记录)。
  2. 真实数据列中只存储**非NULL**的数据。
  3. 除了TEXT、BLOB等大对象类型,一个数据行中包含的信息 (除去**两个隐藏列和记录头信息**)长度不能超过**65535**字节。即**可变长参数列表****NULL值列表****存储的数据**总和不能超过**65535**字节。
  4. 在字符集为**Latin1**的情况下,每个字符占**1字节**,因此**Varchar**类型可以存储的长度则为**65535**-**可变长度列表**(2)- **NULL值列表**(1 如果没有)
  5. 在字符集为**utf8mb4**的情况下,每个字符占**4字节**,因此**Varchar**类型可以存储的长度为(65535 - 2 - 1)/4

  1. **Innodb**中的页大小为**16kb**
  2. 页的节点可以分为两种,**叶子节点**包含**数据列****非叶子节点**,仅包含**主键****索引信息**
  3. 查询的过程中,会先通过索引列数据进行判断,找到**查找数据所在的页**,将**页加载到缓冲池**中,然后先根据**二分查找**找到大致的槽位,再根据单向链表遍历查找到对应的记录。
  4. 因为查询的过程中都需要将**页从硬盘中加载到缓冲池**中,**唯一索引**在读取到一条数据后就可以**停止**搜索,**普通索引**在读取到数据后**仍会继续往下**读取,但因为数据页都已读取到内存中,所以查询的效率没有很大的差异。

**一个区包含64个页**,即1MB

  1. 页与页之间是采用双向链表连接在一起,在查询的过程中,通常需要在**页与页之间**进行**遍历查询**
  2. 如果此时页与页之间的**距离比较远**,则为**随机IO**,随机的IO的速率很慢,因此如果在页与页之间进行查询使用随机IO的话会很影响效率。因此**需要尽可能让页与页之间相邻**,这样在页之间进行**范围查询**时,才能使用**顺序IO**优化查询效率。
  3. 因此在表的数据量较大的时候给索引分配空间时,不会以为单位进行分配,会以**区**进行分配,如果表的数据量很大,可以分配多个区,虽然有一定的空间损耗,但是能让查询的时候有随机IO 优化为顺序IO

  1. 在进行范围查询时,通常是节点之间进行通过双向链表进行**遍历查询**,而**叶子节点**在遍历时**只会经历叶子节点****非叶子节点**在遍历时也**只会经历非叶子节点**
  2. 因此根据这个特性,在建立索引 B+树时,需要**将叶子节点的页与非叶子节点的页分开**,从而叶子和非叶子节点都有自己的区,而存放区的地方叫做**段**,存放**非叶子节点**的段叫做**索引段**,存放**叶子节点**的段叫做**数据段**
  3. 段时以区为单位进行单位的分配,在建立索引时,默认就会有两个段,即**索引段****数据段**
  4. 一个段内包括很多区和碎片区

碎片区

  1. 节约空间,碎片区不属于某个段,而只属于表空间
  2. 刚开始插入表数据的时候段会以某个碎片区的单个页面来分配空间
  3. 当碎片区达到32个时,则会申请完整的区空间

表空间

  1. 独立表空间
  2. 系统表空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值