mysq字符编码

目录

字符简介

常用字符集简介

Mysql中的字符集

字符集和比较字符集修改关联

mysql中字符集分类

客户端和服务器通信中的字符集

总结


字符简介

字符集:计算机中只能存储二进制数据,存储字符就需要建立字符与二进制数据的映射关系。将一个字符映射成一个二进制数据的过程也叫做编码,将一个二进制数据映射到一个字符的过程叫做解码。包含字符的范围和编码规则如 :

比较规则:是比较两个字符大小的规则,二进制比较规则是简单,对于某一种字符集来说,比较 两个字符大小的规则可以制定出很多种。

常用字符集简介

林子大了什么鸟 都有,很不幸,世界很大,就像各国的语言,不同的人制定出了多种不不同的字符集,它们表示的字符范围和用到的编码规则可能都不一样,比较常用的字符集:

  • ASCII字符集
    共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所以可以使用1个字节来进行编码,我们看一些字符的编码方式:
  • ISO 8859-1字符集
    共收录256个字符,是在ASCII字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以使用1个字节来进行编码。这个 字符集也有一个别名latin1。

  • GB2312字符集
    收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个,其他文字符号682个

  • GBK字符集
    GBK字符集只是在收录字符范围上对GB2312字符集作了扩充,编码方式上兼容GB2312。

  • utf8字符集
    收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容ASCII字符集,采用变长编码方式,编码一个字符需要使用1~4个字 节

如果该字符在ASCII字符集中,则采用1字节编码,否则采用2字节编码。对于同一个字符,不同字符集也可能有不同的编码方式。

Mysql中的字符集

MySQL中的 utf8和 utf8mb4

正常utf8字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在MySQL中字符集表示一 个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以MySQL设计者做了特殊设定:

  • utf8mb3:阉割过的utf8字符集,只使用1~3个字节表示字符。
  • utf8mb4:正宗的utf8字符集,使用1~4个字节表示字符。

在MySQL中utf8是utf8mb3的别名,所以之后在MySQL中提到utf8就意味着使用1~3个字节来表示一个字符。

查看字符集

查看 myslq支持的字符集、默认总共41中。

mysql> SHOW CHARSET;       #查看支持的所有字符集

mysql>SHOW CHARSET  LIKE 'utf%';    #查看支持包含utf开头的字符集

查看比较字符集 

mysql> SHOW COLLATION ;       #查看支持的所有字符集

mysql>SHOW COLLATION  LIKE 'utf%';    #查看支持包含utf开头的字符集

比较规则的命名还挺有规律的,utf8_general_ci是一种通用的比较规则,utf8_polish_ci表示以波兰语的规则比较,不用过多记忆 ,了解即可,一般默认比较规则就能满足正常使用。

ai:不区分重音    as:区分重音    ci:不区分大小写    cs:区分大小写    bin:以二进制方式比较

字符集和比较字符集修改关联

由于字符集和比较规则是互相有联系的,如果我们只修改了字符集,比较规则也会跟着变化,如果只修改了比较规则,字符集也会跟着变化,具体规则如下:

  • 只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。
  • 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。

不论哪个级别的字符集和比较规则,这两条规则都适用

mysql中字符集分类

主要有四个层次:服务器,数据库,表和列.字符集编码不仅影响数据存储,还影响客户端程序和数据库之间的交互。

服务器级别

MySQL提供了两个系统变量来表示服务器级别的字符集和比较规则

SHOW VARIABLES LIKE 'character_set_server';

SHOW VARIABLES LIKE 'collation_server';

root@localhost:mysql.sock  15:45:27 [mysql]>SHOW VARIABLES LIKE 'character_set_server';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_server | gbk   |
+----------------------+-------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  15:55:13 [mysql]>SHOW VARIABLES LIKE 'collation_server';
+------------------+----------------+
| Variable_name    | Value          |
+------------------+----------------+
| collation_server | gbk_chinese_ci |
+------------------+----------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  15:55:27 [mysql]>

可以看到在我的计算机中服务器级别默认的字符集是gbk,默认的比较规则是gbk_general_ci

修改服务器级别编码:

修改mysql的配置文件/etc/my.cnf,然后重启,当服务器启动的时候读取这个配置文件后这两个系统变量的值便修改了。

[server] 
character_set_server=utf8 
collation_server=utf8_general_ci 

数据库级别

查看数据库级别字符集和比较字符集 

root@localhost:mysql.sock  16:01:10 [mysql]>use nacos
Database changed
root@localhost:mysql.sock  16:01:16 [nacos]>SHOW VARIABLES LIKE 'character_set_database';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| character_set_database | utf8  |
+------------------------+-------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  16:01:19 [nacos]> SHOW VARIABLES LIKE 'collation_database';
+--------------------+-----------------+
| Variable_name      | Value           |
+--------------------+-----------------+
| collation_database | utf8_general_ci |
+--------------------+-----------------+
1 row in set (0.00 sec)

