MySQL字元集詳解

來源:互聯網
上載者:User

MySQL字元集詳解

在資料庫中,字元亂碼屬於常見、多發問題。鑒於本人水平頂多隻能歸於不入流之類,寫這篇文章時內心誠惶誠恐,實在擔心誤導大家。內容僅供參考,若有錯誤,請各位及時指出,我也好學習提高!

MySQL的字元集有4種層級的設定,分別是:伺服器級、資料庫級、表級、欄位級。

一、伺服器級字元集

(1)、可以在my.cnf中設定

[mysqld]default-character-set=gbk (5.1)character-set-server=gbk (5.5)

(2)、可以在啟動選項中設定

mysqld --default-character-set=gbk

(3)、可以在編譯的時候設定

./configure --with-charset=gbk          或cmake . -default-charset=gbk

如果沒有指定伺服器的字元集,預設使用latin1為伺服器的字元集。

(4)、查看當前伺服器的字元集

mysql> show variables like '%char%';+--------------------------+-----------------------------------------+| Variable_name            | Value                                   |+--------------------------+-----------------------------------------+| character_set_client     | latin1                                  || character_set_connection | latin1                                  || character_set_database   | latin1                                  || character_set_filesystem | binary                                  || character_set_results    | latin1                                  || character_set_server     | latin1                                  || character_set_system     | utf8                                    || character_sets_dir       | /usr/local/mysql-5.6.28/share/charsets/ |+--------------------------+-----------------------------------------+
二、資料庫字元集

資料庫的字元集在建立資料庫的時候指定,也可以在建立完資料庫之後通過alter database語句修改。如果資料庫中已經存在資料,修改資料庫字元集並不能將已有的資料按新字元集存放。所以無法通過修改資料庫字元集修改資料的內容。

設定資料庫字元集的規則:

(1)、如果指定了字元集和校對規則,則使用指定的規則;

(2)、如果僅指定字元集而沒有指定校對規則,則使用指定的字元集和預設的校對規則;

(3)、如果沒有指定字元集和校對規則,則使用伺服器的字元集和校對規;

三、表字元集

表的字元集是在建表的時候指定的,可以通過alter table語句進行修改。同樣,對於表中已經存在的資料,修改字元集不會影響原有的記錄,仍將使用原有的字元集。

設定表的字元集的規則同設定資料庫的字元集規則。

四、列字元集

列的字元集和校對規則可以在建表的時候指定,也可以在修改表的時候調整。(這個不常用,僅記錄一下)

五、SET NAMES命令

除了上述的四種字元集外,對實際的應用訪問來說,還存在用戶端和服務端之間互動的字元集,如下:

(1)、character_set_client:用戶端字元集
(2)、character_set_connection:串連字元集
(3)、character_set_resluts:結果字元集

通常情況下,這3個字元集都應該是相同的,才能保證使用者寫入的資料被正確的讀出,特別是對於中文字元。

set names命令則用於同時修改這3個參數的值。

六、關於中文字元集插入的實驗

字元集不一致是導致資料庫內中文內容亂碼的罪魁禍首。

實驗環境:

Server version: 5.6.28 (在此說明實驗環境是由於在學習過程中,從網上參考了部分資料,實驗過程與資料描述稍有出入,未查出原因,只能暫歸結為版本不同所致。)

實驗對象:

mysql> show create table char_test\G *************************** 1. row ***************************       Table: char_testCreate Table: CREATE TABLE `char_test` (  `id` smallint(6) NOT NULL AUTO_INCREMENT,  `name` char(20) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin11 row in set (0.00 sec)

由上可知,char_test表的字元集是latin1,如果不設定正確的字元集,插入中文字元時,必然會出現如下錯誤:

mysql> insert into char_test (name) values ('小王');ERROR 1366 (HY000): Incorrect string value: '\xE5\xB0\x8F\xE7\x8E\x8B' for column 'name' at row 1

 

解決方案

(1)、先set names latin1,然後再插入資料。

mysql> set names latin1;Query OK, 0 rows affected (0.00 sec)mysql> insert into char_test (name) values ('小王');Query OK, 1 row affected (0.01 sec)mysql> select * from char_test;+----+--------+| id | name   |+----+--------+|  1 | Tom    ||  2 | 小明   ||  3 | 小王   |+----+--------+3 rows in set (0.00 sec)

(2)、在data.sql檔案中指定set names latin1,然後通過source命令匯入data.sql。

# vi data.sqlset names latin1;insert into char_test (name) values ('小李');mysql> source data.sqlQuery OK, 1 row affected (0.00 sec)mysql> select * from char_test;+----+--------+| id | name   |+----+--------+|  1 | Tom    ||  2 | 小明   ||  3 | 小王   ||  4 | 小李   |+----+--------+4 rows in set (0.00 sec)

(3)、在data.sql檔案中指定set names latin1,然後通過mysql命令匯入

# vi data.sqlset names latin1;insert into char_test (name) values ('小張');# mysql -uroot -p test1 < data.sql# mysql -uroot -p -e "set names latin1;select * from test1.char_test;"

(4)、通過指定mysql命令的字元集參數實現 --default-charset-set=字元集

# vi data.sqlinsert into char_test (name) values ('小張');# 錯誤方法# mysql -uroot -p  test1 < data.sql                      Enter password: ******ERROR 1366 (HY000) at line 1: Incorrect string value: '\xE5\xB0\x8F\xE8\xB5\xB5' for column 'name' at row 1# 正確方法# mysql -uroot -p  --default-character-set=latin1 test1 < data.sql Enter password: ******# mysql -uroot -p -e "set names latin1;select * from test1.char_test;"Enter password: ******+----+--------+| id | name   |+----+--------+|  1 | Tom    ||  2 | 小明   ||  3 | 小王   ||  4 | 小李   ||  5 | 小張   ||  6 | 小趙   |+----+--------+

(5)、在設定檔中指定用戶端的字元集

vi my.cnf[client]default-character-set=latin1mysql> insert into char_test (name) values ('小馬');Query OK, 1 row affected (0.00 sec)mysql> select * from char_test;+----+--------+| id | name   |+----+--------+|  1 | Tom    ||  2 | 小明   ||  3 | 小王   ||  4 | 小李   ||  5 | 小張   ||  6 | 小趙   ||  7 | 小馬   |+----+--------+7 rows in set (0.00 sec)

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.