MySQL字符集详解

一、什么是字符集

  简单的说吧、字符集就是一组对应关系的集合;

  1、现在的计算机是在二进制的基础上建立出来的、二进制是数值的一种表达方式、也就是说二进制只的表达“数”、如十进制的3,在二进制中

  就可以写成00000011;

  2、然而在现实生活当中相对于"数"而言我们用到更多的是“文字”;那这个问题(怎么保存文字)怎么解决呢?然而这个问题根本没有难道

  他们、它们决定用一个折中的方式解决;如:保存'a'的时候我就保存一个0,保存'b'的时候我就保存一个1,保存‘A'的时候我就保存一个2

  保存’B‘的时候我就保存一个3。于是整个对应关系就变成了这样

  字符 ->   编码

  'a'  -->  0

  'b'  -->  1

  'A'  -->  2

  'B'  -->  3

  就这样我们就定义了一个只有4个字符的字符集了;只不过我们这个字符集相比gbk\utf8这样的字符集不知道low到那里去了。

 

二、什么是排序规则

  1、上面的内容我们已经自己定义了一个字符集了,有了字符集一些最基本的操作就可能做了,如:我想知道一个字符它是不是'a'那么

  我只要去看这个字符的编码是不是0就可以了,这样就把一个字符问题变成了一个数字问题了,这样数据上的相等(=),大小(>,<),也就有了

  新的意义了。

  2、我们这个字符集还有什么不足吗?如:要做到不区分大小写,那么我们之前的 =,<,>也就都来灵了;我们还要给这个字符集加上新的

  规则才行;如我们在这里可以粗鲁的加上规则 1:0=2 ,2: 1=3;这样就可能做不区分大小写了。

 

三、mysql数据库中有哪些字符集可供选择

select * from information_schema.character_sets;
+--------------------+----------------------+---------------------------------+--------+
| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION                     | MAXLEN |
+--------------------+----------------------+---------------------------------+--------+
| big5               | big5_chinese_ci      | Big5 Traditional Chinese        |      2 |
| dec8               | dec8_swedish_ci      | DEC West European               |      1 |
| cp850              | cp850_general_ci     | DOS West European               |      1 |
| hp8                | hp8_english_ci       | HP West European                |      1 |
| koi8r              | koi8r_general_ci     | KOI8-R Relcom Russian           |      1 |
| latin1             | latin1_swedish_ci    | cp1252 West European            |      1 |
| latin2             | latin2_general_ci    | ISO 8859-2 Central European     |      1 |
| swe7               | swe7_swedish_ci      | 7bit Swedish                    |      1 |
| ascii              | ascii_general_ci     | US ASCII                        |      1 |
| ujis               | ujis_japanese_ci     | EUC-JP Japanese                 |      3 |
| sjis               | sjis_japanese_ci     | Shift-JIS Japanese              |      2 |
| hebrew             | hebrew_general_ci    | ISO 8859-8 Hebrew               |      1 |
| tis620             | tis620_thai_ci       | TIS620 Thai                     |      1 |
| euckr              | euckr_korean_ci      | EUC-KR Korean                   |      2 |
| koi8u              | koi8u_general_ci     | KOI8-U Ukrainian                |      1 |
| gb2312             | gb2312_chinese_ci    | GB2312 Simplified Chinese       |      2 |
| greek              | greek_general_ci     | ISO 8859-7 Greek                |      1 |
| cp1250             | cp1250_general_ci    | Windows Central European        |      1 |
| gbk                | gbk_chinese_ci       | GBK Simplified Chinese          |      2 |
| latin5             | latin5_turkish_ci    | ISO 8859-9 Turkish              |      1 |
| armscii8           | armscii8_general_ci  | ARMSCII-8 Armenian              |      1 |
| utf8               | utf8_general_ci      | UTF-8 Unicode                   |      3 |
| ucs2               | ucs2_general_ci      | UCS-2 Unicode                   |      2 |
| cp866              | cp866_general_ci     | DOS Russian                     |      1 |
| keybcs2            | keybcs2_general_ci   | DOS Kamenicky Czech-Slovak      |      1 |
| macce              | macce_general_ci     | Mac Central European            |      1 |
| macroman           | macroman_general_ci  | Mac West European               |      1 |
| cp852              | cp852_general_ci     | DOS Central European            |      1 |
| latin7             | latin7_general_ci    | ISO 8859-13 Baltic              |      1 |
| utf8mb4            | utf8mb4_general_ci   | UTF-8 Unicode                   |      4 |
| cp1251             | cp1251_general_ci    | Windows Cyrillic                |      1 |
| utf16              | utf16_general_ci     | UTF-16 Unicode                  |      4 |
| utf16le            | utf16le_general_ci   | UTF-16LE Unicode                |      4 |
| cp1256             | cp1256_general_ci    | Windows Arabic                  |      1 |
| cp1257             | cp1257_general_ci    | Windows Baltic                  |      1 |
| utf32              | utf32_general_ci     | UTF-32 Unicode                  |      4 |
| binary             | binary               | Binary pseudo charset           |      1 |
| geostd8            | geostd8_general_ci   | GEOSTD8 Georgian                |      1 |
| cp932              | cp932_japanese_ci    | SJIS for Windows Japanese       |      2 |
| eucjpms            | eucjpms_japanese_ci  | UJIS for Windows Japanese       |      3 |
| gb18030            | gb18030_chinese_ci   | China National Standard GB18030 |      4 |
+--------------------+----------------------+---------------------------------+--------+
-- character_set_name 表示字符集的名字

 

