简单明白彻底解决 MySQL 中文编码问题

1. 问题重现

mysql> create database school;

mysql> use school;

mysql> create table student(name varchar(10));

mysql> insert into student values("Clarke");

mysql> select * from student;

+--------+

| name |

+--------+

| Clarke |

+--------+

mysql> insert into student values("唐三");

# 插入中文失败

ERROR 1366 (HY000): Incorrect string value: '\xE5\x94\x90\xE4\xB8\x89' for column 'name' at row 1

2. 分析和解决

2.1 数据库编码设置

2.1.1 查看 MySQL 程序编码设置

mysql> show variables like 'char%';

+--------------------------+----------------------------+

| Variable_name | Value |

+--------------------------+----------------------------+

| character_set_client | latin1 |

| character_set_connection | latin1 |

| character_set_database | latin1 |

| character_set_filesystem | binary |

| character_set_results | latin1 |

| character_set_server | latin1 |

| character_set_system | utf8 |

| character_sets_dir | /usr/share/mysql/charsets/ |

+--------------------------+----------------------------+

可以看到,设置里有很多的编码设置是 latin1,这个编码是无法正确显示中文的,如果你的设置也是这样,这就是导致中文编码问题的可能原因。

关于这些设置的含义:

option

desc

character_set_client

客户端使用的字符编码,如果客户端连接时没有设置,或者服务端已配置为忽略客户端的设置

character_set_connection

客户端设置连接数据库时的字符编码,如果客户端没有指明,则连接数据库使用该设置的编码

character_set_database

当前选中数据库的默认字符编码,如果没有选中数据库(use ),则和 character_set_server 的值一致

character_set_filesystem

文件系统的编码格式,把操作系统上的文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不做任何转换的

character_set_results

数据库给客户端返回时使用的编码格式,如果客户端连接时没有指明,则使用该编码

character_set_server

数据库服务器默认编码格式,创建数据库时默认使用

character_set_system

数据库系统使用的编码格式,这个值一直是utf8,不需要设置,它是为存储系统元数据的编码格式

character_sets_dir

这个变量是字符集安装的目录

2.1.2 修改编码设置

编码设置中我们需要关注的是下面 5 个字符编码设置:

# 服务端相关

character_set_server

character_set_database #当前选中数据库的编码,这个设置不需要手动修改​

# 客户端相关

character_set_client

character_set_connection

character_set_results

修改编码设置的方式有三种。

方式1: session 范围修改

mysql> set character_set_server=utf8mb4

建议使用 utf8mb4 编码而不是 utf8,因为 MySQL 的 utf8 编码有点小问题,可以自行百度 MySQL 中 utf8 和 utf8mb4 的区别

这种修改方式是 session 范围的,也就是当前的 MySQL 连接结束后,设置就失效了。

其他几个编码设置也一样修改。

方式2: global 范围修改

mysql> set global character_set_server=utf8mb4

global 范围下的修改,重新连接依然有效,直到 MySQL 服务端重启。

方式3: 修改配置文件

想要编码设置在 MySQL 服务端重启后依然生效,可以修改配置文件。

不同平台的配置文件位置不一样,可以通过下面命令查看:

➜ ~ mysql --verbose --help | grep my.cnf

/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

除了~/.my.cnf文件是用户级别的外,其他几个位置都是系统级别的,如果该位置没有my.cnf文件,就新建一个文本文件,命名为 my.cnf。

windows 系统下,这个文件叫 my.ini。

在 my.cnf文件中添加以下内容:

[mysqld]

character_set_server=utf8mb4

collation_server=utf8mb4_unicode_ci

[client]

default_character-set=utf8mb4

配置项说明:

character-set-server 设置影响 character_set_server 的值,character_set_database 的值在未选中当前数据库的情况下下,默认跟随 character_set_server 的值。

default-character-set 影响 character_set_client, character_set_connection, character_set_results 三者的值。

在 MySQL 连接终端中执行 SET NAMES 也是影响的 character_set_client, character_set_connection, character_set_results 三者的值

collation_server 影响 orderby 的排序结果,建议设置 character-set-server 的同时也要设置

关于 character_set_server 和 collation_server: MySQL doc - sysvar_character_set_server

修改配置文件后重启 MySQL,再查看下编码设置,

mysql> show variables like 'char%';

+--------------------------+----------------------------+

| Variable_name | Value |

+--------------------------+----------------------------+

| character_set_client | utf8mb4 |

| character_set_connection | utf8mb4 |

| character_set_database | utf8mb4 |

| character_set_filesystem | binary |

| character_set_results | utf8mb4 |

| character_set_server | utf8mb4 |

| character_set_system | utf8 |

