溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux下mysql字符集問題如何處理

發(fā)布時(shí)間:2021-11-06 14:31:27 來源:億速云 閱讀:185 作者:小新 欄目:MySQL數(shù)據(jù)庫(kù)

小編給大家分享一下Linux下mysql字符集問題如何處理,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

4.1之前的 MySQL 不支持多語言,所以它會(huì)將你給它的數(shù)據(jù)“原封不動(dòng)”地保存,再“原封不動(dòng)”地讀出來。4.1及以后的版本開始支持多語言,這個(gè)所謂的多語言,就是在輸入輸出時(shí) MySQL 會(huì)替你做編碼轉(zhuǎn)換。而這個(gè)轉(zhuǎn)換規(guī)則就是由客戶端編碼和服務(wù)器端編碼來決定的。編碼轉(zhuǎn)換的規(guī)則就是,在輸入數(shù)據(jù)時(shí)將編碼由“客戶端編碼”轉(zhuǎn)換為“服務(wù)器端編碼”,輸出時(shí)將數(shù)據(jù)由“服務(wù)器端編碼”轉(zhuǎn)換為“客戶端編碼”。

MySQL 4.1.x開始支持以下這些事情

  使用多種字符集(Character Set)來存儲(chǔ)字符

  使用多種校對(duì)規(guī)則(Collation)來比較字符串

  在同一臺(tái)服務(wù)器、同一個(gè)數(shù)據(jù)庫(kù)或甚至在同一個(gè)表中使用不同字符集或校對(duì)規(guī)則來混合字符串

 允許定義任何級(jí)別的字符集和校對(duì)規(guī)則

  MySQL 4.1及以上版本的字符集支持(Character Set Support)有兩個(gè)方面:字符集(Character Set)和校對(duì)規(guī)則(Collation)。字符集和校對(duì)規(guī)則有4個(gè)級(jí)別的默認(rèn)設(shè)置:服務(wù)器(server),數(shù)據(jù)庫(kù)(database),數(shù)據(jù)表(table)和連接(connection)。

MySQL字符集設(shè)置

character_set_server:默認(rèn)的內(nèi)部操作字符集

character_set_database:當(dāng)前選中數(shù)據(jù)庫(kù)的默認(rèn)字符集

vi /etc/my.cnf-- 全局選項(xiàng)

[mysqld]

default-character-set=utf8

只能改變對(duì)存儲(chǔ)層(server,database,table,column,system)的設(shè)定,對(duì)于客戶端和服務(wù)器端的通訊層沒有任何影響

character_set_client:客戶端來源數(shù)據(jù)使用的字符集

character_set_connection:連接層字符集

character_set_results:查詢結(jié)果字符集

vi /etc/my.cnf-- 全局選項(xiàng)

[mysql]

default-character-set=utf8

修改當(dāng)前session值:

SET NAMES 'x'語句與這三個(gè)語句等價(jià):

mysql> SET character_set_client = x;

mysql> SET character_set_results = x;

mysql> SET character_set_connection = x;

character_set_system:系統(tǒng)元數(shù)據(jù)(字段名等)字符集

還有以collation_開頭的同上面對(duì)應(yīng)的變量,用來描述字符序。

或者:

CREATE DATABASE db_name DEFAULT CHARACTER SET charset_name;

ALTER DATABASE db_nameDEFAULT CHARACTER SET charset_name;


MySQL
中的字符集轉(zhuǎn)換過程

1. MySQL Server收到請(qǐng)求時(shí)將請(qǐng)求數(shù)據(jù)從character_set_client轉(zhuǎn)換為character_set_connection;

2. 進(jìn)行內(nèi)部操作前將請(qǐng)求數(shù)據(jù)從character_set_connection轉(zhuǎn)換為內(nèi)部操作字符集,其確定方法如下:

使用每個(gè)數(shù)據(jù)字段的CHARACTER SET設(shè)定值;

若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)表的DEFAULT CHARACTER SET設(shè)定值(MySQL擴(kuò)展,非SQL標(biāo)準(zhǔn));

若上述值不存在,則使用對(duì)應(yīng)數(shù)據(jù)庫(kù)的DEFAULT CHARACTER SET設(shè)定值;

若上述值不存在,則使用character_set_server設(shè)定值。

3. 將操作結(jié)果從內(nèi)部操作字符集轉(zhuǎn)換為character_set_results。

檢測(cè)字符集問題的一些手段

SHOW CHARACTER SET;

SHOW COLLATION;

SHOW VARIABLES LIKE ‘character%’;

SHOW VARIABLES LIKE ‘collation%’;

SQL函數(shù)HEXLENGTH、CHAR_LENGTH

SQL函數(shù)CHARSET、COLLATION

STATUS;

常見問題解析

向默認(rèn)字符集為utf8的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前沒有設(shè)置連接字符集,查詢時(shí)設(shè)置連接字符集為utf8

– 插入時(shí)根據(jù)MySQL服務(wù)器的默認(rèn)設(shè)置,character_set_client、character_set_connectioncharacter_set_results均為latin1

