为什么我的数据库总会出现中文乱码的情况。一堆中文乱码不知道怎么回事?当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。
.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
标签:utf8,SET,character,数据库,字符集,乱码,set,MySQL From: https://www.cnblogs.com/ataoxz/p/18666605