root@localhost:mysql.sock  16:01:31 [nacos]>

character_set_database 和collation_database 这两个系统变量是只读的,我们不能通过修改这两个变量的值而改变当前数据库的字符集和比较规则。

如果创建数据库的时候不指定字符集和比较规则,将使用服务器级别的字符集和比较规则作为数据库的字符集和比较规则。

表级别

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

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

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

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

CREATE TABLE  user (
  id int(11),
  name varchar(255) 
) CHARACTER SET utf8 COLLATE utf8_general_ci;

列级别

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

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

ALTER TABLE 表名 MODIFY

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

mysql> ALTER TABLE t MODIFY 
col VARCHAR(10) CHARACTER SET gbk COLLATE gbk_chinese_ci;
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

各级别字符集和比较规则小结

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

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

客户端和服务器通信中的字符集

编码和解码使用的字符集不一致会导致中文乱码问题

MySQL中字符集的转换

我们知道从客户端发往服务器的请求本质上就是一个字符串,服务器向客户端返回的结果本质上也是一个字符串,而字符串其实是使用某种字 符集编码的二进制数据。这个字符串可不是使用一种字符集的编码方式一条道走到黑的,从发送请求到返回结果这个过程中伴随着多次字符集 的转换
character_set_client:服务器解码请求时使用的字符集

character_set_connection:服务器处理请求时会把请求字符串从character_set_client转为character_set_connection

character_set_results:服务器向客户端返回数据时使用的字符集

mysql> SHOW VARIABLES LIKE 'character_set_client';
mysql> SHOW VARIABLES LIKE 'character_set_connection';
mysql> SHOW VARIABLES LIKE 'character_set_results';

设置字符集 

客户端这时候一般需要指定utf8方式连接才能避免乱码。也就是传说总的set  names命令。事实上,set names 字符集 ;命令对应的是服务器端以下几个命令:

SET character_set_client = 字符集名;
SET character_set_connection = 字符集名;

SET character_set_results = 字符集名;

mysql> SET character_set_client = utf8;
mysql> SET character_set_results = utf8;
mysql> SET character_set_connection = utf8;

但这个参数是不能写在配置文件my.cnf里的。只能通过set命令来动态修改。我们需要的是在配置文件里写好一劳永逸的办法。那么这时候,是否有在服务端解决问题的办法呢,可行的思路是在init_connect里设置。这个命令在每个普通用户连接上来的时候都会触发执行,可以在[mysqld]部分增加以下一行设置连接字符集:
在[mysqld]下添加:
  init_connect = 'SET NAMES utf8'

总结

1.在[mysqld]下添加,控制客户端
  default-character-set=utf8 
2.在[client]下添加,控制服务端
  default-character-set=utf8

3、在[mysqld]下添加,控制客户端、连接、服务端
  init_connect = 'SET NAMES utf8'
4、常用命令

#更改客户端、服务器、数据库字符集的命令
 mysql> set character_set_client=utf8;
 mysql> set character_set_connection=utf8;
 mysql> set character_set_database=utf8;
 mysql> set character_set_results=utf8;
 mysql> set character_set_server=utf8;
 mysql> set character_set_system=utf8;

 mysql> set collation_connection=utf8;
 mysql> set collation_database=utf8;
 mysql> set collation_server=utf8;

#查看字符集 
show variables like 'collation_%';
show variables like 'character_set_%';

#设置数据库字符集
alter database mini default character set = gb2312; 
create database mydb character set gb2312;

#修改单个表字符集
alter table pub_logs default character set = gb2312; 
alter table pub_logs convert to character set gb2312;

#生成批量更新字符集 
SELECT a.TABLE_TYPE,CONCAT('alter TABLE ',A.TABLE_NAME,' default character set = gb2312;')  FROM INFORMATION_SCHEMA.TABLES A
WHERE A.TABLE_SCHEMA='MINI'
AND a.TABLE_TYPE='BASE TABLE';

#生成批量更新列字符集
SELECT CONCAT(CONCAT(CONCAT('alter TABLE ',c.TABLE_NAME,' modify'),CONCAT(' ',C.COLUMN_NAME,' '),C.COLUMN_TYPE),' ',' character set gb2312 COLLATE gb2312_chinese_ci;') 
 AS CLOU
 FROM 
 INFORMATION_SCHEMA.COLUMNS C,INFORMATION_SCHEMA.TABLES A
 WHERE c.TABLE_SCHEMA='MINI'
 AND A.TABLE_NAME=c.TABLE_NAME
 AND A.TABLE_TYPE='BASE TABLE'
 AND c.DATA_TYPE='varchar' ;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值