| character_sets_dir | /usr/share/mysql/charsets/ |

+--------------------------+----------------------------+

可以看到已经生效了,5 个相关设置已经修改为 utf8mb4。

三种修改方式,优先选择修改配置文件,其次的选择或者想要灵活设置的话,可以在终端会话中设置。

2.2 已创建的数据库的编码

如果上面的配置已经修改完成,可能仍然有中文编码问题,因为对于已经创建完成的数据库和表,它的编码在创建时已经确定了,前面的配置项(character_set_server)已经不能影响了,需要逐个修改相应的数据库,表,列。

2.2.1 具体数据库的编码

查看完整的数据库创建语句:

mysql> show create database school;

+----------+-------------------------------------------------------------------+

| Database | Create Database |

+----------+-------------------------------------------------------------------+

| school | CREATE DATABASE `school` /*!40100 DEFAULT CHARACTER SET latin1 */ |

+----------+-------------------------------------------------------------------+

可以看到数据库 school 的默认编码仍然是 latin1,改起:

mysql> alter database school character set 'utf8mb4';

mysql> show create database school;

+----------+--------------------------------------------------------------------+

| Database | Create Database |

+----------+--------------------------------------------------------------------+

| school | CREATE DATABASE `school` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |

+----------+--------------------------------------------------------------------+

2.2.2 表的编码

在前一节,数据库 school 的默认编码已经修改为 utf8mb4,接下来看数据表的默认编码:

mysql> show create table student;

+---------+---------------------------------------------------------------------------------------------------+

| Table | Create Table |

+---------+---------------------------------------------------------------------------------------------------+

