MySQL数据库出现乱码怎么解决

为什么我的数据库总会出现中文乱码的情况。一堆中文乱码不知道怎么回事?当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。

.1 解决乱码的几个方面

对于中文乱码的情况,从三个方面

  • 数据终端: 就是我们连接数据库的工具设置为utf8
  • 操作系统层面:linux 系统通过 在命令争端查看当前编码echo $LANG或者locale

如何修改了系统编码了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# centos 6.x 版本是/etc/sysconfig/i18n
修改这个文件
shell> vim /etc/sysconfig/i18n
# 这一行改为utf8
LANG=en_US.UTF-8
# 修改完,不要重启,立即生效如下
shell> source /etc/sysconfig/i18n
 
 
# centos 7.x 版本是/etc/locale.conf 这个文件
[root@mysql-150 ~]# vim /etc/locale.conf
LANG="en_US.UTF-8"
#立即生效
[root@mysql-150 ~]# source /etc/locale.conf

  

  • 数据库层面:

在参数文件中的[mysqld] 下,加入相应utf8字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 注意数据库的系统版本
5.6.x 和 5.7.x设置字符集参数不一样,8.x和5.7.x设置是一样的
#查看当前数据库的字符集参数,查看当前字符集参数
mysql> show variables like '%character%';
 
# 查看数据库支持的字符编码,和编码的排序规则
mysql> show character set;
 
# 修改sutdents表中sname 字段的字符编码
mysql> alter table students modify sname varchar(66) character set gbk;
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0
 
#看看表结构
mysql> show create table students;
...
| students | CREATE TABLE `students` (
  `sid` int(11) NOT NULL,
  `sname` varchar(66) CHARACTER SET gbk DEFAULT NULL,
  `sex` int(11) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
...
 
# 查看连接级字符集和排序规则
mysql> show variables like '%collation%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+

  

从上面示例可以得出:

如果修改数据库字符集,需要从以下考

  • 列级别字符集

  • 表级别字符集

  • 库级别字符集

  • mysql 实例字符集

2 怎么合理修改mysql字符集了

在/etc/my.cnf 加一下参数

1
2
3
4
5
6
7
8
9
10
11
vim /etc/my.cnf
[mysqld]
init-connect='SET NAMES utf8'
character-set-server=utf8
然后去数据库操作:
mysql> set @@global.character_set_server=utf8;
Query OK, 0 rows affected (0.00 sec)
 
mysql> set @@global.init_connect='SET NAMES utf8';
Query OK, 0 rows affected (0.00 sec)
# 注 用户操作的时候看看有没有super权限,对super用户权限 set names 不生效

  

有人说,修改完还是乱码, 这时候就乱码是哪个库的字符集,哪个表的字符集,哪个字段的字符集,还有操作系统字符集,程序连接的字符集,这些都的查看。

在/etc/my.cnf中init-connect='SET NAMES utf8'是什么意思:

让每个客户端连接都自动设置字符集,但缺点是对拥有super权限的用户不生效

init_connect表示服务器为每个连接的客户端执行的字符串。字符串由一个或多个SQL语句组成。要想指定多个语句,用分号间隔开 。

 比如:

1
2
3
4
5
6
# 举例init_connect
mysql> SET @@GLOBAL.init_connect='SET AUTOCOMMIT=0;set names
utf8';
shell> vim my.cnf
[mysqld]
init_connect='SET AUTOCOMMIT=0;set names utf8'

3 连接级字符集和排序规则

  • 每个数据库客户端连接都有自己的字符集和排序规则属性,

    客户端发送的语句的字符集是由character_set_client决定,

    而与服务端交互时会根据character_set_connection和collation_connection两个参数将接收到的语句转化。当涉及到显示字符串的比较时,由collation_connection参数决定,

    而当比较的是字段里的字符串时则根据字段本身的排序规则决定

  • character_set_result参数决定了语句的执行结果以什么字符集返回给客户端

  • 客户端可以很方便的调整字符集和排序规则,比如使用SET NAMES 'charset_name' [COLLATE 'collation_name']表明后续的语句都以该字符集格式传送给服务端,而执行结果也以此字符集格式返回。

  

set names 字符集

1
2
3
4
set names charset_name 语句相当于执行了以下三行语句:
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;

  

或者执行SET CHARACTER SET 'charset_name'命令 :此命令和set names非常类似,唯一不同是将connection的字符集设置为当前数据库的字符集,所以相当于执行以下三行语句:

1
2
3
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = @@character_set_database;

小结: 中文乱码从:数据终端,操作系统,数据库

数据库从: 全局数据库server字符集——>数据库字符集——> 表字符集——> 列字符集

4 表情乱码不能识别

修改存表情字段的字符集为utf8mb4  

posted on   数据库那些事儿  阅读(12)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示