MySQL是怎样运行的(四)

第4章 从一条记录说起——InnoDB记录存储结构

4.1 准备工作

MySQL服务器上负责对表中数据的读取和写入工作的部分是存储引擎,而服务器又支持不同类型的存储引擎,真实数据在不同的存储引擎中存放的格式一般是不同的

4.2 InnoDB页简介

InnoDB是将表中的数据存储到磁盘上的存储引擎。将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为16KB。也就是在一般情况下,一次最少从磁盘中读取16KB内容到内存中,一次最少把内存中的16KB内容刷新到磁盘

4.3 InnoDB行格式

平时以记录为单位来向表中插入数据,这些记录在磁盘上的存放方式也被称为行格式。有四种不同的行格式,分别为Compact、Redundant、Dynamic和Compressed

4.3.1 指定行格式的语法

创建或修改语句中指定行格式

 4.3.2 COMPACT行格式

 一条完整的记录可以被分为记录的额外信息记录的真实数据两大部分

记录的额外信息

这部分信息是服务器为了描述这条记录而不得不额外添加的一些信息,这些额外信息分为3类,分别是变长字段长度列表NULL值列表记录头信息

变长字段长度列表

MySQL支持一些变长的数据类型,如varchar(M)、varbinary(M)、各种text类型、各种blob类型,我们可以把拥有这些数据类型的列称为变长字段变长字段中存储多少字节的数据是不固定的,所以在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来,所以这些变长字段占用的存储空间分为两部分:

  • 真正的数据内容
  • 占用的字节数

在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的自己数按照列的顺序逆序存放

W、M和L

  1. 假设某个字符集中表示一个字符最多需要使用的字节数为W,也就是使用show charset语句的结果中的Maxlen列,如utf8的字符集中的W就是3,gbk字符集中的W就是2,ASCII字符集中的W是1
  2. 对于变长类型varchar(M)来说,这种类型表示能存储最多M个字符(注意是字符不是字节),所以这个类型能表示的字符串最多占用的字节数就是M*W
  3. 假设它实际存储的字符串占用的字节数是L

所以确定使用1个字节还是两个字节表示真正字符串占用的字节数的规则

  • 如果M*W <= 255,那么使用1个字节来表示真正字符串占用的字节数
  • 如果M*W > 255,分为两种情况

        如果L <= 127,则用1个字节来表示真正字符串占用的字节数
        如果L > 127,则用2个字节来表示真正字符串占用的字节数

    InnoDB在读记录的变长字段长度列表时先查看表结构,如果某个变长字段允许存储的最大字节数大于255时,该怎么区分它正在读的某个字节是一个单独的字段长度还是半个字段长度呢?使用该字节的第一个二进制位作为标志位:如果该字节的第一个位为0,那该字节就是一个单独的字段长度(使用一个字节表示不大于127的二进制的第一个位都为0),如果该字节的第一个位为1,那该字节就是半个字段长度。对于一些占用字节数非常多的字段,比方说某个字段长度大于了16KB,那么如果该记录在单个页面中无法存储时, InnoDB会把一部分数据存放到所谓的溢出页中(我们后边会唠),在变长字段长度列表处只存储留在本页面中的长度,所以使用两个字节也可以存放下来

也就是说,如果该可变字段允许存储的最大字节数(M*W)超过255字节,并且真是存储的字节数(L)超过127字节,则使用2个字节,否则使用1个字节

另外,变长字段长度列表中只存储非NULL的列内容占用的长度,值为NULL的列的长度是不储存的

NULL值列表

因为某些列可能存储NULL值,如果把这些NULL值都存放到记录的真实数据中存储会很占地方,所以Compact行格式把这些值为NULL的列统一管理起来,存储到NULL值列表中

  • 首先统计表中允许存储NULL的列表
  • 如果表中没有允许存储NULL的列,则NULL值列表也不存在了,否则将每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列。二进制位值为1时,代表该列的值为NULL;二进制位值为0时,代表该列的值不为NULL
  • MySQL规定NULL值列表必须使用整数个字节的位表示,二进制位个数不是整数个字节,在字节高位补0
  • 如果一个表中有9个允许为NULL,那这个记录的NULL值列表部分就需要2个字节表示了

记录头信息(略)

由固定的5个字节组成,也就是40个二进制位,不同位代表不同意义

 记录的真实数据

