mysql字符集基础知识
1.什么叫字符集?常用的字符集的分类?
字符集就是字符和编码的集合,常用的中文字符集是gbk,英文字符集是ASCII
多种字符在一个字符集里,常用的UTF8
2.数据库存取数据与字符集的关系
数据库在存取数据时,会在字符集中寻找各个字符对应的编码,然后存取编码
3.操作系统查看字符集的种类
windows 使用chcp命令查看,查看到是936,说明是中文字符集
linux 使用cat /etc/sysconfig/i18n #当前是utf8字符集4.在linux中编码和字符的关系,以ASCII字符集为例
mysql> select ascii(‘a’); ##查看在ASCII中字符a对应的编码
±-----------+
| ascii(‘a’) |
±-----------+
| 97 | ##在ascii中,字符a对应的编码是97
±-----------+
1 row in set (0.01 sec)
mysql> select ascii(‘x’);
±-----------+
| ascii(‘x’) |
±-----------+
| 120 |
±-----------+
1 row in set (0.00 sec)
mysql> select ascii(‘1’);
±-----------+
| ascii(‘1’) |
±-----------+
| 49 | ##字符1对应的编码是49
±-----------+
1 row in set (0.00 sec)
5.mysql内部存储字符集的相关知识
1)mysql内部存储字符集有4种。分别是服务器字符集,数据库字符集,表字符集,列字符集,他们的优先级顺序是列字符集 > 表字符集 > 数据库字符集 > 数据库字符集,因为数据最终存放在列上。我们常用的字符集是数据库字符集和表字符集,服务器级别一般忽略
如果列的字符集没有设置,那么列的字符集就会继承表的字符集
2)mysql> show character set; ##查看数据库级别中有哪些字符集
mysql> show variables like ‘%character%’; ##可以查看到服务器级别(character_set_server)是什么字符集,一 般忽略!
mysql>show create database test; ##可以查看到test数据库是什么字符集
3)在创建数据库(database)的时候可以指定该数据库是哪个字符集,同样在新建表(table)也可以指定是哪个字符集
EX: mysql> create table t20(name varchar(10)) character set gbk;
Query OK, 0 rows affected (0.06 sec)
##创建t20表,指定为gbk字符集
mysql>show create table t20;
##可以查看到t20表是哪个字符集
同样的新建列时也可以指定是哪个字符集
mysql> create table t21(name varchar(10) character set big5); ##新建t21表,表里有name列,name列上是big5字符集
Query OK, 0 rows affected (0.05 sec)
mysql> show create table t21; ##查看t21表中的信息,可以看到列的字符集
±------±-----------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
±------±-----------------------------------------------------------------------------------------------------------------+
| t21 | CREATE TABLE t21
(
name
varchar(10) CHARACTER SET big5 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
±------±-----------------------------------------------------------------------------------------------------------------+
mysql字符集综合解惑以及最佳实践
mysql> show variables like ‘%character%’;
±-------------------------±---------------------------------+
| Variable_name | Value |
±-------------------------±---------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
±-------------------------±---------------------------------+
各类字符集关系详解
1.客户端连接服务端,客户端在往服务端传输数据时,数据只能以数字形式传输,所以在传输之前会对数据进行编码
假如在客户端执行insert into t20(name) values(‘你好’);【命令释义:往t20表中的name列插入你好】。
‘你好’被进行了编码 假设被编成9190和9133
2.mysql服务端接到你输入的SQL语句以后,发现里面有字符,他会在发送之前做以下事情
1)发现是insert命令
2)发现t20表中的name列的数据类型是varchar,varchar里面存放的是字符,字符就需要编码
3)找到‘你好’对应的编码‘9190 ,9193’
4)找到对应编码以后,客户端会通过character_set_client参数告诉服务端自己的编码方式
补充:可以通过status查看客户端的编码方式
Client characterset一定要正确的反映客户端的编码方式
注:
1)存数据即客户端执行插入等语句时:
如果客户端的character_set_client对应的编码方式与服务器端character_set_connection对应的编码方式不一致时,会发生转换;但是只能有一次转换机会,也可能发生在character_set_connection对应的编码方式与mysql内部存储字符集的编码方式不一致;如果都一致,则不会进行转换
2)取数据即客户端向服务端读取数据时:
服务端的character_set_connection与客户端的character_set_results,两者发生协商
注意:存数据和取数据与服务端协商不是一个通道,存数据是与character_set_client参数有关,取数据是与character_set_results参数有关
最佳实践举例:d1列没有设置字符集,d2列是utf8,d1和d2列上都含有varchar数据类型的列
当中国用户往d1列上插入数据时,不用转换,取数据时也没有发生转换,因为client,connection和d1列的字符集都是gbk
当日本用户往d2列上插入数据时,在client和connection上没有发生转换,在d2列上发生转换,将日文的字符集转换为utf8,取数据时将utf8转换为日文字符集
校对规则(collation)
我们需要针对utf8字符集或其他字符集设置一个关于比较和排序的大小写是否敏感的参数,默认是都不区分大小写。
如何设置这个参数?
我们需要在建表时,指定collate=utf8_bin(utf8可以换成其他字符集)
mysql> create table t2(id int,name varchar(20)) CHARACTER SET utf8 COLLATE=utf8_bin;
##建表和id,name列,指定为utf8字符集,并且设置参数为大小写敏感
Query OK, 0 rows affected (0.05 sec)
mysql> insert into t2 values(1,‘a’); #往id列中插入1,name列中插入a
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(1,‘A’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(1,‘B’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(1,‘b’);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t2 where name=‘a’; ##查看t2列中名字叫a的列
±-----±-----+
| id | name |
±-----±-----+
| 1 | a |
±-----±-----+
1 row in set (0.00 sec)
utf8_bin是按照字符编码的数字大小排序
可以使用select ascii(‘字符’)查看对应的编码号
所以utf8_bin的排序方式是ABab
综上可以看出设置utf8_bin这个参数会影响排序方式和where条件语句
关于collation的特点
在mysql服务器,数据库,表,列四种级别中都有collation,且优先级越来越高
我们可以在建表时使用SET utf8 COLLATE=utf8_bin语句设置collation参数,那么collate有哪些值可以设置呢?我们可以使用show collation;查看允许设置的值。