mysql 编码不同 比较_MySQL字符编码与比较规则

本文详述了MySQL中的字符编码,包括阉割版UTF-8(utf8mb3)与完整UTF-8(utf8mb4),并探讨了比较规则,如区分大小写的cs和不区分大小写的ci。此外,介绍了字符编码在服务器、数据库、表和列四个级别的设置,以及MySQL通信中的字符编码转换,包括关键配置如character_set_client和collation_server等。
摘要由CSDN通过智能技术生成

这是《Java与MySQL字符集与编码》 第四篇,也是本系列的最后、最想写的一篇。这个系列最初是想了解MySQL的编码问题,在整理的过程中,想到了Java的字节编码问题,所以就产生了这个系列。

1 字符编码与比较规则

字符编码我们前面几节已经做了介绍。这儿只讲一点,MySQL中的阉割UTF-8。

1.1 MySQL中的UTF-8

正常来说,像系统、Java语言本身等各个环节UTF-8都是1~4 字节变长的。而在MySQL中基于效率和容量的考虑,对UTF-8进行了阉割,我们通俗意义上说的MySQL UTF-8是指utf8mb3 (UTF-8 most bytes 3) , 也就是说最大支持3字节。这样就导致了有些可以在其他系统支持的UTF-8字符在MySQL中就不能表示了,比如emoji表情。

为了兼容常规意义上的UTF-8,故MySQL中用utf8mb4 编码方案来支持。

我们看下某个MySQL系统支持哪些字符集:

show charset;

复制代码

b5b347fd94f4833831258ad1fc95daa2.png

比较重要的就是最大长度(Maxlen) 和 默认比较规则(Default collation)。

1.2 比较规则

比较规则,就是指比较两个字符的大小。最常用的方式就是使用二进制的比较大小。有些可能会涉及忽略大小写的比较,这就会衍生出了好多的比较规则。每一种编码方案会对应很多的比较规则。

常见的比较规则(以utf-8为例):

show collation like 'utf8%';

复制代码

4303668c144614697dbba74e861941d4.png

我们可以看到每种字符集就对应好多的比较规则,不过会有一个默认的比较规则。

其中带有ci 的后缀表示是case ignore,是指不区分大小写。 cs 表示case sensitive ,是指区分大小写。而bin 的后缀则表示是纯二进制的比较。

2 字符编码与比较规则的设置

MySQL中有4个级别的字符集和比较规则:

服务器级别

数据库级别

表级别

列级别

复制代码

2.1 服务器级别

SHOW VARIABLES LIKE 'character_set_server';

SHOW VARIABLES LIKE 'collation_server';

复制代码

2808416e6b1727f26c6378f1d68b69f8.png

65c1d9aff11422cc26b9f45ab1153c80.png

当然,我们可以在服务启动时进行设置。

[server]

character_set_server=gbk

collation_server=gbk_chinese_ci

复制代码

2.2 数据库级别

SHOW VARIABLES LIKE 'character_set_database';

SHOW VARIABLES LIKE 'collation_database';

复制代码

可以通过如上两个命令来查看。

注意:数据库级别的编码只有在创建时可以指定,创建之后就没有办法修改了。

2.3 表级别

在创建表的时候,可以指定。如果没有指定则使用数据库的编码跟比较规则。

dbc3ac717bc885b06b5518b037b763a1.png

2.4 列级别

一般不会对列进行特殊编码设定,当然如果想设定,可以通过指令修改。比如下面的例子:

ALTER TABLE 表名

[[DEFAULT] CHARACTER SET 字符集名称]

[COLLATE 比较规则名称]

复制代码

2.5 修改

关于字符编码跟比较规则的修改,遵循如下规则,简单点说二者是联动的:

只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。

只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。

3 MySQL通信中的字符编码转码

3.1 涉及的流程

在MySQL通信过程中,涉及到从客户端->服务端-> 客户端的整体流程,所以中间会涉及到编码转换的问题。如下图所示(图片来自掘金小册《MySQL 是怎样运行的:从根儿上理解 MySQL》)。

60e4da37ae5172647974686fedfe4f1f.png

如果任何一个环节出现编码、解码不一致的问题,则会出现乱码。

3.2 涉及的配置

MySQL涉及转码的配置有如下几个:

character_set_client

character_set_connection

character_set_results

复制代码

其中

character_set_client 是决定以什么编码的方式解码客户端传来的编码。

character_set_connection 是 将character_set_client 接收来的字符集转换为具体使用的编码集。

character_set_results 是指结果返回时,给到客户端的编码集。

我们看下数据库的有些相关配置:

97475e68424e96e3f53a8ffdde908d56.png

d91bb856d86eeb2b0d4ebd65c2b9c80a.png

d4d41f011ef88acebe42c24692a0f83b.png

3.3 jdbc 编码设置demo

把spring jdbc 的编码改为gbk看下:

23ed96d27fe2517ee1170bc5f3635516.png

发现报如下的错误:

9b744d9a62e98f39d0b6ff36f979b7db.png

UncategorizedSQLException 就是编码的问题了。

那我们再改回到utf-8, 发现就正常了。

4 小结

本文首先讲了MySQL字符编码、比较规则的理论知识,并查看了具体的数据配置。然后又讲了MySQL通信中的字符编码转码的问题。最后我们解答了上一篇文章中,关于jdbc 配置跟character_set_client 的交互问题。

5 参考文献

掘金小册《MySQL 是怎样运行的:从根儿上理解 MySQL》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值