04 字符集

mysql中有utf8和utf8mb4两种编码,在mysql中请大家忘记utf8,永远使用utf8mb4

需要存储emoji的时候,MySQL需要设置字符集为utf8mb4,这样才能存储占四个字节的字符,默认的utf8只能存储占三个字节的字符,这是mysql的一个遗留问题。

初始化配置

容器

使用MySQL容器修改配置看这里,不带cnf文件进行自定义配置这一节。

非容器

直接修改my.cnf配置文件即可,一般在/etc/mysql或者/etc/mysql/conf.d等目录下。

修改JDBC连接串

JDBC URL 由下面这几部分组成。

protocol//[hosts][/database][?properties]

重点看[?properties]的配置,以key=value的形式,用&连接多个配置参数,且key是大小写敏感的(两个只有大小写不同的key会引起冲突)。

参数说明默认值
useUnicode是否使用Unicode字符集,这是下一个参数的前置条件false
characterEncoding当useUnicode设置为true时,指定字符编码false
autoReconnect当数据库连接异常中断时,是否自动重新连接?false
autoReconnectForPools是否使用针对数据库连接池的重连策略false
failOverReadOnly自动重连成功后,连接是否设置为只读?true
maxReconnectsautoReconnect设置为true时,重试连接的次数3
initialTimeoutautoReconnect设置为true时,两次重连之间的时间间隔,单位:秒2
connectTimeout和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时0
socketTimeoutsocket操作(读写)超时,单位:毫秒。 0表示永不超时0

修改运行中的MySQL

查看建表、建库时,默认的字符集配置,来确定是否要修改。

show create table <表名>
show create database <库名>

使用客户端连接数据库的时候,可以指定默认编码:

mysql -u root -p --default-character-set=utf8mb4

连接的时候,如果没有指定字符集,则取配置文件中的值;否则,取指定的字符集。

配置文件中的内容类似这样:

[client]
default-character-set=utf8mb4

使用不同的字符集连接数据库的时候,会影响下面 3 个变量:

character_set_client
character_set_connection
character_set_results

# 动态修改
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;

# 下面这个设置与上面三个等价
SET NAMES utf8mb4;

当这 3 个变量值与数据库的字符集不统一的时候,就有可能出错或乱码

  • character_set_client 指客户端请求内容的字符集,
  • character_set_connection 指服务器处理内容的字符集,
  • character_set_results 指服务器返回的响应的字符集。

image

  1. 服务器收到请求时,会将请求以 character_set_client 的字符集进行解码,然后以 character_set_connection 的字符集进行编码,然后丢给服务器处理。
  2. 待处理结束后,又将结果使用 character_set_connection 的字符集进行解码,然后使用 character_set_results 的字符集进行编码返回。

修改列

ALTER TABLE <表名> MODIFY <列名> varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '标题';

修改表

为了让新增的列的字符串也是 utf8mb4 的字符集,修改表的字符集。

ALTER TABLE <表名> DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

修改库

如果想让新增的表默认也是这个字符集,可以修改数据库的字符集。

ALTER DATABASE <库名> DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

理解

在进行修改的时候,CHARACTER好理解,那么COLLATE是什么意思呢?

维基百科翻译“文字排序”。如数值序或者字母序 。

COLLATE会影响到ORDER BY语句的顺序,会影响到WHERE条件中大于小于号筛选出来的结果,会影响DISTINCTGROUP BYHAVING语句的查询结果。另外,MySQL建索引的时候,如果索引列是字符类型,也会影响索引创建。凡是涉及到字符类型比较或排序的地方,都会和COLLATE有关。

COLLATE通常是和数据编码(CHARSET)相关的,一般来说每种CHARSET都有多种它所支持的COLLATE,并且每种CHARSET都指定一种COLLATE为默认值。

  • Latin1编码的默认COLLATE为latin1_swedish_ci
  • GBK编码的默认COLLATE为gbk_chinese_ci
  • utf8mb4编码的默认值COLLATE为utf8mb4_general_ci

很多COLLATE都带有_ci字样,这是Case Insensitive的缩写,即大小写无关

上次修改: 14 April 2020