今天答應準時回家和老婆一起吃晚飯,但臨時有事加了會班,回家晚了點
回到家,本以為老婆會很生氣,但老婆卻立即從廚房端出了熱著的飯菜
(資料圖片僅供參考)
老婆:還沒吃飯吧,去洗下,來吃飯吧
我洗好,坐下吃飯,內(nèi)心感動十分;老婆坐旁邊深情的看著我
老婆:你知道誰最愛你嗎
我毫不猶豫道:你
老婆:誰最關(guān)心你?
我:你
老婆:我是誰呀?
我:我老婆
老婆:那你以后是不是得對我好點?
這時電話響了,一看好哥們打過來的,我接了并開了免提
哥們:樓下洗浴八折,干啥呢?
我:那個......,在陪我前妻吃口飯
問題背景一天,小伙伴找到我,他說他碰到一個很奇怪的問題
他說:明明表名的入?yún)⑹莟est ,為什么展示到界面的記錄包括test這條記錄?
他補充道:會不會是MyBatis-Plus做了什么騷操作,把test 末尾的空格給拿掉了
我:你直接把SQL語句到MySQL執(zhí)行下試試
結(jié)果如下:
這看起來不夠直觀,我移動下光標
然后我和小伙伴面面相覷
環(huán)境準備MySQL5、MySQL8各準備一個
我們來看下默認情況下,末尾空白的判斷情況
MySQL 5.7.36如下
1 表示TRUE,也就是相等
MySQL 8.0.27如下
0 表示FALSE,表示不相等
這是什么原因,我們繼續(xù)往下看
字符集與字符序比較肯定就需要比較規(guī)則,SQL的比較規(guī)則就離不開字符序,字符序又與字符集相關(guān),所以我們一個一個來捋
字符集關(guān)于字符集,不是只言片語可以說清楚的,但是大家也不用擔心,網(wǎng)上相關(guān)資料已經(jīng)非常多,大家擦亮慧眼去查閱即可
簡單點來說:字符集定義了字符和字符的編碼
有人又問了:字符、字符的編碼又是什么?
為了方便大家理解,舉個簡單栗子
有四個字符:A、B、C、D,這四個字符的編碼分別是 A = 0, B = 1, C = 2, D = 3
這里的字符(A、B、C、D) + 編碼(0、1、2、3)就構(gòu)成了字符集(character set)
MySQL支持的字符集有很多,可以通過SHOW CHARACTER SET;查看
Charset:字符集名
Description:描述
Default collation:默認字符序
Maxlen:每個字符最多字節(jié)數(shù)
字符序定義了字符的比較規(guī)則;字符間的比較按何種規(guī)則進行
一個字符集對應多個字符序,通過SHOW COLLATION;可以查看全部的字符序;也可以帶條件查具體某個字符集的字符序
Default等于Yes表示是默認字符序
每個字符集都有默認的字符序
server的字符集與字符序當我們創(chuàng)建數(shù)據(jù)庫時,沒有指定字符集、字符序,那么server字符集、server字符序就會作為該數(shù)據(jù)庫的字符集、字符序
database的字符集與字符序指定數(shù)據(jù)庫級別的字符集、字符序
同一個MySQL服務下的數(shù)據(jù)庫,可以分別指定不同的字符集、字符序
創(chuàng)建、修改數(shù)據(jù)庫的時候,可以通過CHARACTER SET、COLLATE指定數(shù)據(jù)庫的字符集、字符序
可以通過
查看數(shù)據(jù)庫的字符集和字符序
table的字符集與字符序創(chuàng)建、修改表的時候,可以通過CHARACTER SET、COLLATE指定表的字符集、字符序
可以通過
查看表的字符序
column的字符集與字符序類型為CHAR、VARCHAR、TEXT的列,可以指定字符集、字符序
可以通過
查看字段的字符集和字符序
多個維度指定字符集、字符序的話,粒度越細的優(yōu)先級越高(column>table>database>server)
如果細粒度未指定字符集、字符序,那么會繼承上一級的字符集,字符序則是上一級字符集的默認字符序
通常情況下我們一般不會指定table、column粒度的字符集、字符序
也就是說,通常情況下column的字符集會與database的字符集一致,而column的字符序則是database字符集的默認字符序
空白丟失上面講了那么多,跟空白丟失有什么關(guān)系?
大家先莫急,繼續(xù)往下看
MySQL5.7The CHAR and VARCHAR Types中有這么一段
翻譯過來就是:
1、類型是CHAR、VARCHAR、TEXT列的值,會根據(jù)列的字符序來比較和排序
2、所有MySQL排序規(guī)則的類型都是PAD SPACE。這就意味著,CHAR、VARCHAR、TEXT類型的值進行比較時,不用考慮任何末尾空格,LIKE除外
3、不受SQL mode影響,也就是說不管是嚴格模式,還是非嚴格模式,都不影響 2 所說的規(guī)則
劃重點,記筆記:在MySQL5.7及以下(<=5.7)版本中,排序規(guī)則都是PAD SPACE,末尾的空格會忽略不考慮
那如何讓末尾空格參與比較了,有三種處理方式
1、BINARY,類似SELECT "test" = BINARY "test ";
2、LIKE,類似SELECT "test" LIKE "test ";
3、LENGTH函數(shù),類似
MySQL8做了調(diào)整,The CHAR and VARCHAR Types 有如下說明
翻譯過來就是:
1、類型是CHAR、VARCHAR、TEXT列的值,會根據(jù)列的字符序來比較和排序
2、MySQL字符序的pad參數(shù)的可選值,除了PAD SPACE,還增加了NO PAD
3、對于非二進制字符串(CHAR、VARCHAR、TEXT),字符序pad參數(shù)決定如何去處理字符串末尾的空格
NO PAD不會忽略末尾空格,會將其當做其他字符一樣對待
PAD SPACE會忽略末尾空格,LIKE除外
SQL mode不參與字符串末尾空格的處理
MySQL8server 維度的字符集是utf8mb4,對應的默認字符序是:utf8mb4_0900_ai_ci
Pad_attribute的值是NO PAD,也就是不會忽略字符串末尾的空格
所以在MySQL8中,SELECT "test" = "test ";默認情況下得到的結(jié)果是 0
總結(jié)1、非二進制字符串(CHAR、VARCHAR、TEXT)比較時,末尾空格的處理跟列的字符序有直接關(guān)系
2、MySQL5.7及之前的版本,排序規(guī)則的類型都是PAD SPACE,會忽略字符串末尾的空格,LIKE除外
3、MySQL8開始,字符序增加了一個參數(shù)Pad_attribute,該參數(shù)的值不同,對字符串末尾空格的處理方式不同
NO PAD:字符串末尾的空格會和其他字符一樣,不會被忽略
PAD SPACE:字符串末尾的空格會被忽略,LIKE除外
4、如上針對的都是非二進制字符串的排序和比較,而不是儲存
參考The CHAR and VARCHAR Types
The CHAR and VARCHAR Types
再見亂碼:5分鐘讀懂MySQL字符集設置
關(guān)鍵詞: