MySql修炼一、字符编码

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

MySQL 字符集简介

简单地说,MySQL中的字符集就是一组符号和编码,比如我们有一个字母表,其中包含字母az 。我们分配每个字母的一个数字,例如,a = 1, b = 2等。那么a就是一个符号,数字1就是编码。从az的所有字母和相应编码组合在一起就被称为字符集。

排序规则是一组用于比较字符集中字符的规则。同样,如果我们想在两个字符串值之间进行比较,例如,ab。最简单的方法是使用它们的编码,拿上面的举例来说就是a1b2,从编码中可以看出,1<2 ,所以我们可以说a小于b。

MySQL支持很多字符集,每个字符集都至少使用一种排序规则,定义了如何来比较字符集中的字符。我们可以使用以下语句查看 MySQL 数据库服务器中可用的所有字符集:

SHOW  CHARACTER SET ;

.............
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 |
| dec8     | DEC West European           | dec8_swedish_ci     |      1 |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1 |
| utf16    | UTF-16 Unicode              | utf16_general_ci    |      4 |
| utf16le  | UTF-16LE Unicode            | utf16le_general_ci  |      4 |
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |      2 |
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |      3 |
+----------+-----------------------------+---------------------+--------+

或者使用以下语句查看排序规则。

show collation like 'utf8%';

默认的字符集

通常,MySQL中的字符集是这样工作的:

  • 创建数据库时,字符集是从服务器character_set_server变量派生。
  • 创建表时,字符集是从数据库派生。
  • 创建列时,字符集将从表中派生。

1.查看character_set_server变量

SHOW GLOBAL VARIABLES LIKE 'character_set_server%';

+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+

2.查看数据库字符集

1.create database test;

2.use test

3.select @@character_set_database, @@collation_database;

+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| utf8mb4                  | utf8mb4_general_ci   |
+--------------------------+----------------------+

第三条命令的写法同等于下面写法:

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME  FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'test'

但注意的是在Mysql8.0中,默认的字符集已经从latin1更改为utf8mb4

3.更改默认字符集。

接下来做一个测试,首先更改默认的character_set_server,然后创建数据库,并查看字符编码,但是注意的是,修改character_set_server之后貌似不能立马生效,需要断开一次连接才可以。

1.set global character_set_server = utf8;

2.create database utf8database

3.SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME  FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'utf8database';

+----------------------------+------------------------+
| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+----------------------------+------------------------+
| utf8                       | utf8_general_ci        |
+----------------------------+------------------------+

获取长度

MySQL提供了LENGTH()函数用以字节为单位返回字符串的长度,还有CHAR_LENGTH()函数用于以字符为单位查找字符串的长度。如果我们使用 LENGTH()函数来计算字符的字符串的长度,那么会得到比CHAR_LENGTH()的结果更高的结果。比如一个汉字是3个字节,一个字母是1个字节。

1select length("掘金"),char_length("掘金"),length("abc");
+------------------+-----------------------+---------------+
| length("掘金")   | char_length("掘金")   | length("abc") |
+------------------+-----------------------+---------------+
|                6 |                     2 |             3 |
+------------------+-----------------------+---------------+
1 row in set (0.000 sec)

当然我们可以通过CONVERT函数将字符串转换为特定的字符集。比如在下面例子中,它将utf8编码的字符串转换为gbk,在gbk中一个汉字2个字节,所以最终结果是4。

select length(convert("掘金" using gbk));
+-------------------------------------+
| length(convert("掘金" using gbk))   |
+-------------------------------------+
|                                   4 |
+-------------------------------------+
1 row in set (0.000 sec)

控制server端和client端交互通信的配置

一些MySql客户端不具备同时支持多种字符集的能力,每次都只能使用一种字符集,客户端和服务端之间的字符集转换工作是由下面几个系统变量来控制的。

  1. character_set_server

    MySql服务默认字符集

  2. character_set_database

    数据库默认字符集

  3. character_set_client

    MySql假定客户端是以character_set_client变量作为发送语句的字符集。

  4. character_set_connection

    服务器会将客户端发送的语句从character_set_client 转换为character_set_connection

  5. character_set_result

    服务器查询结果返回到客户端时,将转换成此字符集。这包括结果数据(例如列值)、结果元数据(例如列名称)和错误消息。如果不想进行转换,那么可以设置 character_set_results值为NULLbinary

MySql修炼一、字符编码
image.png

陷阱utf8

尽量不要使用Mysql中的UTF-8,如果使用了,那么要改成utf8mb4,因为MySQL的UTF-8与真正的UTF-8编码不同。之所以如此,是因为它没有提供完整的unicode支持,可能会导致数据丢失或安全问题,比如表情或者一些特殊符号无法显示,utf8mb4是"最安全"的字符集,因为它支持4字节的unicode,而utf8最多只支持 3 个。

另外utf8mb4_general_ci是一组简化的排序规则,就是为了提高速度,而utf8mb4_unicode_ci可以在多种语言中准确排序。

- END -


原文始发于微信公众号(十四个字节):MySql修炼一、字符编码