MySQL查詢關於區分字母大小寫問題


前段時間在工作中測試提出了一個BUG,讓我把根據ID查詢區分大小寫的功能去掉,大小寫都隨便查,然后我在SQL的位置加上了UPPER(id) = UPPER(#{id})的寫法,而同事知道這個問題后的反映是"MySQL查詢不是本就不區分大小寫嗎",后來我找機會簡單了解了一下才明白,MySQL區分大小寫取決於數據庫的排序規則,今天在這里記錄一下

一般創建數據庫都會使用utf8編碼,對應兩種常用的排序規則就是utf8_binutf8_general_ci,其中utf8_bin就是區分大小的排序規則,另一個就是不區分大小寫的排序規則,接下來針對排序規則進行一些簡單的測試

注意:本人使用的Navicat客戶端工具,其他客戶端工具可能會對測試結果造成影響(例如SQLyog)

先測試區分大小寫的排序規則

-- 創建區分大小寫的數據庫
CREATE DATABASE test DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

-- 選擇數據庫
USE test;

-- 創建一張測試表
CREATE TABLE aaa (
  id VARCHAR(16),
  PRIMARY KEY(id)
);

-- 插入測試數據
INSERT INTO aaa VALUES('abc');

-- 正常查詢,可以查詢到結果
SELECT id FROM aaa WHERE id = 'abc';

-- 修改大小寫后,查詢不到結果
SELECT id FROM aaa WHERE id = 'abC';

可以看出排序規則為bin的數據庫使用查詢是區分大小寫的,然后再測試一下不區分大小寫的

-- 創建不區分大小寫的數據庫
CREATE DATABASE test2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 選擇數據庫
USE test2;

-- 創建一張測試表
CREATE TABLE aaa (
  id VARCHAR(16),
  PRIMARY KEY(id)
);

-- 插入測試數據
INSERT INTO aaa VALUES('abc');

-- 正常查詢,可以查詢到結果
SELECT id FROM aaa WHERE id = 'abc';

-- 修改大小寫后同樣可以查詢到結果
SELECT id FROM aaa WHERE id = 'abC';

可以看出general_ci是不區分大小寫的,有了結論后我們把test庫修改為不區分大小寫試試看

-- 將數據庫的排序規則修改為utf8_general_ci
ALTER DATABASE test CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 選擇test數據庫
USE test;

-- 再次查詢,還是查詢不到結果
SELECT id FROM aaa WHERE id = 'abC';

這里已經把數據庫的排序規則修改了,怎么還是查不到數據呢?原因是因為直接改庫只對以后創建的表生效,並不會對已存在的表造成影響,這里新建一張表來測試一下

CREATE TABLE bbb (
  id VARCHAR(16),
  PRIMARY KEY(id)
);

INSERT INTO bbb VALUES('bbb');

SELECT id FROM bbb WHERE id = 'bBb';

果然,后續創建的表是不區分大小寫的,接下來需要讓已經創建的表也不區分大小寫,這里直接修改表的排序規則試試

-- 將表的排序規則修改為utf8_general_ci
ALTER TABLE aaa DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 再次查詢,還是查詢不到結果
SELECT id FROM aaa WHERE id = 'abC';

修改表的排序規則不行,那就修改字段(列)的排序規則

-- 將字段的排序規則修改為utf8_general_ci
ALTER TABLE aaa MODIFY id VARCHAR(16) CHARACTER SET utf8 COLLATE utf8_general_ci;

-- 再次查詢,查詢成功!
SELECT id FROM aaa WHERE id = 'abC';

通過測試我們可以知道,排序規則分別有三個生效的作用域,分別是 列、表、庫,而他們之間生效的優先級為列 > 表 > 庫,只要列的排序規則修改成功,表和庫的排序規則對於列來說就不重要了


經過測試了解到如果想要某個字段不區分大小寫查詢,就執行如下SQL修改他的排序規則即可:

ALTER TABLE [表名] MODIFY [字段名] [字段類型] CHARACTER SET utf8 COLLATE utf8_general_ci;

如果表中有大批字段需要修改的話一個一個改很麻煩,可以調用這段SQL修改表以及表中所有字段

ALTER TABLE [表名] CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

擴展

其實除了utf8_general_ci排序規則之外,utf8_unicode_ci同樣不區分大小寫,只不過unicode相對於general效率較低,但是查詢精准度更高一些,詳情點擊這里(其實我也不懂)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM