MySQL 字符集:
MySQL 支持很多种字符集的方式,比如 GB2312、GBK、BIG5、多种 Unicode 字符集(UTF-8 编码、UTF-16 编码、UCS-2 编码、UTF-32 编码等等)。
查看支持的字符集
你可以通过 SHOW CHARSET
命令来查看,支持 like 和 where 子句。
字符集的层次级别
MySQL 中的字符集有以下的层次级别:
server
(MySQL 实例级别)database
(库级别)table
(表级别)column
(字段级别)
它们的优先级可以简单的认为是从上往下依次增大,也即 column
的优先级会大于 table
等其余层次的。如指定 MySQL 实例级别字符集是utf8mb4
,指定某个表字符集是latin1
,那么这个表的所有字段如果不指定的话,编码就是latin1
。
server
不同版本的 MySQL 其 server
级别的字符集默认值不同,在 MySQL5.7 中,其默认值是 latin1
;在 MySQL8.0 中,其默认值是 utf8mb4
。
当然也可以通过在启动 mysqld
时指定 --character-set-server
来设置 server
级别的字符集。
mysqld
mysqld --character-set-server=utf8mb4
mysqld --character-set-server=utf8mb4 \
--collation-server=utf8mb4_0900_ai_ci
JDBC 对连接字符集的影响:
不知道你们有没有碰到过存储 emoji 表情正常,但是使用类似 Navicat 之类的软件的进行查询的时候,发现 emoji 表情变成了问号的情况。这个问题很有可能就是 JDBC 驱动引起的。
根据前面的内容,我们知道连接字符集也是会影响我们存储的数据的,而 JDBC 驱动会影响连接字符集。
mysql-connector-java
(JDBC 驱动)主要通过这几个属性影响连接字符集:
characterEncoding
characterSetResults
以 DataGrip 2023.1.2
来说,在它配置数据源的高级对话框中,可以看到 characterSetResults
的默认值是 utf8
,在使用 mysql-connector-java 8.0.25
时,连接字符集最后会被设置成 utf8mb3
。那么这种情况下 emoji 表情就会被显示为问号,并且当前版本驱动还不支持把 characterSetResults
设置为 utf8mb4
,不过换成 mysql-connector-java driver 8.0.29
却是允许的。
具体可以看一下 StackOverflow 的 DataGrip MySQL stores emojis correctly but displays them as?这个回答
通常情况下,我们建议使用 UTF-8 作为默认的字符编码方式。
不过,这里有一个小坑。
MySQL 字符编码集中有两套 UTF-8 编码实现:
utf8
:utf8
编码只支持1-3
个字节 。 在utf8
编码中,中文是占 3 个字节,其他数字、英文、符号占一个字节。但 emoji 符号占 4 个字节,一些较复杂的文字、繁体字也是 4 个字节。utf8mb4
:UTF-8 的完整实现,正版!最多支持使用 4 个字节表示字符,因此,可以用来存储 emoji 符号。
为什么有两套 UTF-8 编码实现呢? 原因如下:
因此,如果你需要存储emoji
类型的数据或者一些比较复杂的文字、繁体字到 MySQL 数据库的话,数据库的编码一定要指定为utf8mb4
而不是utf8
,要不然存储的时候就会报错了。