这是学习笔记的第 2275篇文章
今天处理了一个RDS的问题,突然想起了好几年前处理的一个性能案例,看似不经意的细节竟然让我对整个问题的过程有了更清晰的认识。
整个细节可以参见我写的这篇文章的处理过程:
力荐:一条update语句引发的“血案”
当时有一个地方没有想明白,那就是里面的字段APNS_PUSH_ID为什么字符集会是latin1,而表的字符集却妥妥的是UTF8,看起来是一个不大可能出现的场景。
下午在协助处理一个问题的时候,才突然明白,我来复现下这个问题。
创建一张表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_charset
Create Table: CREATE TABLE `test_charset` (
`id` int(11) NOT ,
`name` varchar(30) DEFAULT ,
`memo` varchar(30) DEFAULT ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 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_charset
Create 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=utf8
1 row in set (0.00 sec)
如果后续再添加字段mysql替换字段中的部分字符,不显式指定字符集。
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_charset
Create 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=utf8
1 row in set (0.00 sec)
好了,问题到了这里就相对有了一个思路。
那么产生最开始让人疑惑的问题原因是什么呢?就是哪个骚操作:
mysql> alter table test_charset charset=utf8;
这是一个表级属性的变更,注意MySQL里面字段,表,数据库都可以存在差异化的字符集设置。虽然可以支持,但是显然这样做是不合理的。
而如果要让字段的变更同时生效,应该使用convert to 语句,我们为了突出变化mysql替换字段中的部分字符,改为utf8mb4字符集。
mysql> alter table test_charset convert to charset utf8mb4;
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table test_charsetG
*************************** 1. row ***************************
Table: test_charset
Create 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=utf8mb4
1 row in set (0.00 sec)
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。