四、mysql中可以怎么指定字符集

  1、mysql可以在实例级别指定默认字符集、配置项名:character_set_server

  2、可以在创建库的时候指定字符集

create database testdb character set utf8;

  3、可以在创建表的时候指定表级的字符集

create table person(id int not null auto_increment primary key,name varchar(4)) character set utf8;

-- 在表级别指定字符集是utf8

  4、可以在创建表的时候指定

create table person(id int not null auto_increment primary key,name varchar(4) character set utf8);

-- 指定name 列的字符集是utf8

 

五、有些编码不能由用户定义

  1、先看一个例子

create table user(id int auto_increment primary key,name char(8));
Query OK, 0 rows affected (0.01 sec)

  这样的会在元数据中记录user这个表、别的不说表名是一定要记录在元数据中的吧!好、我们下面再看一个放荡不羁的写法

create table 用户(id int auto_increment primary key,name char(8));
Query OK, 0 rows affected (0.01 sec)

  2、如果元数据用的是ascii码来保存那么“用户” 这个表名是会乱码的

select _ascii '用户';
+--------+
|        |
+--------+
| ?????? |
+--------+
1 row in set, 1 warning (0.00 sec)

  3、那么元数据中对字符的保存用的是什么字符集呢?

show global variables like 'character_set_system';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_system | utf8  |
+----------------------+-------+

  4、给你见识一下mysql对元数据所用的字符集的保护有多强大

set @@global.character_set_system='GB2312';
ERROR 1238 (HY000): Variable 'character_set_system' is a read only variable
mysql> show grants;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

-- root 也不是什么都能做的!

 

六、中文乱码了怎么办?

  1、最为本质的原因是你用了错误的编码去查看数据、如数据是以gb2312编码的,然而你用utf8的方式去看(解码),当然会有问题。

  2、从应用程序与MySQL的交互过程来分析乱码

  2.1 为了使client 发过去的语句MySQL可以正确解析、所以MySQL它就要知道client发送过来的SQL语句的编码、

  这个编码由character_set_client设定

  2.2 为了使MySQL发过去的结果集Client 可以正确解析、所以client它就要知道MySQL发送过来的结果集的编码、

  这个编码由character_set_results设定

  2.3 实现上MySQL会把client 发过来的语句进行一次转码、这次转换的目标编码是由character_set_connection来设定的

  3、为什么要有 character_set_connection ? 知道了character_set_client 就可以解码数据了,为什么还要转码?

  我们来看一下这个例子:

select _utf8'蒋乐哥哥' = _gb2312 '蒋乐哥哥';
ERROR 1267 (HY000): Illegal mix of collations (utf8_general_ci,COERCIBLE) and (gb2312_chinese_ci,COERCIBLE) for operation '='

--  如果两个字符集之间不能兼容的话、是不能进行操作的、所以要兼容就只能转码!

select _utf8'abc' = _ascii 'abc';
+---------------------------+
| _utf8'abc' = _ascii 'abc' |
+---------------------------+
|                         1 |
+---------------------------+

-- 两个兼容的字符集之间是可以进行操作的

  4、为了让上图中的这个闭环能走通(client --sql--> mysqld --结果集--> client)

  character_set_client、character_set_results、character_set_connection 要把这三个变量设置成客户

  端所使用的字符集;你可以一个个的设置、但是我这里想说一个简便的方法,它就是set names

set names 'gb2312';
mysql> show  variables like 'char%';
+--------------------------+------------------------------------------------------------------------+
| Variable_name            | Value                                                                  |
+--------------------------+------------------------------------------------------------------------+
| character_set_client     | utf8                                                                   |
| character_set_connection | utf8                                                                   |
| character_set_database   | utf8                                                                   |
| character_set_filesystem | binary                                                                 |
| character_set_results    | utf8                                                                   |
| character_set_server     | utf8                                                                   |
| character_set_system     | utf8                                                                   |
| character_sets_dir       | /usr/local/mysql-advanced-5.7.18-linux-glibc2.5-x86_64/share/charsets/ |
+--------------------------+------------------------------------------------------------------------+
8 rows in set (0.00 sec)

mysql> set names 'gb2312';
Query OK, 0 rows affected (0.00 sec)

mysql> show  variables like 'char%';
+--------------------------+------------------------------------------------------------------------+
| Variable_name            | Value                                                                  |
+--------------------------+------------------------------------------------------------------------+
| character_set_client     | gb2312                                                                 |
| character_set_connection | gb2312                                                                 |
| character_set_database   | utf8                                                                   |
| character_set_filesystem | binary                                                                 |
| character_set_results    | gb2312                                                                 |
| character_set_server     | utf8                                                                   |
| character_set_system     | utf8                                                                   |
| character_sets_dir       | /usr/local/mysql-advanced-5.7.18-linux-glibc2.5-x86_64/share/charsets/ |
+--------------------------+------------------------------------------------------------------------+
8 rows in set (0.00 sec)

   5 好吧、乱码了怎么办?通过set names 'xxx'; 把字符集设置的与客户端所用的一样、4 中有例子! 

----

交流学习

posted on 2017-05-26 11:41  蒋乐兴的技术随笔  阅读(812)  评论(0编辑  收藏  举报

导航