mysql 解決生僻字,特殊字符插入失敗


MySQL 的 utf8 實際上不是真正的 UTF-8。utf8 只支持每個字符最多三個字節,而真正的 UTF-8 是每個字符最多四個字節。MySQL 一直沒有修復這個 bug,他們在 2010 年發布了一個叫作 utf8mb4 的字符集,繞過了這個問題。當然,他們並沒有對新的字符集廣而告之(可能是因為這個 bug 讓他們覺得很尷尬),以致於現在網絡上仍然在建議開發者使用 utf8,但這些建議都是錯誤的。

簡單概括如下:

  • MySQL 的 utf8mb4 是真正的 UTF-8。

  • MySQL 的 utf8 是一種專屬的編碼,它能夠編碼的 Unicode 字符並不多。
    所有在使用 utf8 的 MySQL 和 MariaDB 用戶都應該改用 utf8mb4,永遠都不要再使用 utf8。

  • 為什么會有UTF8MB4?
    既然utf8應付日常使用完全沒有問題,那為什么還要使用utf8mb4呢? 低版本的MySQL支持的utf8編碼,最大字符長度為 3 字節,如果遇到 4 字節的字符就會出現錯誤了。三個字節的 UTF-8 最大能編碼的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面(BMP)。也就是說,任何不在基本多文平面的 Unicode字符,都無法使用MySQL原有的 utf8 字符集存儲。這些不在BMP中的字符包括哪些呢?最常見的就是Emoji 表情(Emoji 是一種特殊的 Unicode 編碼,常見於 ios 和 android 手機上),和一些不常用的漢字,以及任何新增的 Unicode 字符等等。

  • UTF-8編碼
    理論上將, UTF-8 格式使用一至六個字節,最大能編碼 31 位字符。最新的 UTF-8 規范只使用一到四個字節,最大能編碼21位,正好能夠表示所有的 17個 Unicode 平面。關於UTF編碼,請閱讀《常見編碼總結》一文。
    而utf8 則是 Mysql 早期版本中支持的一種字符集,只支持最長三個字節的 UTF-8字符,也就是 Unicode 中的基本多文本平面。這可能是因為在MySQL發布初期,基本多文種平面之外的字符確實很少用到。而在MySQL5.5.3版本后,要在 Mysql 中保存 4 字節長度的 UTF-8 字符,就可以使用 utf8mb4 字符集了。例如可以用utf8mb4字符編碼直接存儲emoj表情,而不是存表情的替換字符。
    為了獲取更好的兼容性,應該總是使用 utf8mb4 而非 utf8,事實上,最新版的phpmyadmin默認字符集就是utf8mb4。誠然,對於 CHAR 類型數據,使用utf8mb4 存儲會多消耗一些空間。

  • 那么utf8mb4比utf8多了什么的呢?
    多了emoji編碼支持.
    如果實際用途上來看,可以給要用到emoji的庫或者說表,設置utf8mb4.
    比如評論要支持emoji可以用到.
    建議普通表使用utf8 如果這個表需要支持emoji就使用utf8mb4
    新建mysql庫或者表的時候還有一個排序規則
    utf8_unicode_ci比較准確,utf8_general_ci速度比較快。通常情況下 utf8_general_ci的准確性就夠我們用的了,在我看過很多程序源碼后,發現它們大多數也用的是utf8_general_ci,所以新建數據 庫時一般選用utf8_general_ci就可以了
    如果是utf8mb4那么對應的就是 utf8mb4_general_ci utf8mb4_unicode_ci

查詢系統字符編碼變量 (最好不要使用連接工具 navica 等,查出來的不准,使用終端,cmd 等)

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
  • 未修改之前


     
    image.png

修改設置

  • 修改數據庫編碼及字符集
ALTER DATABASE db_name(你的數據庫) CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; 
  • 給沒有設置編碼的表設置編碼
alter table table_name(你的表名) default character set utf8mb4 collate=utf8mb4_general_ci; 
  • 批量生成修改所有表編碼的 sql 然后復制執行
SELECT CONCAT("ALTER TABLE `", TABLE_NAME,"` default character set utf8mb4 collate=utf8mb4_general_ci;") AS target_tables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = "db_name" (這里是數據庫名) AND TABLE_TYPE="BASE TABLE" 
  • 修改表字段編碼
ALTER TABLE temp convert to CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • 批量生成修改所有表字段編碼的 sql 然后復制執行
SELECT CONCAT("ALTER TABLE `", TABLE_NAME,"` convert to CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") AS target_tables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = "db_name" (這里是數據庫名) AND TABLE_TYPE="BASE TABLE" 
  • 修改 my.ini 文件或者 my-default.int 文件
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] # 設置表字段排序規則 init_connect='SET collation_connection = utf8mb4_unicode_ci' # set names utf8 是用於設置編碼,可以再在建數據庫的時候設置,也可以在創建表的時候設置,或只是對部分字段進行設置 init_connect='SET NAMES utf8mb4' # 設置數據庫編碼 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci # 此處是忽略客戶端的字符集,使用服務器的設置 skip-character-set-client-handshake 

重新啟動

修改之后

 
 



作者:吉他手_c156
鏈接:https://www.jianshu.com/p/b821f69e189a
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM