今天答應準時回家和老婆一起吃晚飯,但臨時有事加了會班,回家晚了點
回到家,本以為老婆會很生氣,但老婆卻立即從廚房端出了熱著的飯菜
老婆:還沒吃飯吧,去洗下,來吃飯吧
我洗好,坐下吃飯,內心感動十分;老婆坐旁邊深情的看著我
老婆:你知道誰最愛你嗎
我毫不猶豫道:你
老婆:誰最關心你?
我:你
老婆:我是誰呀?
我:我老婆
老婆:那你以後是不是得對我好點?
這時電話響了,一看好哥們打過來的,我接了並開了擴音
哥們:樓下洗浴八折,幹啥呢?
我:那個......,在陪我前妻吃口飯
一天,小夥伴找到我,他說他碰到一個很奇怪的問題
他說:明明表名的入參是 test ,為什麼展示到介面的記錄包括 test 這條記錄?
他補充道:會不會是 MyBatis-Plus 做了什麼騷操作,把 test 末尾的空格給拿掉了
我:你直接把 SQL 語句到 MySQL 執行下試試
結果如下:
這看起來不夠直觀,我移動下游標
然後我和小夥伴面面相覷
我們來看下預設情況下,末尾空白的判斷情況
MySQL 5.7.36 如下
1 表示 TRUE ,也就是相等
MySQL 8.0.27 如下
0 表示 FALSE ,表示不相等
這是什麼原因,我們繼續往下看
比較肯定就需要比較規則, SQL 的比較規則就離不開字元序,字元序又與字元集相關,所以我們一個一個來捋
關於字元集,不是隻言片語可以說清楚的,但是大家也不用擔心,網上相關資料已經非常多,大家擦亮慧眼去查閱即可
簡單點來說:字元集定義了字元和字元的編碼
有人又問了:字元、字元的編碼又是什麼?
Charset :字元集名
Description :描述
Default collation :預設字元序
Maxlen :每個字元最多位元組數
定義了字元的比較規則;字元間的比較按何種規則進行
一個字元集對應多個字元序,通過 SHOW COLLATION; 可以檢視全部的字元序;也可以帶條件查具體某個字元集的字元序
Default 等於 Yes 表示是預設字元序
每個字元集都有預設的字元序
當我們建立資料庫時,沒有指定字元集、字元序,那麼server字元集、server字元序就會作為該資料庫的字元集、字元序
指定資料庫級別的字元集、字元序
同一個MySQL服務下的資料庫,可以分別指定不同的字元集、字元序
建立、修改資料庫的時候,可以通過 CHARACTER SET 、 COLLATE 指定資料庫的字元集、字元序
可以通過
檢視資料庫的字元集和字元序
建立、修改表的時候,可以通過 CHARACTER SET 、 COLLATE 指定表的字元集、字元序
可以通過
檢視表的字元序
型別為 CHAR 、 VARCHAR 、 TEXT 的列,可以指定字元集、字元序
可以通過
檢視欄位的字元集和字元序
多個維度指定字元集、字元序的話,粒度越細的優先順序越高( column > table > database > server )
如果細粒度未指定字元集、字元序,那麼會繼承上一級的字元集,字元序則是上一級字元集的預設字元序
通常情況下我們一般不會指定 table 、 column 粒度的字元集、字元序
也就是說,通常情況下 column 的字元集會與 database 的字元集一致,而 column 的字元序則是 database 字元集的預設字元序
上面講了那麼多,跟空白丟失有什麼關係?
大家先莫急,繼續往下看
MySQL5.7 The CHAR and VARCHAR Types中有這麼一段
翻譯過來就是:
1、型別是 CHAR 、 VARCHAR 、 TEXT 列的值,會根據列的字元序來比較和排序
2、所有 MySQL 排序規則的型別都是 PAD SPACE 。這就意味著, CHAR 、 VARCHAR 、 TEXT 型別的值進行比較時,不用考慮任何末尾空格,LIKE 除外
3、不受 SQL mode 影響,也就是說不管是嚴格模式,還是非嚴格模式,都不影響 2 所說的規則
劃重點,記筆記:在 MySQL5.7 及以下( <=5.7 )版本中,排序規則都是 PAD SPACE ,末尾的空格會忽略不考慮
那如何讓末尾空格參與比較了,有三種處理方式
1、 BINARY ,類似 SELECT 'test' = BINARY 'test ';
2、 LIKE ,類似 SELECT 'test' LIKE 'test ';
3、 LENGTH 函數,類似
MySQL8 做了調整,The CHAR and VARCHAR Types 有如下說明
翻譯過來就是:
1、型別是 CHAR 、 VARCHAR 、 TEXT 列的值,會根據列的字元序來比較和排序
2、 MySQL 字元序的 pad 引數的可選值,除了 PAD SPACE ,還增加了 NO PAD
3、對於非二進位制字串( CHAR 、 VARCHAR 、 TEXT ),字元序 pad 引數決定如何去處理字串末尾的空格
NO PAD 不會忽略末尾空格,會將其當做其他字元一樣對待
PAD SPACE 會忽略末尾空格, LIKE 除外
SQL mode 不參與字串末尾空格的處理
MySQL8 server 維度的字元集是 utf8mb4 ,對應的預設字元序是: utf8mb4_0900_ai_ci
Pad_attribute 的值是 NO PAD ,也就是不會忽略字串末尾的空格
所以在 MySQL8 中, SELECT 'test' = 'test '; 預設情況下得到的結果是 0
1、非二進位制字串( CHAR 、 VARCHAR 、 TEXT )比較時,末尾空格的處理跟列的字元序有直接關係
2、 MySQL5.7 及之前的版本,排序規則的型別都是 PAD SPACE ,會忽略字串末尾的空格, LIKE 除外
3、 MySQL8 開始,字元序增加了一個引數 Pad_attribute ,該引數的值不同,對字串末尾空格的處理方式不同
NO PAD :字串末尾的空格會和其他字元一樣,不會被忽略
PAD SPACE :字串末尾的空格會被忽略, LIKE 除外
4、如上針對的都是非二進位制字串的排序和比較,而不是儲存