– 插入操作的數(shù)據(jù)將經(jīng)過latin1=>latin1=>utf8的字符集轉(zhuǎn)換過程,這一過程中每個(gè)插入的漢字都會(huì)從原始的3個(gè)字節(jié)變成6個(gè)字節(jié)保存;

– 查詢時(shí)的結(jié)果將經(jīng)過utf8=>utf8的字符集轉(zhuǎn)換過程,將保存的6個(gè)字節(jié)原封不動(dòng)返回,產(chǎn)生亂碼……

向默認(rèn)字符集為latin1的數(shù)據(jù)表插入utf8編碼的數(shù)據(jù)前設(shè)置了連接字符集為utf8

– 插入時(shí)根據(jù)連接字符集設(shè)置,character_set_client、character_set_connectioncharacter_set_results均為utf8;

– 插入數(shù)據(jù)將經(jīng)過utf8=>utf8=>latin1的字符集轉(zhuǎn)換,若原始數(shù)據(jù)中含有u0000~u00ff范圍以外的Unicode字 符,會(huì)因?yàn)闊o法在latin1字符集中表示而被轉(zhuǎn)換為“?(0×3F)符號(hào),以后查詢時(shí)不管連接字符集設(shè)置如何都無法恢復(fù)其內(nèi)容了。

本次兩次測(cè)試內(nèi)容:

環(huán)境ed Hat Enterprise Linux Server release 5.5 (Tikanga)LANG=zh_CN.UTF-8

mysql5.0.77

測(cè)試一:

Vi/etc/my.cnf

[mysqld]

default-character-set=utf8

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | lantin1 |
| character_set_connection | lantin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | lantin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/

結(jié)果:服務(wù)器端正常,

在客戶端訪問WindowXp EMS SQL Manager for my sql是亂碼:

測(cè)試二:

set names utf8;

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/share/mysql/charsets/

測(cè)試一中的數(shù)據(jù)變?yōu)閬y碼,測(cè)試二中的數(shù)據(jù)正常顯示。

測(cè)試二的數(shù)據(jù)在客戶端數(shù)據(jù)也正常顯示。

如果從客戶端插入數(shù)據(jù):測(cè)試三

在服務(wù)器則顯示亂碼:

測(cè)試三:

set names utf8;

set character_set_results=gb2312

insert into test values('測(cè)試');

客戶端正常,服務(wù)器亂碼

客戶端:

處理亂碼的思路:

讓服務(wù)器端和客戶端的字符集保持一致。

服務(wù)器端的編碼是由字符集(Character Set)和校對(duì)規(guī)則(Collation)決定的。

  上面提到,MySQL 中是根據(jù)下面幾個(gè)變量確定服務(wù)器端和客戶端用的什么字符集:

  character_set_client     客戶端字符集

  character_set_connection   客戶端與服務(wù)器端連接采用的字符集

  character_set_results     SELECT查詢返回?cái)?shù)據(jù)的字符集

  character_set_database    數(shù)據(jù)庫(kù)采用的字符集

也就是說,只要保證這幾個(gè)變量采用一致的字符集,就不會(huì)出現(xiàn)亂碼問題了。

很多情況下,這樣設(shè)置了之后就能把亂碼問題解決了。但是還是不能完全避免出現(xiàn)亂碼的可能,為什么呢? 因?yàn)?span lang="EN-US">character_set_client character_set_connection 這兩個(gè)變量?jī)H用于保證與 character_set_database 編碼的一致,而 character_set_results 則用于保證 SELECT 返回的結(jié)果與程序的編碼一致。例如,你的數(shù)據(jù)庫(kù)(character_set_database)用的是 utf8 的字符集,那么你就要保證 character_set_client ,character_set_connection 也是utf8的字符集。而你的程序也許采用的并不是utf8 ,比如你的程序用的是gbk ,那么你若把 character_set_results 也設(shè)置為 utf8 的話就會(huì)出現(xiàn)亂碼問題。此時(shí)你應(yīng)該把 character_set_results 設(shè)置為gbk。這樣就能保證數(shù)據(jù)庫(kù)返回的結(jié)果與你的程序的編碼一致。

備注:

1、要保證數(shù)據(jù)庫(kù)中存的數(shù)據(jù)與數(shù)據(jù)庫(kù)編碼一致,即數(shù)據(jù)編碼與character_set_database一致;

2、要保證通訊的字符集與數(shù)據(jù)庫(kù)的字符集一致,即character_set_client, character_set_connectioncharacter_set_database一致;

3、要保證SELECT的返回與程序的編碼一致,即character_set_results與程序編碼一致;

4、要保證程序編碼與瀏覽器編碼一致,即程序編碼與"/>一致。

更改設(shè)定值的一個(gè)方法是通過重新編譯。如果希望在從源程序構(gòu)建時(shí)更改默認(rèn)服務(wù)器字符集和校對(duì)規(guī)則,使用:--with-charset--with-collation作為configure的參量。例如:

shell> ./configure --with-charset=latin1

以上是“Linux下mysql字符集問題如何處理”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI