zoukankan      html  css  js  c++  java
  • MySQL字符集详解

    一、什么是字符集

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

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

      就可以写成00000011;

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

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

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

      字符 ->   编码

      'a'  -->  0

      'b'  -->  1

      'A'  -->  2

      'B'  -->  3

      就这样我们就定义了一个只有4个字符的字符集了;只不过我们这个字符集相比gbkutf8这样的字符集不知道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 中有例子! 

    ----

    交流学习

  • 相关阅读:
    设计模式学习总结系列应用实例
    【研究课题】高校特殊学生的发现及培养机制研究
    Linux下Oracle11G RAC报错:在安装oracle软件时报file not found一例
    python pro practice
    openstack python sdk list tenants get token get servers
    openstack api
    python
    git for windows
    openstack api users list get token get servers
    linux 流量监控
  • 原文地址:https://www.cnblogs.com/JiangLe/p/6907748.html
Copyright © 2011-2022 走看看