mysql数据存在哪里的?(小林coding学习笔记)
每创建一个库,都在val/lab/mysql/{database},这个目录下面有三个文件
- to_order.opt 存放字符校验规则
- to_order.frm 表的结构
- to_order.ldb 表中的数据
表空间文件的结构是怎么样的?
库->段->区->页->行
-
行
存放mysql表中每一行的数据
-
页
页是 InnoDB 存储引擎磁盘管理的最小单元,一页有16kb,页里面的结构:讲多个行数据分组,还有页目录,相当于各组的索引,页目录里面的槽点,记录的是每组的最后一个行数据的偏移量,相当于指针,如何
- 区
如果innodb每次加载数据都是以页加载的话,因为业务上连续的页的存储空间的物理位置不是连续的,那么就会产生很多随机i/o,随机i/o的性能比顺序i/o慢多了,解决办法很简单,将链表中相邻的页的物理位置也相邻,分配空间的时候按区来分配,连续的64页分为一个区,一个区1mb。
- 段
索引段:b+树非叶子节点
数据段:b+树叶子结点
回滚段:回归数据区的集合
InnoDB 行格式有哪些?
redundant:古老的行格式,已经废弃
Compact:让一行更紧凑
Dynamic和 Compressed :跟compact差不多
Compact组成
变长字段varchar()
[逆序的字段个数] [逆序的null值表示(0表示没有null,1表示是null)] [记录的头信息]
[row id ,rtx_id,roll_ptr] [字段名] [字段真实值]
比如第2行:4 2 |00000001(这里要补8位) name phome age | bb 1234
为什么「变长字段长度列表」的信息要按照逆序存放?
因为这把从左边读和从右边读取出来的字段是对应上的,利用了计算机CPU cache(高数缓存器),使得命中的效率更高
现代CPU Cache通常使用Cache Line(缓存行)作为最小的数据读取单位。Cache Line的大小通常为64字节(具体大小可能因处理器而异)。当CPU需要读取一个数据项时,不仅会将该数据项本身加载到Cache中,而且会将与该数据项相邻的一部分数据(Cache Line)一并加载进来。这就是所谓的空间局部性原理。
在上述情况下,逆序存放「变长字段长度列表」可以使得在读取变长字段的数据时,位置靠前的记录的真实数据和数据对应的字段长度信息可以同时在一个Cache Line中。这样,当需要访问某个字段的数据时,该字段长度信息也会被加载到Cache中,即使该字段长度信息不在当前Cache Line中,也有很大的概率它的前一个Cache Line中存在。这种方式利用了空间局部性原理,提高了CPU Cache的命中率,从而加快了对变长字段数据的读取速度。
每个数据库表的行格式都有「变长字段字节数列表」
不是的,比如int类型,就没有必要
2. NULL 值列表
二进制位1为NULL,0为非NULL,8位存储
「NULL 值列表」是固定 1 字节空间吗?如果这样的话,一条记录有 9 个字段值都是 NULL,这时候怎么表示?
「NULL 值列表」的空间不是固定 1 字节的。
当一条记录有 9 个字段值都是 NULL,那么就会创建 2 字节空间的「NULL 值列表」,以此类推。
3. 记录头信息
记录头信息中包含的内容很多,我就不一一列举了,这里说几个比较重要的:
- delete_mask :标识此条数据是否被删除。从这里可以知道,我们执行 detele 删除记录的时候,并不会真正的删除记录,只是将这个记录的 delete_mask 标记为 1。
- next_record:下一条记录的位置。从这里可以知道,记录与记录之间是通过链表组织的。在前面我也提到了,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。
- record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
记录的真实数据
row_id行索引,当没有主键的时候就是用他做主键,有就为空
rtx_id事务id
roll_ptr指向下一个数据行的指针
varchar(n) 中 n 最大取值为多少?
除去text,blob这种大数据的对象,一行最大字节数是65535,那么var(65535)行不行?我们可以看见他失败了,因为一行最大的字节数是要包括[变长字段长度列表」和 「NULL 值列表],在字段长度>255字节,可变字段长度为2,<=255为1,然后NULL列表占着1位,所以varchar(65532)可以的
行溢出后,MySQL 是怎么处理的?
行益出后,mysql会将数据转移到益出页
compact数据页会存放一部分数据,然后还有个益出页的指针
dynamic和compressed测试数据页只存放溢出页的指针