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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 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 ,当记录中的数据太多,当前页放不下的时候,会把多余的数据存储到其他页中,这种现象称为 行溢出 。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
8月前
|
存储 关系型数据库 MySQL
Linux 安装 mysql 及配置存储位置
Linux 安装 mysql 及配置存储位置
207 3
|
7月前
|
存储 关系型数据库 MySQL
MySQL——数据库备份上传到阿里云OSS存储
MySQL——数据库备份上传到阿里云OSS存储
276 0
|
11天前
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(09)数据磁盘存储模型 | 一行数据怎么存?
文中详细介绍了MySQL数据库中一行数据在磁盘上的存储机制,包括表空间、段、区、页和行的具体结构,以及如何设计和优化行数据存储以提高性能。
|
23天前
|
存储 缓存 关系型数据库
MySQL原理简介—5.存储模型和数据读写机制
本文介绍了MySQL中InnoDB存储引擎的物理存储结构和读写机制。主要内容包括: 1. 为什么不能直接更新磁盘上的数据 2. 数据页的概念 3. 一行数据的存储 4. 数据头的内容 5. 行溢出和溢出页 6. 数据页的物理结构 7. 表空间的物理结构 8. InnoDB存储模型及读写机制总结 这些机制共同确保了InnoDB在高并发场景下的高效运行和数据一致性。
|
10天前
|
存储 SQL 关系型数据库
【YashanDB 知识库】MySQL 迁移至崖山 char 类型数据自动补空格问题
问题分类】功能使用 【关键字】char,char(1) 【问题描述】MySQL 迁移至崖山环境,字段类型源端和目标端都为 char(2),但应用存储的数据为'0'、'1',此时崖山查询该表字段时会自动补充空格 【问题原因分析】mysql 有 sql_mode 控制,检查是否启用了 PAD_CHAR_TO_FULL_LENGTH SQL 模式。如果启用了这个模式,MySQL 才会保留 CHAR 类型字段的尾随空格,默认没有启动。 #查看sql_mode mysql> SHOW VARIABLES LIKE 'sql_mode'; 【解决/规避方法】与应用确认存储的数据,正确定义数据
|
7月前
|
存储 关系型数据库 MySQL
mysql 使用变量存储中间结果的写法
mysql 使用变量存储中间结果的写法
|
5月前
|
存储 关系型数据库 MySQL
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
PACS系统 中 dicom 文件在mysql 8.0 数据库中的 存储和读取(pydicom 库使用)
106 2
|
5月前
|
存储 SQL 关系型数据库
MySQL 存储函数及调用
MySQL 存储函数及调用
317 3
|
5月前
|
存储 关系型数据库 MySQL
MySQL 如何存储地理信息
MySQL 如何存储地理信息
456 1
|
6月前
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
684 1