《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)变长字段列表

image

在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,已经够了

因此这行的存储格式就是这样的

image

然后讨论一下长度的表示问题

  • 有没有发现,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()

posted on   yq1DB  阅读(6)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示