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 中有例子!
----
交流學習