MySQL Charset--UTF8和UTF8MB4对比测试

UTF8和UTF8MB4

在早期MySQL版本中,使用只支持最长三字节的UTF8字符集便可以存放所有Unicode字符。随着Unicode的完善,Unicode字符集收录的字符数量越来越多,最新版本的UTF8需要使用1到4个字节来存放Unicode字符,而MySQL为保持版本兼容,依旧使用最多3字节的UTF8字符集,并在MySQL 5.5.3版本引入UTF8MB4字符集来支持4字节的Unicode字符。

汉字 '?' 和 ' ? ' 是异体字,读音均为xi,但两个字的unicode不同:

? 对应的UNICODE是 \ud850\udeee; 
? 对应的UTF8是 ��
? 对应的HEX编码是 %f0%a4%8b%ae
熙 对应的UNICODE是 \u7199 
熙 对应的UTF8是
熙
熙 对应的HEX编码是 %e7%86%99

 

在UTF8字符集模式下测试

创建测试表:

CREATE TABLE `tb5001` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT,
  `C1` VARBINARY(100) DEFAULT NULL,
  `C2` VARCHAR(100) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=INNODB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4

在UTF8字符集下测试

SET NAMES utf8;

INSERT INTO TB5001(C1,C2)
SELECT '?','?';
INSERT INTO TB5001(C1,C2)
SELECT '','';

SELECT * FROM TB5001;

执行第一条INSERT有警告,警告信息为:

Warning Code : 1300
Invalid utf8 character string: 'F0A48B'

Warning Code : 1366
Incorrect string value: '\xF0\xA4\x8B\xAE' for column 'C2' at row 1

查询结果为:

在UTF8字符集下,VARCHAR类型"无法支持“四字节的"?",但VARBINARY不受字符集影响。

 

在UTF8MB4字符集模式下测试

测试脚本

SET NAMES utf8mb4;

INSERT INTO TB5001(C1,C2)
SELECT '?','?';

INSERT INTO TB5001(C1,C2)
SELECT '','';

SELECT * FROM TB5001;

测试中无任何警告,查询结果:

在UTF8MB4字符集下,VARCHAR类型"完美支持“四字节的"?",但VARBINARY不受字符集影响。

 

乱码问题

表TB5001字符集已定义为UTF8MB4,表上C1列的字符集也是UTF8MB4,为啥还出现乱码呢?

测试脚本:

SET NAMES utf8;
SELECT * FROM TB5001;

SET NAMES utf8mb4;
SELECT * FROM TB5001;

测试对比图:

虽然表上C1列的字符集是UTF8MB4,能存放4字节的字符,但:

1、对于ID=33的记录,由于在插入时使用UTF8字符集,在插入到C1列前'?'字已经发生乱码,存储到C1列中数据也是乱码,因此无论读取时使用UTF8还是UTF8MB4都是乱码。

2、对于ID-35的记录,由于在插入时使用UTF8MB4字符集,插入C1列前和存储到C1中都正常,在读取时使用UTF8MB4能正常读取,但在读取使用UTF8是乱码。

 

SET NAMES x相当于执行下面三条语句:

SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;

要保证数据库正常存储4字节的表情符合生僻字,除将数据库相关表和列设置为UTF8MB4外,还需要确保操作数据库时使用UTF8MB4,需重点关注以下几个方面:

1、数据库启动配置参数

2、应用与数据库连接配置

3、DBA日常运维操作

如DBA操作过程中,使用mysql客户端连接到数据库执行操作,而mysql客户端可能使用默认UTF8字符集(default-character-set),导出乱码问题。

 

在xshell工具下粘贴下面代码:

SELECT '?','?';
SELECT '','';

将代码粘贴到vim工具中自动变为:

SELECT '<d850><deee>','<d850><deee>';
SELECT '','';

将代码粘贴到mysql命令总变为:

因此建议DBA在日常运维中关注生僻字和表情符,避免异常。

 

 

参考:http://seanlook.com/2016/10/23/mysql-utf8mb4/

 

转载于:https://www.cnblogs.com/gaogao67/p/11356558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值