mysql 取出最後一個字元_MySQL一個字符集轉換的騷操作,釀下效能的苦果
阿新 • • 發佈:2021-02-14
技術標籤:mysql 取出最後一個字元
這是學習筆記的第 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> 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 語句,我們為了突出變化,改為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)