1. 程式人生 > 其它 >MySQL查詢關於區分字母大小寫問題

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效率較低,但是查詢精準度更高一些,詳情點選這裡(其實我也不懂)


作者多數為原創文章 ( 部分轉載已標出 ),目前資歷尚淺文章內描述可能有誤,對此造成的後果深表歉意,如有錯誤還望指正