成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

什么?MySQL的等值查詢竟然出錯了?

數據庫 新聞
? 認知有界,而求知無界。

1.問題背景

前段時間,一個業務線的小伙伴大G找過來,如下是我倆的對話。

大G:云杰,聽說你MySQL挺厲害的,我最近遇到一個奇怪問題,不知道你遇到過沒,請教你下。

我:請教不敢當,我也就是個MySQL入門級選手,說來看看。

大G:WHERE條件去等值查詢字符串,結果卻查出來幾條尾部有空格的,明明不相等。

我:不會吧?這么神奇,這個真沒遇到過!

大G:不信你試試!

我:試試就試試!

抱著求知的心態,開啟了本篇的探索之旅。

2.驗證

2.1 數據準備

首先在測試庫里建表,并準備相關的原數據。創建個user_info表,分別插入'adu'(無空格)、'adu '(一個空格)、'adu    '(四個空格)三個用戶。

CREATE TABLE `user_info` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵自增ID',
`user_name` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '名字',

PRIMARY KEY (`id`),
KEY `idx_user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';

INSERT INTO user_info(user_name) values('adu'); #無空格
INSERT INTO user_info(user_name) values('adu '); #一個空格
INSERT INTO user_info(user_name) values('adu '); #四個空格

2.2 問題驗證

2.2.1 尾部空格驗證

SELECT * FROM user_info WHERE user_name = 'adu'; #無空格
SELECT * FROM user_info WHERE user_name = 'adu '; #一個空格
SELECT * FROM user_info WHERE user_name = 'adu '; #兩個空格
SELECT * FROM user_info WHERE user_name = 'adu '; #四個空格

我們使用如上條件去查,還真復現了!無論查詢中尾部帶有幾個空格,結果是一樣的,都會命中'adu'、'adu '、'adu    '三個用戶,結果如下圖所示(紅框圈起來的表示我們認為不應該出現的異常結果):

圖片

太神奇了!

2.2.2 頭部空格驗證

那如果把空格放在前面呢?再來一把,結果如下:圖片這下又匹配不上了。空格放在后邊可以,放在前邊不可以,這太神奇了!!

2.2.3 唯一索引驗證

那如果在user_name字段上建唯一索引,還能插入這三條記錄嗎?再來一把,結果如下:

圖片

也不行,被唯一索引約束住了。

2.2.4 長度驗證

那這三條記錄的user_name長度又分別是多少呢?

圖片

確實長度也不一樣。

2.3 驗證小結

從結果上來看,明明是三個長度不同的字符串,空格放在前邊被認為是不同,放在后邊又被認為是相同,而且唯一索引也沖突。我們有充足的理由懷疑MySQL忽略字符串尾部的空格,把'adu'、'adu '、'adu    '都當成'adu'來處理。這確實超出了已有的認知,那背后的原因究竟又是什么呢?

3.分析原因

查詢MySQL的官方文檔[1],原來跟字符串的校對規則有關。

圖片

原來MySQL的校對規則基于PAD SPACE,這就意味著CHAR、VARCHAR、TEXT等字符串的等值比較(“=”)會忽略掉尾部的空格,而且官網也說了,適用于所有MySQL版本,并且不會改變。這。。。

既然MySQL官網說的這么肯定,那么自信來自哪里呢?我們繼續追查SQL規范,原來SQL規范還真對這塊做了特別說明[2],如下所示:

圖片

既然規范都這樣要求了,等值查詢“=”不能精確查詢,那么到底該如何精確地進行等值查詢呢?

4.精確查詢的方法

通過調研,我們可以通過以下兩種方式進行精確等值查詢。

4.1 LIKE

LIKE是基于逐個字符進行比較的,這樣就不會忽略尾部的空格,官網對這塊也有特別的說明。

圖片

那么我們再使用LIKE進行等值查詢,結果還真可以!

圖片

4.2 BINARY

BINARY不是函數,是類型轉換運算符,它用來強制它后面的字符串轉為二進制字節,再逐個字節比較,也可以理解成精確匹配,官網[4]對這塊也有特別的說明。

圖片

那么我們再使用BINARY進行等值查詢,結果也是可以的。

圖片

5.總結

  • MySQL的CHAR、VARCHAR、TEXT等字符串字段在等值比較("=")時,基于PAD SPACE校對規則,會忽略掉尾部的空格;
  • 在存儲時,不會自動截斷尾部的空格,會按原值存儲;
  • 如果想要精確查詢就不能用等值查詢("="),而應改用LIKE或BINARY;
  • 認知有界,而求知無界。

關于作者

杜云杰,高級架構師,轉轉架構部負責人,轉轉技術委員會執行主席,騰訊云TVP。負責服務治理、MQ、云平臺、APM、IM、分布式調用鏈路追蹤、監控系統、配置中心、分布式任務調度平臺、分布式ID生成器、分布式鎖等基礎組件。

道阻且長,擁抱變化;而困而知,且勉且行。

責任編輯:張燕妮 來源: 轉轉技術
相關推薦

2024-01-04 08:12:12

IDE代碼出錯ChatGPT

2014-07-03 14:04:55

Bug報告Bug

2012-05-18 13:23:02

iPhone 4S

2015-12-07 14:11:01

2020-04-07 11:15:03

Zoom加密網絡安全

2024-12-02 08:01:47

加鎖高并發程序

2010-05-12 18:10:26

MySQL出錯代碼

2021-08-16 12:32:37

HashMap八股文面試

2015-07-20 15:26:56

WiFi感知

2022-05-30 07:57:06

密態等值查詢數據庫

2011-05-16 10:16:19

MYSQL出錯代碼

2022-02-24 07:48:47

MySQL索引查詢

2024-01-08 08:23:07

Go語言代碼

2021-05-08 15:41:06

計算機互聯網 技術

2019-06-26 10:16:52

微軟Windows谷歌

2023-06-13 10:01:48

SpringOpenFeign

2022-03-21 08:07:21

計費系統開發

2020-07-06 14:16:22

Fastjson漏洞開源

2010-05-13 11:05:56

2019-10-23 08:45:34

SQL數據庫開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩精品在线一区 | 中文精品视频 | 久久免费精品视频 | www.日韩 | 精品国产鲁一鲁一区二区张丽 | av 一区二区三区 | 一级二级三级在线观看 | 一区二区在线 | 国产国产精品久久久久 | 日韩一区二区在线播放 | 福利一区在线观看 | 91精品国产综合久久精品 | 国产精品成人一区二区三区夜夜夜 | 国产在线一区二区三区 | 精品成人免费一区二区在线播放 | 亚洲一区 中文字幕 | 欧美极品在线 | 精品少妇一区二区三区日产乱码 | 亚洲视频二 | 天天操操 | 成人在线视频一区 | 国产大片黄色 | av大片在线观看 | 97伦理影院 | 成人在线免费看 | 国产重口老太伦 | 国产成年人小视频 | 黑人一级片视频 | 欧美日韩精品一区二区三区蜜桃 | 夜夜夜夜夜夜曰天天天 | 中文字幕一区二区三区不卡 | 精品免费视频 | 免费黄视频网站 | 欧美激情精品久久久久久变态 | 男女羞羞视频在线免费观看 | 成人二区| 久久久久久国产免费视网址 | 热久久性| 久久精品二区亚洲w码 | 日韩av一区二区在线观看 | 亚洲+变态+欧美+另类+精品 |