• 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 中有例子! 

    ----

    交流学习

  • 相关阅读:
    iOS开发之单例模式
    XCode 安装 Alcatraz包管理器失败的处理
    iOS "此证书由未知颁发机构签名"此问题的解决方法
    Android WebView 使用
    BaseActivity
    定时周期执行指定的任务 ScheduledExecutorService
    SQLite数据库浅谈
    android 图片缓存
    Android之drawable state各个属性详解
    Android应用中如何启动另一个应用
  • 原文地址:https://www.cnblogs.com/JiangLe/p/6907748.html
Copyright © 2020-2023  润新知