MySQL 5.7升8.0后latin1转utf8mb4报Incorrect string value错误
问题原因分析
这个错误的核心是编码格式不匹配,具体拆解:
- 在MySQL 5.7的latin1字符集下,
ó对应的单字节是0xF3——latin1是单字节编码,任何字节值都能直接对应一个字符,所以存储毫无问题。 - 你把列转成VARBINARY时,只是把原来的字节序列(包括
0xF3)原封不动存了下来,没有做任何编码转换。 - 当你再转回VARCHAR(utf8mb4)时,MySQL会把这些字节当成utf8mb4编码的字节序列去解析,但utf8mb4的编码规则里,
0xF3是四字节字符的起始标记,需要后面跟3个合法的续写字节才是有效编码。而你的数据里0xF3后面跟着的是n(0x6E)等普通ASCII字节,完全不符合utf8mb4的编码规范,所以MySQL判定这是无效字符串,抛出错误。
简单说:你把latin1编码的字节直接丢给utf8mb4去解码,自然会失败——就像把中文拼音当成英文单词读,肯定不通。
正确的转换方法
不要用先转VARBINARY的思路,直接通过MySQL的编码转换命令完成:
ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
这个命令会自动把表中所有latin1编码的列,按照“latin1转utf8mb4”的规则完成编码转换,不会出现解码错误。
如果需要单独转换某一列:
ALTER TABLE 表名 MODIFY COLUMN 列名 VARCHAR(长度) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:执行前确保你的MySQL连接的character_set_client和character_set_connection参数是utf8mb4或者latin1(如果是latin1,MySQL会自动识别原编码转成utf8mb4)。
内容的提问来源于stack exchange,提问作者Vitaly Radchik
相关产品推荐
相关产品推荐

