修改MySQL5.7字符集

修改步骤

在MySQL 8.0版本之前,默认字符集为 latin1 ,utf8字符集指向的是 utf8mb3 。网站开发人员在数据库 设计的时候往往会将编码修改为utf8字符集。如果遗忘修改默认的编码,就会出现乱码的问题。从MySQL 8.0开始,数据库的默认编码将改为 utf8mb4 ,从而避免上述乱码的问题。

操作1:查看默认使用的字符集

  1. show variables like 'character%';
  2. # 或者
  3. show variables like '%char%';
  • MySQL8.0中执行:

1642732559(1).png

  • MySQL5.7中执行

1642732478(1).png
MySQL 5.7 默认的客户端和服务器都用了 latin1 ,不支持中文,保存中文会报错。MySQL5.7截图如下:
1642733090(1).png
因为默认情况下,创建表使用的是 latin1 。如下:
1642733141(1).png
操作2:修改字符集

vim /etc/my.cnf

在MySQL5.7或之前的版本中,在文件最后加上中文字符集配置:

character_set_server=utf8

1642733327(1).png
操作3:重新启动MySQL服务

systemctl restart mysqld

注意: 但是原库、原表的设定不会发生变化,参数修改只对新建的数据库生效。

已有库&表字符集的变更

MySQL5.7版本中,以前创建的库,创建的表字符集还是latin1。
1642733486(1).png
修改已创建数据库的字符集

alter database dbtest1 character set 'utf8';

修改已创建数据表的字符集

alter table emp1 convert to character set 'utf8';

1642733775(1).png
1642733807(1).png
注意:但是原有的数据如果是用非’utf8’编码的话,数据本身编码不会发生改变。已有数据需要导 出或删除,然后重新插入。

各级别的字符集

MySQL有4个级别的字符集和比较规则,
分别是:
1,服务器级别
2,数据库级别
3,表级别
4,列级别

执行如下SQL语句: (8.0版本中查看)

show variables like 'character%';

1642733970(1).png

  • character_set_server:服务器级别的字符集
  • character_set_database:当前数据库的字符集
  • character_set_client:服务器解码请求时使用的字符集
  • character_set_connection:服务器处理请求时会把请求字符串从character_set_client转为 character_set_connection
  • character_set_results:服务器向客户端返回数据时使用的字符集

1. 服务器级别

character_set_server: 服务器级别的字符集。 我们可以在启动服务器程序时通过启动选项或者在服务器程序运行过程中使用 SET 语句修改这两个变量 的值。比如我们可以在配置文件中这样写:

[server]
character_set_server=gbk                     # 默认字符集
collation_server=gbk_chinese_ci     #对应的默认的比较规则

当服务器启动的时候读取这个配置文件后这两个系统变量的值便修改了。

2. 数据库级别

character_set_database:当前数据库的字符集 我们在创建和修改数据库的时候可以指定该数据库的字符集和比较规则,具体语法如下:

CREATE DATABASE 数据库名
        [[DEFAULT] CHARACTER SET 字符集名称]
        [[DEFAULT] COLLATE 比较规则名称];

ALTER DATABASE 数据库名
        [[DEFAULT] CHARACTER SET 字符集名称]
        [[DEFAULT] COLLATE 比较规则名称];

3. 表级别

我们也可以在创建和修改表的时候指定表的字符集和比较规则,语法如下:

REATE TABLE 表名 (列的信息)
        [[DEFAULT] CHARACTER SET 字符集名称]
        [COLLATE 比较规则名称]]

ALTER TABLE 表名
        [[DEFAULT] CHARACTER SET 字符集名称]
        [COLLATE 比较规则名称]

如果创建和修改表的语句中没有指明字符集和比较规则,将使用该表所在数据库的字符集和比较规则作 为该表的字符集和比较规则。

4. 列级别

对于存储字符串的列,同一个表中的不同的列也可以有不同的字符集和比较规则。我们在创建和修改列 定义的时候可以指定该列的字符集和比较规则,语法如下:

CREATE TABLE 表名(
            列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],
            其他列...
);

ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];

对于某个列来说,如果在创建和修改的语句中没有指明字符集和比较规则,将使用该列所在表的字符集 和比较规则作为该列的字符集和比较规则

提示

在转换列的字符集时需要注意,如果转换前列中存储的数据不能用转换后的字符集进行表示会发生 错误。比方说原先列使用的字符集是utf8,列中存储了一些汉字,现在把列的字符集转换为ascii的 话就会出错,因为ascii字符集并不能表示汉字字符。

5. 小结

我们介绍的这4个级别字符集和比较规则的联系如下:

  • 如果** 创建或修改列 **时没有显式的指定字符集和比较规则,则该列** 默认用表的 **字符集和比较规则
  • 如果 **创建表时 **没有显式的指定字符集和比较规则,则该表 默认**用数据库的** 字符集和比较规则
  • 如果 **创建数据库时 **没有显式的指定字符集和比较规则,则该数据库 **默认用服务器**的 字符集和比较规则

知道了这些规则之后,对于给定的表,我们应该知道它的各个列的字符集和比较规则是什么,从而根据这个列的类型来确定存储数据时每个列的实际数据占用的存储空间大小了。比方说我们向表 t 中插入一 条记录:

mysql> INSERT INTO t(col) VALUES('我们');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM t;
+--------+
|          s |
+--------+
|      我们 |
+--------+
1 row in set (0.00 sec)

首先列 col 使用的字符集是 gbk ,一个字符 ‘我’ 在 gbk 中的编码为 0xCED2 ,占用两个字节,两个字符的实际数据就占用4个字节。如果把该列的字符集修改为 utf8 的话,这两个字符就实际占用6个字节