mysql 取出最后一个字符_MySQL一个字符集转换的骚操作,酿下性能的苦果

这是学习笔记的第 2275篇文章

990156d8fe71af2b8cde379ced51fa0c.gif

今天处理了一个RDS的问题,突然想起了好几年前处理的一个性能案例,看似不经意的细节竟然让我对整个问题的过程有了更清晰的认识。

整个细节可以参见我写的这篇文章的处理过程:

力荐:一条update语句引发的“血案”

当时有一个地方没有想明白,那就是里面的字段APNS_PUSH_ID为什么字符集会是latin1,而表的字符集却妥妥的是UTF8,看起来是一个不大可能出现的场景。

c88139d9aeb99123133d02433076b9c6.png

下午在协助处理一个问题的时候,才突然明白,我来复现下这个问题。

创建一张表test_charset,设置字符集为latin1

mysql> create table test_charset(id int primary key,name varchar(30),memo varchar(30)) charset=latin1;Query OK, 0 rows affected (0.12 sec)

查看表结构,可以清晰的看到,字段是共享了表的默认字符集,没有显式显示出来。

mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) DEFAULT , `memo` varchar(30) DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.01 sec)

我们使用如下的语句来变更下表的字符集。

mysql> alter table test_charset charset=utf8;Query OK, 0 rows affected (0.05 sec)Records: 0 Duplicates: 0 Warnings: 0

这个时候再次查看就会发现,原本“继承”的latin1字符集现在显式显示出来了,表的字符集是utf8,但是字符类型的字段字符集依然是latin1

mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) CHARACTER SET latin1 DEFAULT , `memo` varchar(30) CHARACTER SET latin1 DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)

如果后续再添加字段,不显式指定字符集。

mysql> alter table test_charset add memo2 varchar(30);Query OK, 0 rows affected (0.14 sec)Records: 0 Duplicates: 0 Warnings: 0

查看表结构会发现,新字段memo2的字符集就会是utf8

mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) CHARACTER SET latin1 DEFAULT , `memo` varchar(30) CHARACTER SET latin1 DEFAULT , `memo2` varchar(30) DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)

好了,问题到了这里就相对有了一个思路。

那么产生最开始让人疑惑的问题原因是什么呢?就是哪个骚操作:

mysql> alter table test_charset charset=utf8;

这是一个表级属性的变更,注意MySQL里面字段,表,数据库都可以存在差异化的字符集设置。虽然可以支持,但是显然这样做是不合理的。

而如果要让字段的变更同时生效,应该使用convert to 语句,我们为了突出变化,改为utf8mb4字符集。

mysql> alter table test_charset convert to charset utf8mb4; Query OK, 0 rows affected (0.13 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> show create table test_charsetG*************************** 1. row *************************** Table: test_charsetCreate Table: CREATE TABLE `test_charset` ( `id` int(11) NOT , `name` varchar(30) DEFAULT , `memo` varchar(30) DEFAULT , `memo2` varchar(30) DEFAULT , PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb41 row in set (0.00 sec)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值