| student | CREATE TABLE `student` (

`name` varchar(10) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

+---------+---------------------------------------------------------------------------------------------------+

看到数据表 student 的默认编码仍然是 latin1,再改起:

mysql> alter table student character set 'utf8mb4';

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> show create table student;

+---------+-------------------------------------------------------------------------------------------------------------------------+

| Table | Create Table |

+---------+-------------------------------------------------------------------------------------------------------------------------+

| student | CREATE TABLE `student` (

`name` varchar(10) CHARACTER SET latin1 DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |

+---------+-------------------------------------------------------------------------------------------------------------------------+

2.2.3 列的编码

在上一节可以看到,数据表 student 的默认编码已经修改为 utf8mb4,但是列 name 的编码还是 latin1,改起!

mysql> alter table `student` change `name` `name` text character set 'utf8mb4';

Query OK, 1 row affected (0.04 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> show create table student;

+---------+--------------------------------------------------------------------------------+

| Table | Create Table |

+---------+--------------------------------------------------------------------------------+

| student | CREATE TABLE `student` (

`name` text

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |

+---------+--------------------------------------------------------------------------------+

到这里,对于已经存在的数据库,修改完成,再插入中文试试:

mysql> insert into student value("昊天");

Query OK, 1 row affected (0.00 sec)

mysql> select * from student;

+--------+

| name |

+--------+

| Clarke |

| 昊天 |

+--------+

2 rows in set (0.00 sec)

成功!到此,中文编码的问题就解决了。

2.3 防御性编码

为了防止意外的情况发生,我们可以采取更健壮的防御性编码的方式,哪怕数据库服务端的编码设置不正确,我们仍然可以插入中文数据。

具体就是在创建数据表的时候指定默认编码:

mysql> show variables like 'char%';

+--------------------------+----------------------------+

| Variable_name | Value |

+--------------------------+----------------------------+

| character_set_client | latin1 |

| character_set_connection | latin1 |

| character_set_database | latin1 |

| character_set_filesystem | binary |

| character_set_results | latin1 |

| character_set_server | latin1 |

| character_set_system | utf8 |

| character_sets_dir | /usr/share/mysql/charsets/ |

+--------------------------+----------------------------+

8 rows in set (0.00 sec)

# 指定存储引擎,编码,排序规则

mysql> create table course(name varchar(32)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Query OK, 0 rows affected (0.03 sec)

mysql> insert into course value('高数');

Query OK, 1 row affected (0.01 sec)

mysql> select * from course;

+--------+

| name |

+--------+

| 高数 |

+--------+

1 row in set (0.00 sec)

或者直接在创建数据库的时候就指定编码:

mysql> create database school DEFAULT CHARACTER SET utf8mb4;

3. 总结

解决 MySQL 中文编码问题的步骤:

查看数据库编码设置

修改编码设置,在终端中修改设置项,或者修改配置文件 my.cnf 以永久生效

对于之前创建的数据库,修改数据库,数据表,数据列的默认编码

最佳实践:防御性编码,在数据库创建语句中指定默认编码。

mysql 可逆编码,简单明白彻底解决 MySQL 中文编码问题相关推荐

  1. 简单明白彻底解决 MySQL 中文编码问题

    1. 问题重现 mysql> create database school; mysql> use school; mysql> create table student(name ...

  2. mysql share 字体 中文_简单明白彻底解决 MySQL 中文编码问题

    1. 问题重现 mysql> create database school; mysql> use school; mysql> create table student(name ...

  3. mysql 5.6 登录 警告_解决mysql登录出现警告问题的简单方法

    解决mysql登录出现警告问题的简单方法 发布时间:2020-05-11 11:50:39 来源:亿速云 阅读:125 作者:三月 本文主要给大家介绍解决mysql登录出现警告问题的简单方法,文章内容 ...

  4. 修改mysql编码方式centos_CentOS下修改mysql数据库编码为UTF-8(附mysql开启远程链接和开放3306端口)...

    楼主在配置好linux云服务器的jdk,tomcat,mysql后,当要开始部署项目是,忽然意识到一个很严重的问题,那就是数据库的编码问题,自安装完成后并未修改数据库的额编码....下面就来讲说lin ...

  5. linux中mysql不显示中文_linux中解决mysql中文乱码方法

    改默认编码: /etc/init.d/mysql start (stop) 为启动和停止服务器 /etc/mysql/ 主要配置文件所在位置 my.cnf /var/lib/mysql/ 放置的是数据 ...

  6. mysql 删表卡死_如何解决mysql 删表卡住的问题

    如何解决mysql 删表卡住的问题 mysql删表卡住的解决办法:首先执行"show full processlist;"语句:然后执行"kill processid;& ...

  7. mysql主从切换gtid不一致_解决mysql使用GTID主从复制错误问题

    解决mysql使用GTID主从复制错误问题 做MySQL主从的话肯定会遇到很多同步上的问题, 大多数都是由于机器宕机,重启,或者是主键冲突等引起的从服务器停止工作, 这里专门收集类似问题并提供整理解决 ...

  8. mysql数据库编码设置_如何修改mysql数据库编码

    在建网站时,有时需要将一个数据库里的数据导入到另一个数据库里,但往往会出现二个数据库的编码不同,造成网页乱码.解决方法就是修改数据库编码. 下面介绍一下如何修改MYSQL数据库编码的方法. 方法/步骤 ...

  9. mysql my.ini位置错误_解决mysql导入数据量很大导致失败及查找my.ini 位置(my.ini)在哪...

    数据库数据量很大的数据库导入到本地时,会等很久,然而等很久之后还是显示失败: 这是就要看看自己本地的没mysql是否设置了超时等待,如果报相关time_out这些,可以把mysql.ini尾部添加ma ...

最新文章

  1. Android--EditText控件属性汇总
  2. 拿来主义——老外写的系统统计脚本
  3. 揭开ITIL 4的神秘面纱,引领企业数字化转型
  4. 计算机专业学生求职信500字,计算机专业求职信500字范文
  5. Python中多线程和多处理的初学者指南
  6. 披荆斩棘:饿了么业务架构的演进之路
  7. linux git 搭建 debian,基于Debian Linux搭建Git服务器
  8. Delphi【变体记录及存储方式】
  9. Android-【报错】java.lang.ClassCastException: .MainActivity cannot be cast to java.lang.Runnable
  10. php$.ajax(),使用PHP的jQuery $.ajax()
  11. IntelliJ IDEA主题选择
  12. linux添加jdk权限不够
  13. Sketch的插件管理
  14. 【Uniapp框架】快速开发自己一款APP应用,如何将Uniapp项目快速打包成APP应用
  15. Python抓取网页云音乐指定歌手的歌曲和评论数量
  16. 去掉Word2007文档眉头的横线
  17. vcruntime140_1.dll缺失
  18. TypeError: argument 1 has unexpected type 'NoneType'(解决办法)
  19. MongoDB集群和安全
  20. python量化交易笔记---13.描述性统计

热门文章

  1. Linux学习总结(50)——grep查看打印匹配的下几行或前后几行使用总结
  2. Myeclipse学习总结(10)——MyEclipse2014导入项目时The project was not built since its build问题...
  3. Java基础学习总结(93)——Java编码规范之代码性能及惯例
  4. Mysql学习总结(30)——MySQL 索引详解大全
  5. 用户不在sudoers文件中,需要使用命令 sudo npm install 的解决方法
  6. ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。
  7. P1155 双栈排序
  8. 手动为linux系统添加新用户——过程详解
  9. vue data属性中的值绑定到dom上的一些问题
  10. 高并发秒杀系统--Service事务管理与继承测试