謹記不要在MySQL中使用“utf8”編碼


掉坑回顧:

最近在工作中遇到一個BUG,用於記錄客戶昵稱的數據表,在插入帶有表情的字符時候報錯.使用的存儲引擎是INNODB,當我查看數據庫字段的時候確實是設置的utf8,我傳入的字符也是utf8的編碼集,這有什么錯?直到我深入了解才發自己使用的姿勢並不對,mysql數據庫中的"utf8"並不是真正的utf8編碼,關於這個問題mysql官方一直未能修復,取而代之的推出了utf8mb4,這一點讓我記憶猶新,切記mysql中不要再使用utf8編碼!

1.BUG重現

這里我做了一個簡單的試驗,來驗證utf8在mysql中存在的問題:

建立數據表:

CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `nickname` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '昵稱',
  `sex` varchar(255) DEFAULT NULL COMMENT '性別',
  `age` int(10) DEFAULT NULL COMMENT '年齡',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='測試utf8問題重現'

這里我們直接指定了nickname字段的字符編碼為utf8,然后我向里面插入一條普通數據,使用mybatis的插入數據庫語句如下:

INSERT INTO  `user` ( `nickname`, `sex`, `age`) VALUES ( '張三', '男', '18');

n3jFld.png

的確是像我們平時操作一樣插入成功了,似乎沒有什么問題,但這里我們再測試一下昵稱中帶有表情符(emoji)的數據嘗試一下:

張三 An 😀awesome 😃string 😄with a few 😉emojis!

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x80aw...' for column 'nickname' at row 1

這個時候報的錯誤就很明顯是指的這個表情符無法存入該字段,那為什么emoji無法存入utf8編碼的字段呢,這又是怎么回事呢?

2.Mysql遺留問題

這個問題的症結在於,Mysql的"utf8"並不是真正的UTF-8.

“utf8”只支持每個字符三個字節,而真正的 UTF-8 是每個字符最多四字節,MySQL 一直沒有修復這個 bug,他們在 2010 年發布了一個叫作“utf8mb4”的字符集,繞過了這個問題,但為什么沒有修復"utf8"問題?具體原因不詳.

簡單歸納綜合如下:
MySQL 的“utf8mb4”是真正的“UTF-8”,MySQL 的“utf8”是一種“專屬的編碼”,它能夠編碼的 Unicode 字符其實不多,所以在使用mysql的時候還是用"utf8mb4"的編碼集恰當!


免責聲明!

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



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