mysql之一条sql语句是如何存储的

  1. 查看mysql数据存储在磁盘的哪一个文件
mysql> show variables like 'datadir';
+---------------+---------------------------------------------+
| Variable_name | Value                                       |
+---------------+---------------------------------------------+
| datadir       | C:\ProgramData\MySQL\MySQL Server 5.5\Data\ |
+---------------+---------------------------------------------+
1 row in set (0.03 sec)

每创建一个数据库,就会在该目录下创建一个与数据库名字同名的文件夹
在这里插入图片描述
在这里插入图片描述
db.opt,用来存储当前数据库的默认字符集和字符校验规则。
t_order.frm ,t_order 的表结构会保存在这个文件。在 MySQL 中建立一张表都会生成一个.frm 文件,该文件是用来保存每个表的元数据信息的,主要包含表结构定义。
t_order.ibd,t_order 的表数据会保存在这个文件。表数据既可以存在共享表空间文件(文件名:ibdata1)里,也可以存放在独占表空间文件(文件名:表名字.ibd)。这个行为是由参数 innodb_file_per_table 控制的,若设置了参数 innodb_file_per_table 为 1,则会将存储的数据、索引等信息单独存储在一个独占表空间,从 MySQL 5.6.6 版本开始,它的默认值就是 1 了,因此从这个版本之后, MySQL 中每一张表的数据都存放在一个独立的 .ibd 文件。
好了,现在我们知道了一张数据库表的数据是保存在「 表名字.ibd 」的文件里的,这个文件也称为独占表空间文件。

  1. 为什么分区
    让逻辑上相邻很近的元素在物理上也相邻很近
      利用索引查找数据,存取数据不是很好吗,为什么还要分区呢?想想一个场景,加入一个表非常的大,但各个页的数据却不是一次性存入数据库(本质上是磁盘,写入一页的索引数据后,还会有别的页,别的程序的数据写入磁盘)中的,各个逻辑上相邻的数据页在物理上可能相聚非常的远(相邻的页是别的索引(表)的数据),当批量取数据时,定位到以一条数据,此时因为数据页比较分散,产生过多的随机I/0,影响读取效率.
      所以引入分区的概念,索引不再是以页为基本单位分配空间,而是以区为了进一步提高扫描的效率,将一个索引内的叶子结点和非叶子节点放入不同的区中(查找目录也时块,扫描数据页时更加"纯粹",页更快).
      同一索引内存放叶子节点的区的集合形成一个段,存放非叶子节点的集合也形成一个段.段是以区为基本单位申请空间.这样做还存在一个问题,如果一个表只有几条记录,难道也要为他申请两个段吗,两个段至少有两个区,至少2MB,太流量空间了.于是引入了碎片区的概念.碎片区不属于任何一个段,直属于表空间
     &emsp段是若干区的集合,是零散页面以及完整区(??)的集合.索引内某一类型数据的集合

在这里插入图片描述
3. mysql(INODB)有哪些行格式
InnoDB 提供了 4 种行格式,分别是 Redundant、Compact、Dynamic和 Compressed 行格式。

Redundant 是很古老的行格式了, MySQL 5.0 版本之前用的行格式,现在基本没人用了。
由于 Redundant 不是一种紧凑的行格式,所以 MySQL 5.0 之后引入了 Compact 行记录存储方式,Compact 是一种紧凑的行格式,设计的初衷就是为了让一个数据页中可以存放更多的行记录,从 MySQL 5.1 版本之后,行格式默认设置成 Compact。
Dynamic 和 Compressed 两个都是紧凑的行格式,它们的行格式都和 Compact 差不多,因为都是基于 Compact 改进一点东西。从 MySQL5.7 版本之后,默认使用 Dynamic 行格式
4. ?为什么变长字段列表要逆序存放
5. 一定需要变长字段列表吗
如果表没有变长字段,就不需要
6. 空值列表
对所有的没有非空限定的字段,用0代表该字段非空,1为空,按照字段在表中顺序的逆序排列,不够一字节时高位补0填充.
7. 变长字段列表每个字段所占用的字节数如何确定
上文提到变长字段列表存储变长字段实际占据的字节数,1字节可以表达0-255的长度,超过255怎么办呢,直接占据两个字节?Innodb有一套规则。为了说清楚这套规则,首先定义三个符号:
M:记录所在字符集表示一个字符所需最大字节数,例如utf8对应的M为3,即三个字节一定能够表示该字符集里的所有单个字符。
W:变长类型所能存储的最大字符数,例如varchar(15),W=15
L:变长类型字段实际占用的字节数,例如varchar(15)字段存储‘qbc’,则L=3
MW:变长字段所占的最大字节数
当进行数据存储的时候,首先计算M
W的值,当该值小于等于255,则代表该处的属于,无论怎么存,其长度都不会超过255,所以使用一字节存储其长度即可。当MW>255,代表未来该处存储的字节长度有可能超过255,此时看L的值,如果L<=127,代表当前用一个字节也能存的下,使用一字节存储,当L>127,使用2字节存储。这种机制考虑的比较全面,不仅考虑了当下,还考虑了未来(MW)。当L>127时,最高位为1,小于127时,最高位为0.
当读取记录的时候,首先查看该表结构,获取M 和W 值。计算M*W,如果<=255,读取长度列表的一个字节查看其长度,否则,查看第一个字节的最高位是否为1,为1的话读取两个长度,为0读取1个长度。
我们知道,一页的容量为16kb,极端条件下,该页面全部用来存储一条记录的一个字段,它所占的字节为2^16个,用两字节来表示它所占字节完全足够。
一个变长字段的长度使用两个字节完全能够存储下
8. varchar(n)的n值最大是多少
n代表的是字符数,字符所占的字节和编码规则有关.Mysql规定,一行最多占65535个字节
(1)单字段
如果是ascii编码:
变长字段列表 2字节
控制列表 1字节
最大65532
在 UTF-8 字符集下,一个字符串最多需要三个字节,varchar(n) 的 n 最大取值就是 65532/3 = 21844。
上面所说的只是针对于一个字段的计算方式。

  1. 当发生溢出时,会发生什么?
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈师亦友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值