《MySQL是怎么运行的》读书笔记(持续更新中)
第3章 字符集和比较规则
3.1 字符集和比较规则简介
这一节小孩子告诉我们字符集的作用
就是将字符映射成二进制数据而已,比如我自己可以创立一个字符集,规定 'a' = 00000001
在传输数据的过程中,只会传输000000001,对方收到后,使用相同的字符集解析之后就知道是‘a’了,如果接收方使用了00000001=‘A’的字符集,就发生了乱码了
然后说到一些重要的字符集
比如说ACSII:
‘L’ = 01001100
'M' = 01001101
一直只收录了128个字符而已,包括英文、数字和一些符号
可以看到ACSII使用【1个字节】来进行编码
然后提到【变长编码】的概念
比如说 GB2312字符集,收录了汉字同时又兼容ACSII字符集,它的规则是这样的:如果该字符在ACSII字符集中,就用1字节编码,否则就用2个字节编码
比如 “爱u”,爱使用2字节编码,u使用1字节,爱是0xB0AE,u是0x75,所以“爱u”就是0xB0AE75
所以这个字符串就是:1011000010101110 - 01110101
3.2 MySQL中支持的字符集和比较规则
UTF-8这个字符集也是具有【变长编码】的一个字符集,使用1~4字节来表示一个字符
但是设计MySQL大叔认为,大大大大部份的字符使用1~3字节就可以了,所以定义了两个字符集:
· utf8mb3:“阉割“过的UTF-8字符集,使用1~3个字节表示字符
· utf8mb4:正宗的UTF-8字符集,使用1~4个字节表示字符
在MySQL中显示utf8,其实就是utf8mb3
然后说一下mysql的排序规则,比如说 utf8_general_ci,是一种通用的比较规则
ci的意思是 case insensitive ,那case sensitive 就是 cs了
3.3 字符集和比较规则的应用
告诉了我们系统里有几种级别的字符集和比较规则
1.服务器级别
2.数据库级别
3.表级别
4.列级别
第4章 从一条记录说起——InnoDB记录存储结构
4.1 准备工作
MySQL是MySQL ,存储引擎是存储引擎
存储引擎的作用是什么?
答:同样的数据,在不同存储引擎的【存放格式】是不一样的
4.2 innodb页简介
记住一个重要概念:innodb将数据划分为若干个页
以页作为磁盘与内存之间交互的基本单位,一般是16KB的单位
就像oracle使用块作为基本单位一样
4.3 InnoDB行格式
我们的rdbms都是基于元组的原理,以行为单位向表插入数据的
行格式
:行格式就是一条记录怎么才磁盘上存放的格式
现在InnoDB引擎的行格式有4种:
- COMPACT 致密
- REDUNDANT 冗余
- DYNAMIC 动态
- COMPRESSED 压缩
4.3.1 指定行格式的语法
我们可以手动指定行格式:
CREATE TABLE 表名(列) ROW_FORMAT=行格式; ALTER TABLE 表名 ROW_FORMAT=行格式;
建立测试数据:
mysql> use xiaohaizi; mysql> create table record_format_demo(c1 varchar(10), c2 varchar(10) NOT NULL, c3 char(10), c4 varchar(10) -> ) charset=ascii ROW_FORMAT=COMPACT; INSERT INTO record_format_demo VALUES('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL);commit;
现在表的数据
mysql> select * from record_format_demo; +------+-----+------+------+ | c1 | c2 | c3 | c4 | +------+-----+------+------+ | aaaa | bbb | cc | d | | eeee | fff | NULL | NULL | +------+-----+------+------+
4.3.2 COMPACT 格式
4.3.2.1 记录的额外信息
首先我们要意识到,一行里面的数据,肯定有两部分:
1)真实数据 2)描述真实数据的数据
也就是我们的数据
与 元数据
的区别
(1)变长字段列表
在mysql里有一些变长的数据类型,比如varchar(M),varbinary(M), TEXT,BLOB
为什么要把这些字段的字节数存起来?因为要知道它们的长度,不至于把mysql搞蒙
变长字段长度列表的存放规则:
各字段的字节数,按列的顺序逆序存放
mysql的varchar是字符数!!
oracle的varchar2是字节数!!
mysql> select * from record_format_demo; +------+-----+------+------+ | c1 | c2 | c3 | c4 | +------+-----+------+------+ | aaaa | bbb | cc | d | | eeee | fff | NULL | NULL | +------+-----+------+------+
大家看看看看这两条数据,c1 c2 c4 是变长字段
列名 | 存储内容 | 内容长度(十进制显示) | 内容长度(十六进制) |
---|---|---|---|
c1 varchar(10) | 'aaaa' | 4 | 0x04 |
c2 varchar(10) | 'bbb' | 3 | 0x03 |
c4 varchar(10) | 'd' | 1 | 0x01 |
长度分别是 4 ,3,1 ,没错吧?
用十六进制表示就是 0x04 0x03 0x01
但是逆序存放之后就变成了 01 03 04
为什么是 0x04 不是 0x0004
两位的16进制可以变身多少?16x16-1=255=FF,最多可以表示255,已经够了
因此这行的存储格式就是这样的
然后讨论一下长度的表示问题
- 有没有发现,c1、c2、c3 这三个列都比较短,也就是4字节、3字节、1字节
- 也就是说用4、3、1就可以表示了(十六进制就是 0x04 0x03 0x01 )
- 而 0x04 0x03 0x01 都是一字节的;也就是用1字节就能表示4、3、1这三个数字
但是一字节最多可以表示0xFF,也就是255
- 如果这列是VARCHAR(256)呢?FF就表示不了了
- 只能用2字节表示,比如256 = 0x0100
那怎么确定这个列是用一字节还是两字节来表示呢?
InnoDB有它自己的规则,首先引入W,M,L这3个符号
- W:代表
字符集
中,一个字符最多需要多少个字符表示,也就是show charset;
(参看下面的补充)中的maxlen
列;比如ascii用1个字节就可以表示一个字符了,比如用utf8mb4可以用4个字节表示一些emoji - M:就是我们变长字段类型最大可以存储多少个字符,VARCHAR(M);比如varchar(255)的M就是255
- 因此一个字段最多占用的【字节数】就是W×M
- 比如这个字符集是utf8mb4,字段是varchar(20),表示最多最多也就是20×4=80个字节
- L:表示该变长字段实际存储的【字节数】
- 比如上面的
ascii
字符集的aaaa
,有4个字符,每个字符用1个字节就能表示,所以这个字符串就是4个字节,L=4; - 比如有一个
utf8mb4
存了xxx
(x只是举例子代表一个很大的字符,需要用4个字节表示),有3个字符,每个字符需要用4个字节来表示,所以这个字符串的L=3×4=12个字节
- 比如上面的
补充show charset
mysql> show charset; +----------+---------------------------------+---------------------+--------+ | Charset | Description | Default collation | Maxlen | +----------+---------------------------------+---------------------+-------- | ascii | US ASCII | ascii_general_ci | 1 | | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 | +----------+---------------------------------+---------------------+--------+
所以该InnoDB规则是这样的
1)如果M×W <= 255,那么使用1字节真实数据占用的字节数
- 这个很容易理解,比如
utf8mb4
,虽然一个字符最多需要4个字节来表示,但是varchar(1),你最大也就是存4个字节,用0x04就可以表示了- 如果是varchar()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?