MySQL字符集詳解

1、什麼是字符集mysql

  簡單的說吧、字符集就是一組對應關係的集合;linux

  一、如今的計算機是在二進制的基礎上創建出來的、二進制是數值的一種表達方式、也就是說二進制只的表達「數」、如十進制的3,在二進制中sql

  就能夠寫成00000011;數據庫

  二、然而在現實生活當中相對於"數"而言咱們用到更多的是「文字」;那這個問題(怎麼保存文字)怎麼解決呢?然而這個問題根本沒有難道學習

  他們、它們決定用一個折中的方式解決;如:保存'a'的時候我就保存一個0,保存'b'的時候我就保存一個1,保存‘A'的時候我就保存一個2編碼

  保存’B‘的時候我就保存一個3。因而整個對應關係就變成了這樣spa

  字符 ->   編碼code

  'a'  -->  0orm

  'b'  -->  1server

  'A'  -->  2

  'B'  -->  3

  就這樣咱們就定義了一個只有4個字符的字符集了;只不過咱們這個字符集相比gbk\utf8這樣的字符集不知道low到那裏去了。

 

2、什麼是排序規則

  一、上面的內容咱們已經本身定義了一個字符集了,有了字符集一些最基本的操做就可能作了,如:我想知道一個字符它是否是'a'那麼

  我只要去看這個字符的編碼是否是0就能夠了,這樣就把一個字符問題變成了一個數字問題了,這樣數據上的相等(=),大小(>,<),也就有了

  新的意義了。

  二、咱們這個字符集還有什麼不足嗎?如:要作到不區分大小寫,那麼咱們以前的 =,<,>也就都來靈了;咱們還要給這個字符集加上新的

  規則才行;如咱們在這裏能夠粗魯的加上規則 1:0=2 ,2: 1=3;這樣就可能作不區分大小寫了。

 

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 表示字符集的名字

 

4、mysql中能夠怎麼指定字符集

  一、mysql能夠在實例級別指定默認字符集、配置項名:character_set_server

  二、能夠在建立庫的時候指定字符集

create database testdb character set utf8;

  三、能夠在建立表的時候指定表級的字符集

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

-- 在表級別指定字符集是utf8

  四、能夠在建立表的時候指定

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

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

 

5、有些編碼不能由用戶定義

  一、先看一個例子

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)

  二、若是元數據用的是ascii碼來保存那麼「用戶」 這個表名是會亂碼的

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

  三、那麼元數據中對字符的保存用的是什麼字符集呢?

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

  四、給你見識一下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 也不是什麼都能作的!

 

6、中文亂碼了怎麼辦?

  一、最爲本質的緣由是你用了錯誤的編碼去查看數據、如數據是以gb2312編碼的,然而你用utf8的方式去看(解碼),固然會有問題。

  二、從應用程序與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來設定的

  三、爲何要有 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 |
+---------------------------+

-- 兩個兼容的字符集之間是能夠進行操做的

  四、爲了讓上圖中的這個閉環能走通(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 中有例子! 

----

交流學習

相關文章
相關標籤/搜索