记录真实数据除了自己定义的列的数据以外,还会为每个记录默认添加一些列(也称为隐藏列

这里需要提一下InonoDB表对主键的生成策:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个Unque键作为主键,如果表中连 Unique键都没有定义的话,则 InnoDB会为表默认添加一个名为row_id的隐藏列作为主键。所以我们从上表中可以看出InnoDB存储引擎会为每条记录都添加 transactiohd和roll_pointer这两个列,但是row_id是可选的(在没有自定义主键以及 Unique键的情况下才会添加该列)。这些隐列的值不用我们操心, InnoDB存储引会自己帮我们生成的。

char(M)列的存储格式

因为我们的 demo表采用的是ASCII宇符集,这个宇符集是一个定长字符集,也就是说表示一个字符采用固定的一个字节,如果采用变长的字符集(也就是表示一个字需要的字节数不确定,比如gbk表示一个宇符要1~2个字节、utf8表示一个字符要1~3个字节等)的话,列的长度也会被存到变长字段长度列表中

变长字符集的char(M)类型的列要求至少占用M个字节

4.3.3 REDUNDANT行格式

MySQL5.0之前使用的一种行格式

字段长度偏移列表

Redundant行格式的开头是字段长度偏移列表,把该条记录中所有列(包括隐藏列)的长度信息都按照逆序存储到字段长度偏移列;偏移,采用 两个相邻数值的差值来计算各个列值的长度

记录头信息

 Redundant行格式中NULL值处理

Redundant行格式没有NULL值列表

char(M)列的存储格式

不管该列使用什么字符集,占用的真实数据空间就是该字符集表示一个字符最多需要的字节数和M的乘积

4.3.4 溢出列

varchar(M)最多能存储的数据

varchar(M)类型列最多可以占用65535个字节,其中M表示最多存储的字符数量

MySQL对一条记录占用的最大存储空间是有限制的,除了blob或text类型之外,其他所有列(不包括隐藏列和记录头信息)占用的字节长度加起来不超过65535个字节,如存储一个varchar类型列,其实需要占用3部分存储空间:

  • 真实数据
  • 真实数据占用字节长度
  • NULL值标识,如果该列有NOT NULL属性可以没有这部分存储空间

在列值允许为NULL情况下,gbk字符集下的M最大取值就是32766(65532/2),utf8字符集下M最大取值是21844(65532/3)个字符,这仅是在表只有varchar(M)这一个字段情况下的。一行所有列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节

记录中的数据太多产生的溢出

MySQL中磁盘和内存交互的基本单位是,也就是说MySQL是以页为基本单位来管理存储空间的,我们的记录都会被分配到某个页中存储。而一个页的大小一般是16KB,也就是16384(16*1024)字节,而一个varchar类型最多可以存储65532个字节,就可能造成一个页放不下一条记录的情况

Compact和Redundant行格式来说,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分数据,把剩下的数据分散存储在几个其他的页中,然后记录的真实数据处用20个字节存储指向这些页的地址(这20个字节还包括这些分散在其他页面中的数据的占用的字节数),从而找到剩余的数据所在的页

可看出,如果某一列中的数据非常多,在本记录的真实数据处只会存储该列的前768个字节的数据和一个指向其他页的地址,然后把剩下的数据存放在其他页,这个过程也叫做行溢出,存储超出768字节的那些页面也被称为溢出页

不只是varchar类型列,其他的text、blob类型的列在存储数据非常多的时候也会发生行溢出

行溢出的临界点

 MySQL规定一个页中至少存放两行记录

  • 每页除了存放我们的记录外,也需要存储一些额外的信息,加起来需要132个字符空间,其他空间都可以被用来存储记录
  • 每个记录需要额外信息是27字节

    2个字节用于存储 真实数据的长度
    1个字节用于存储列是否是NULL值
    5个字节大小的头信息
    6个字节的row_id列
    6个字节的transaction_id列
    7个字节的roll_pointer列

132+2*(27+n)< 16384 即 n<8099。也就是说如果一个列中存储的数据小于8099个字节,那么该列就不会成为溢出列。不过这个8099个字符结论只针对只有一个列的表,所以:不需要关注这个临界点是什么,只要知道如果一条记录的某个列存储的数据占用的字节数非常多时,就可能成为溢出列

4.3.5 DYNAMIC行格式和COMPRESSED行格式

和Compact相似,只是在处理行溢出数据时有不同,它们不会在记录的真实数据处储存真实数据的前768个字节,而是把所有的字节都存储到其他页面中,只记录其他页面的地址

Compressed行格式和Dynamic不同一点就是,Compressed行格式会采用压缩算法对页面进行压缩,以节省空间

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL是一个开源的关系型数据库管理系统。它使用SQL语言作为与用户进行交互的基础语言。MySQL运行过程可以简单分为个步骤:连接、语句处理、结果处理和断开连接。 首先,当用户连接MySQL时,客户端会发送连接请求给MySQL服务器,以建立连接。MySQL在收到请求后,会根据用户名和密码进行验证并建立连接。 其次,当连接建立后,用户可以发送SQL语句给MySQL服务器。MySQL会解析SQL语句,并在执行前进行一系列的检查,例如是否存在语法错误和安全性检查等。当SQL语句验证通过后,MySQL会执行相应的操作,例如插入、更新或查询数据等。在执行操作时,MySQL会根据数据存储引擎的不同,选择使用不同的方式来处理数据请求。 第三,当MySQL执行完SQL语句后,会将结果返回给用户。如果执行的SQL语句是一个查询命令,MySQL会将查询结果集返回给用户。返回的结果可能是一个整数值、一个文本字符串或一组数据记录等。 最后,在用户完成操作后,他可以选择断开与MySQL服务器的连接。MySQL会释放资源并清理内存,以便下一次请求时使用。 综上所述,MySQL运行过程是一个相对复杂的过程,它依赖于多个因素,如数据存储引擎、SQL语句的复杂度、连接的负载平衡和网络带宽等。理解MySQL运行过程能帮助我们更好地优化数据库的性能,提高系统的稳定性和可用性。 ### 回答2: MySQL是一种开源的关系型数据库管理系统。它是用来存储和管理数据的软件,可以支持很多不同的应用程序。MySQL运行过程可以分为三个部分:连接处理、查询处理和结果返回。 在连接处理阶段,应用程序将与MySQL建立连接。MySQL运行在服务器上,应用程序通过网络访问MySQL服务器。连接处理包括三个步骤:身份验证、设置连接信息和处理用户权限。 一旦连接建立,应用程序可以发送SQL查询语句给MySQL,并接收查询结果。在查询处理阶段,MySQL首先对查询进行语法分析和语义检查,然后将其转换为执行计划。执行计划定义了执行查询所需的操作。MySQL就会根据执行计划执行查询,并从数据表中检索所需的数据。 在结果返回阶段,MySQL将查询结果返回给应用程序。如果查询结果比较大,MySQL可以将其分成多个数据块,每块包含一部分查询结果。应用程序可以逐步接收这些数据块直到接收到完整的查询结果。一旦结果返回,应用程序可以根据需要处理查询结果。 总之,MySQL是一个高效的数据库管理系统,它可以通过网络与应用程序通信,并在服务器上存储和管理数据。MySQL运行过程包括连接处理、查询处理和结果返回三个阶段,它可以为应用程序提供可靠的数据存储和查询服务。 ### 回答3: MySQL是一种关系型数据库管理系统,它使用SQL语言作为管理和查询数据的工具。MySQL运行方式是客户端/服务器模型,客户端向服务器发送请求,服务器接收到请求后进行处理并返回结果。 在MySQL服务器中,有多个组件用于处理不同的任务。其中最重要的组件是MySQL服务进程,它负责处理所有与客户端的通信。服务进程接收到客户端请求后,会将请求传递给查询处理器进行处理。 查询处理器是MySQL的核心组件,它负责解析SQL语句并执行查询操作。查询处理器首先将SQL语句分解为语法单元,然后将其转换为内部表示形式。查询处理器会根据查询计划生成查询执行计划,该计划指定了如何从数据库中检索所需的数据。 MySQL还有其他一些组件,如存储引擎和缓存管理器。存储引擎是用于管理数据的组件,它们负责将数据存储在磁盘上,以及处理数据的读取和写入。缓存管理器负责管理查询缓存,以确保查询结果能够被快速检索和重用。 总的来说,MySQL运行是基于客户端/服务器模型,通过解析SQL语句、生成查询执行计划和处理数据等组件来实现。MySQL的稳定性和可靠性得到了广泛认可,它被广泛应用于众多网站和应用程序中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值