mysql字符集与排序规则

MySQL的字符集包括字符集(charset)和排序规则(collation)两个概念,其中字符集定义了存储字符串的方式,排序规则定义了比较字符串的方式

[TOC]

字符集

  • MySQL 5.7 默认字符集为 Latin1,它不支持中文,若要支持中文需将数据库的字符集修改为gbk或者utf8
  • MySQL 5.7 及以前,默认字符集为 latin1、默认排序规则为 latin1_swedish_ci,utf8 默认指向的是 utf8mb3
  • MySQL 8.0 及以后,默认字符集为 utf8mb4、默认排序规则为 utf8mb4_general_ci,utf8 默认指向的是 utf8mb4
  • MySQL 对于字符集的支持细化到四个层次:
实例(server)
数据库(database)
数据表(table)及字段(column)
连接(connection)

排序规则

  • 排序规则:是指对指定字符集下不同字符的比较规则,它有以下特征:
它和字符集(CHARSET)相关
每种字符集都有多种它支持的排序规则
每种字符集都会默认指定一种排序规则为默认值。
  • 排序规则的影响范围:凡是涉及到字符类型比较或排序的地方,都和排序规则有关,具体如下
影响 ORDER BY 语句查询的结果顺序
影响 WHERE条件中大于小于号的筛选结果
影响 DISTINCT、GROUP BY、HAVING 语句的查询结果
如果索引列是字符类型,还会影响索引的创建
  • 排序规则的设置可以分为:MySQL实例级别、库级别、表级别、字段级别、SQL指定
  • 排序规则的优先级顺序是:SQL指定 > 字段级别设置 > 表级别设置 > 库级别设置 > 实例级别设置。也就是说,如果SQL语句中指定了排序规则,则以其指定为准,否则以字段级别设置为准,如果字段级别没有指定,则继承表级别的设置,以此类推。

如何确认

  • 查看当前mysql支持的字符集和排序规则: show charset;
  • 查看实例字符集: show variables like 'character_set_server';
  • 查看实例排序规则: show variables like 'collation_server';
  • 查看指定库的字符集: show create database 库名;
  • 查看当前库的字符集: use 库名; show variables like 'character_set_database';
  • 查看当前库的排序规则: use 库名; show variables like 'collation_database';
  • 查看的字符集: show create table 表名;
  • 查看字段字符集: show full columns from 表名;
  • 查看连接字符集: show variables like 'character_set_connection';
  • 查看连接的排序规则: show variables like 'collation_connection';

如何修改

  • 修改实例的字符集和排序规则:先修改 /etc/my.cnf重启mysql服务以生效,示例为 utf8mb4
[client]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

[mysql]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4
  • 修改的字符集,示例为 utf8mb4: alter database 库名 character set utf8mb4;
  • 修改的字符集,示例为 utf8mb4: ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 修改的字符集,示例为 utf8mb4: ALTER TABLE 表名 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  • 修改字段的排序规则,示例为 xxx: alter table 表名 modify column '字段名' varchar(30) character set utf8mb4_unicode_ci not null;
  • SQL语句指定排序规则,示例为 utf8_bin:select * from tb03 where name='user' collate utf8_bin;
  • 修改连接的字符集,执行 SET NAMES xxx; 相当于同时设置3个客户端的字符集,示例为 latin1
mysql> SET NAMES 'latin1';
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |  #.生效的地方
| character_set_connection | latin1                     |  #.生效的地方
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |  #.生效的地方
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
+--------------------------+----------------------------+

批量修改

  • 批量修改某个db下所有表的字符集,示例为 utf8mb4
select 
   table_schema,table_name,table_rows,table_collation
  ,concat('alter table ','`',table_schema,'`.`',table_name,'`',' convert to character set utf8mb4 collate utf8mb4_unicode_ci;') as command
from information_schema.tables 
where table_schema = 'testdb' and table_collation <> 'utf8mb4_unicode_ci' order by table_name;

#.脚本执行效果如下
+--------------+------------+------------+-----------------+------------------------------------------------------------------------------------------+
| table_schema | table_name | table_rows | table_collation | command                                                                                  |
+--------------+------------+------------+-----------------+------------------------------------------------------------------------------------------+
| testdb       | Tb01       |          0 | utf8mb4_bin     | alter table `testdb`.`Tb01` convert to character set utf8mb4 collate utf8mb4_unicode_ci; |
+--------------+------------+------------+-----------------+------------------------------------------------------------------------------------------+

如何避免乱码

  • 登录 mysql 先执行 use xxx; 切换到指定库,再执行 show variables like 'character%';
mysql> use 库名;
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |  #.客户端使用的字符集
| character_set_connection | utf8                       |  #.连接数据库时的字符集
| character_set_database   | utf8                       |  #.当前库的字符集,或默认创建数据库的编码格式
| character_set_filesystem | binary                     |  #.文件系统的编码格式,不会影响乱码
| character_set_results    | utf8                       |  #.mysql给客户端返回时使用的编码格式
| character_set_server     | utf8                       |  #.mysql安装时指定的默认编码格式
| character_set_system     | utf8mb4                    |  #.数据库系统使用的编码格式,优先级最低,不会影响乱码
+--------------------------+----------------------------+
  • 客户端的设置:character_set_client、character_set_connection、character_set_results
  • 服务端的设置:character_set_system、character_set_server、character_set_database
  • 服务器端的参数优先级:charactersetdatabase > charactersetserver > charactersetsystem
  • 以上参数必须保证除了 character_set_filesystem 外的参数都统一,才不会出现乱码的情况
  • 但由于 character_set_system 优先级最低,因此影响不大。修改了客户端字符集、character_set_database、character_set_server 基本上就不会出现乱码了

其他涉及字符集的地方

  • mysql登录的时候,指定 --default-character-set=latin1 可对客户端指定字符集
[root@localhost ~]# mysql -uroot -p -h 127.0.0.1 --default-character-set=latin1 -e"show variables like 'character%';"
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |  #.生效的地方
| character_set_connection | latin1                     |  #.生效的地方
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |  #.生效的地方
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
+--------------------------+----------------------------+
  • mysqldump备份的时候,指定 --default-character-set=utf8mb4 可按照设定的字符集来备份数据
mysqldump --single-transaction --master-data=2 --default-character-set=utf8mb4 --databases 库名 > data.2023.sql
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2023-12-04 16:45:08

results matching ""

    No results matching ""