4.3.3.1 【MySQL】CHAR(M)列的存储格式

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 4.3.3.1 【MySQL】CHAR(M)列的存储格式

我们知道 Compact 行格式在 CHAR(M) 类型的列中存储数据的时候还挺麻烦,分变长字符集和定长字符集的情况,而在 Redundant 行格式中十分干脆,不管该列使用的字符集是啥,只要是使用 CHAR(M) 类型,占用的真实数据空间就是该字符集表示一个字符最多需要的字节数和 M 的乘积。比方说使用 utf8 字符集的 CHAR(10) 类型的列占用的真实数据空间始终为 30 个字节,使用 gbk 字符集的 CHAR(10) 类型的列占用的真实数据空间始终为 20 个字节。由此可以看出来,使用 Redundant 行格式的 CHAR(M) 类型的列是不会产生碎片的。

4.3.4 行溢出数据

4.3.4.1 VARCHAR(M)最多能存储的数据

我们知道对于 VARCHAR(M) 类型的列最多可以占用 65535 个字节。其中的 M 代表该类型最多存储的字符数量,如果我们使用 ascii 字符集的话,一个字符就代表一个字节,我们看看 VARCHAR(65535) 是否可用:

从报错信息里可以看出, MySQL 对一条记录占用的最大存储空间是有限制的,除了 BLOB 或者 TEXT 类型的列之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过 65535 个字节。所以 MySQL 服务器建议我们把存储类型改为 TEXT 或者 BLOB 的类型。这个 65535 个字节除了列本身的数据之外,还包括一些其他的数据( storage overhead ),比如说我们为了存储一个 VARCHAR(M) 类型的列,其实需要占用3部分存储空间:


真实数据

真实数据占用字节的长度

如果 VARCHAR 类型的列有 NOT NULL 属性,那最多只能存储 65533 个字节的数据,因为真实数据的长度可能占用2个字节,不需要 NULL 值标识:

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

我们以 ascii 字符集下的 varchar_size_demo 表为例,插入一条记录:


其中的 REPEAT('a', 65532) 是一个函数调用,它表示生成一个把字符 'a' 重复 65532 次的字符串。前边说过, MySQL 中磁盘和内存交互的基本单位是 页 ,也就是说 MySQL 是以 页 为基本单位来管理存储空间的,我们的记录都会被分配到某个 页 中存储。而一个页的大小一般是 16KB ,也就是 16384 字节,而一个 VARCHAR(M) 类型的列就最多可以存储 65532 个字节,这样就可能造成一个页存放不了一条记录的尴尬情况。


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

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


4.4 总结


1. 页是 MySQL 中磁盘和内存交互的基本单位,也是 MySQL 是管理存储空间的基本单位。

2. 指定和修改行格式的语法如下:

CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名称
ALTER TABLE 表名 ROW_FORMAT=行格式名称

3. InnoDB 目前定义了4种行格式

COMPACT行格式

具体组成如图:

Redundant行格式

具体组成如图:



Dynamic和Compressed行格式


这两种行格式类似于 COMPACT行格式 ,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处存储字符串的前768个字节,而是把所有的字节都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。


另外, Compressed 行格式会采用压缩算法对页面进行压缩。


4. 一个页一般是 16KB ,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为 行溢出 。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
存储 关系型数据库 MySQL
Linux 安装 mysql 及配置存储位置
Linux 安装 mysql 及配置存储位置
103 3
|
2月前
|
存储 关系型数据库 MySQL
MySQL——数据库备份上传到阿里云OSS存储
MySQL——数据库备份上传到阿里云OSS存储
93 0
|
2月前
|
存储 关系型数据库 MySQL
mysql 使用变量存储中间结果的写法
mysql 使用变量存储中间结果的写法
|
7天前
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
15 1
|
2月前
|
存储 SQL 关系型数据库
mysql百分数转小数点格式
在MySQL中,将百分数转换为小数点格式是一个简单直接的操作,可以通过基本的数学表达式和函数实现。无论是处理以字符串形式存储的百分数值,还是直接以数值形式表示的百分比,都可以通过适当的转换查询轻松实现这一目标。通过理解和应用这些基本的转换方法,可以有效地处理和分析数据库中的百分比数据。
31 5
|
3月前
|
关系型数据库 MySQL 存储
|
2月前
|
存储 小程序 关系型数据库
原生小程序 获取手机号并进行存储到mysql数据库
原生小程序 获取手机号并进行存储到mysql数据库
|
2月前
|
存储 关系型数据库 MySQL
在 MySQL 中使用 CHAR
【8月更文挑战第11天】
36 0
|
3月前
|
关系型数据库 MySQL 数据库
实时计算 Flink版产品使用问题之如何排除某个列进行同步MySQL数据
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
4月前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之 MySQL数据库中,执行delete命令删除数据后,存储空间通常不会立即释放,该如何优化
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
下一篇
无影云桌面