mysql 字符集
前言
简单介绍一下mysql的字符集
正文
字符和二进制到底什么关系:
'a' -> 00000001 (十六进制:0x01)
'b' -> 00000010 (十六进制:0x02)
'A' -> 00000011 (十六进制:0x03)
'B' -> 00000100 (十六进制:0x04)
其实就是一个映射关系。
就是规定一些二进制映射成哪个字符。
然后就是比较规则呢?
比如 'a' 大还是 'b' 大呢?
如果根据二进制规则比较,也就是binary collation 而言,那么这个比较是比较简单的。
但是还有一些其他的规则,比如认为不区分大小写的时候,那么也就是将'A'转换成小写'a' 进行比较。
对于某一种字符集来说,比较两个字符大小的规则可以制定出很多种,也就是说同一种字符集可以有多种比较规
则
重要的字符集
这些比较重要,不然无论是开发还是啥都会比较困难。
首先是ASCII字符集:
共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所
以可以使用1个字节来进行编码,我们看一些字符的编码方式:
'L' -> 01001100(十六进制:0x4C,十进制:76)
'M' -> 01001101(十六进制:0x4D,十进制:77)
ISO 8859-1 字符集
共收录256个字符,是在 ASCII 字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以
使用1个字节来进行编码。这个字符集也有一个别名 latin1 。
GB2312 字符集
收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个,
其他文字符号682个。同时这种字符集又兼容 ASCII 字符集,所以在编码方式上显得有些奇怪:
如果该字符在 ASCII 字符集中,则采用1字节编码。
否则采用2字节编码。
这种表示一个字符需要的字节数可能不同的编码方式称为 变长编码方式 。比方说字符串 '爱u' ,其
中 '爱' 需要用2个字节进行编码,编码后的十六进制表示为 0xCED2 , 'u' 需要用1个字节进行编码,
编码后的十六进制表示为 0x75 ,所以拼合起来就是 0xCED275 。
GBK 字符集
GBK 字符集只是在收录字符范围上对 GB2312 字符集作了扩充,编码方式上兼容 GB2312 。
utf8 字符集
收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容 ASCII 字符集,采用变长编码方式,编
码一个字符需要使用1~4个字节,比方说这样:
'L' -> 01001100(十六进制:0x4C)
'啊' -> 111001011001010110001010(十六进制:0xE5958A)
我们怎么区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?别忘了ASCII
字
符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内
的,就意味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。
3.2.1 MySQL中的utf8和utf8mb4
我们上边说 utf8 字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表
示了。而在 MySQL 中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以设计
MySQL 的大叔偷偷的定义了两个概念:
utf8mb3 :阉割过的 utf8 字符集,只使用1~3个字节表示字符。
utf8mb4 :正宗的 utf8 字符集,使用1~4个字节表示字符。
有一点需要大家十分的注意,在 MySQL 中 utf8 是 utf8mb3 的别名,所以之后在 MySQL 中提到 utf8 就意味着使
用1~3个字节来表示一个字符,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请
使用 utf8mb4。
查看支持的字符:
show character set
查看比较规则:
查看utf8的比较规则:
SHOW COLLATION LIKE '%utf8%'
比如这个:utf8mb4_general_ci 表示按照一般规则
utf8mb4_german2_ci 表示按照德语规则
名称后缀意味着该比较规则是否区分语言中的重音、大小写啥的,具体可以用的值如下:
|后缀|英文释义|描述| |:--😐:--😐:--😐 | _ai | accent insensitive |不区分重音| | _as | accent sensitive |区分重
音| | _ci | case insensitive |不区分大小写| | _cs | case sensitive |区分大小写| | _bin | binary |以二进制
方式比较|
比如 utf8_general_ci 这个比较规则是以 ci 结尾的,说明不区分大小写。
每种字符集对应若干种比较规则,每种字符集都有一种默认的比较规则, SHOW COLLATION 的返回结果中的
Default 列的值为 YES 的就是该字符集的默认比较规则,比方说 utf8 字符集默认的比较规则就是
utf8_general_ci 。
mysql 又4个级别的字符集和比较规则,分别是:
- 服务器级别
- 数据库级别
- 表级别
- 列级别
服务器级别:
比如查看服务器级别的符号:
show variables like 'collation_server'
可以查看到服务器级别的比较规则
这个服务级别的这样配置:
[server]
character_set_server=gbk
collation_server=gbk_chinese_ci
当服务器启动的时候读取这个配置文件后这两个系统变量的值便修改了。
这个服务器级别的作用就是当系统创建数据库的时候,没有指定数据库的时候默认就为其中的默认字符和比较规则。
CREATE DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
ALTER DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
如果想查看当前数据库级别的:
SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'collation_database';
然后这个数据库级别的是只读的不能修改的。
当然有数据库级别,那么就有表级别,有表级别,那么就有列级别,
这些都不用去记忆,知道有就行了,用的时候去查看文档。
然后我们要知道一件事的是:
当我们修改只字符集或者只修改比较规则会发生什么呢?
-
只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。
-
只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。
也就是这两者是关联的。
然后关于服务端和客户端的交互字符集了:
大致是这样:
character_set_client 要求客户端请求的字符集
character_set_connection 会转换成服务端处理的字符集
character_set_results 要求客户端接受的字符集
这几个一般是一致的,这样避免转换问题。
其实知道这个真的没有啥子用,我们知道是怎么交互的就行了,就是一个约定。
结
大多数时候我们知道有用的就是选好我们的字符集,然后选好规则就行,知道里面是怎么回事,然后知道最小粒度是列即可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2021-02-14 jenkins 持续集成和交付——一个构件小栗子前置(三)
2021-02-14 jenkins 持续集成和交付——gogs安装(外篇)
2020-02-14 两个数之和
2020-02-14 android 动画基础绘——帧动画(三)
2020-02-14 android 动画基础绘——view 动画(二)[补]