mysql怎麼不亂碼了

2021-10-20 23:10:03 字數 2585 閱讀 7319

我在「utf8字符集的表怎麼直接轉utf8mb4」一文中介紹了如何把錶字符集由utf8直接轉換成utf8mb4的幾種方法。

1、只修改字符集(使用預設校驗集)

[email protected]> alter table t1 convert to character set utf8mb4

2、同時修改表字符集和校驗集

[email protected]> alter table t1 convert to character set utf8mb4 collate utf8mb4_bin;

3、只修改某列的字符集

[email protected]> alter table t1 modify c1 varchar(20) character set utf8mb4 not null default 『』

4、同時修改某列的字符集和校驗集

[email protected]> alter table t1 modify c1 varchar(20) character set utf8mb4 collate utf8mb4_unicode_ci not null default 『』

好了,有個字符集為utf8mb4的表中想儲存各類不同字符集的文字,有哪些注意事項億避免亂碼?

如果是通過web介面儲存資料,則建議在browser端、server端全都採用utf8字符集,mysql server端採用utf8/utf8mb4均可(針對大多數文字,其實utf8字符集就足夠儲存的了)。

其中,mysql端的字符集設定比較讓人頭大,涉及到的字符集有好幾個:character_set_server,server端預設字符集;

character_set_database,database預設字符集,若未設定,則和 character_set_server 的設定一樣;database中的 資料表/stored procedure/stored function 也可以自行設定字符集,若未指定,則和 character_set_database 的設定一樣;資料表中的字元型別列,也可以單獨設定字符集,若未設定,則和該錶指定的字符集一樣;

character_set_client,客戶端顯示讀取結果的字符集;

character_set_connection,客戶端從server端讀取資料時傳輸字符集;

character_set_results,server端將資料傳送給客戶端時的字符集;

可見,涉及到字符集的因素實在太多,因此我們強烈建議各個環節全部採用同一種字符集,避免出現意外狀況。

mysql採用utf8mb4字符集時,儲存文字實際消耗位元組數是由文字內容的位元組數決定的,並非總是需要4位元組,列舉幾種情況:輸入字符集任意,且儲存ascii字元時,每個字元需要1byte;

輸入字符集是gb2312,且儲存的字元是漢字時,每個字元需要2bytes;

輸入字符集是utf8/utf8mb4,且儲存的字元是低編碼漢字時,每個字元需要3bytes;

輸入字符集是utf8/utf8mb4,且儲存的字元是高編碼漢字時,每個字元需要4bytes;

輸入字符集是binary,且儲存的字元是高編碼漢字時,每個字元需要4bytes;

總結建議從前端到後端(瀏覽器=>web server=>mysql連線層=>server層=>db層》table層),盡可能使用同一種字符集;

盡可能採用大字符集,也就是優先順序:utf8mb4 > utf8 > gbk > latin1;

採用邏輯備份資料時,切記要不定期進行恢復測試,我以前在這方面栽過一次,教訓慘痛。

附1,關於編碼簡介ascii碼,佔7bit,由128個字元組成,包括大小寫字母、數字0-9、標點符號、非列印字元(換行符、製表符等4個)以及控制字元(退格、響鈴等)組成;

latin1,佔1byte,在ascii基礎上,增加128 ~ 255區間的字元;

gb2312等cjk字符集,可變長字符集,最多佔2bytes,用於儲存常見的cjk字元;

utf8,可變長字符集,最多佔3bytes,可以囊括ascii、cjk及其他絕大多數常用語言文字;這中間其實還有個unicode字符集,它也是2bytes的,也能囊括ascii字元,但即便是ascii字元也需要消耗2bytes,存在一定浪費,而用utf8儲存ascii字元時,實際只需要1byte,更為節省儲存空間;

utf8mb4,可變長字符集,最多佔4bytes,可以包含上面其他幾種字符集;同樣地,以utf8mb4儲存ascii字元時,實際上也是只占用1bytes,儲存一般的漢字占用3bytes,而儲存個別漢字則需要4bytes,儲存emoji也至少需要4bytes;

為了方便大家,我寫了個簡單的php介面供測試,可以提交一些不常見的漢字,或者emoji表情符,看看是否都能正常顯示。

開發這個介面時,發現釘釘中的個別表情符是由2個4位元組編碼組成的,也就是說乙個emoji表情符,其實是需要8個位元組的。

這個介面最後輸出的格式是:

字串 : 位元組數

比如 "a齒a : 5" ,表示 "a齒a" 這個字串共消耗 5個位元組,因為 "齒" 其實只需要3個位元組來儲存,雖然看起來挺大一坨的。

相應的**如下:

select vchar, length(vchar) as vcharlen

如果想要寫入4位元組的漢字,可以從龍泉寺提供的字型檔拷貝過來,或者插入emoji表情符。

原文發布時間為:2017-12-6

MySQL怎麼存文字不亂碼?

1 只修改字符集 使用預設校驗集 yejr imysql.com alter table t1 convert tocharacter set utf8mb4 2 同時修改表字符集和校驗集 yejr imysql.com alter table t1 convert tocharacter set ...

GET請求不亂碼,Ajax請求POST亂碼問題

var params mainform serialize ajax function else error function 我反覆測試,發現get請求就不會亂碼,post傳到controller就是iso8859 1。最終大牛給我修改後的 var params getformjson mainf...

python python讀寫檔案,都不亂碼

讀是按照文字的編碼方式讀取,寫是按照文字的編碼方式追加 import chardet filename e 2 採集資料 pswf12 180大0小35750 20181206.txt 按照二進位制唯讀模式 開啟檔案 僅讀取一行 並解析文字內容的編碼方式 currentfile open filen...