MYSQL中的空格及大小寫問題

項目去O,有同窗反映oracle中的數據導入到mysql中不對了,背景是oracle中的數據存在空格敏感字段,好比oracle中123,空格123,123空格就是3個不一樣的數據,符合惟一約束。而mysql則認爲存在相同的數據 mysql

另外對於oracle來講,大小寫是敏感的,而mysql則不是,好比ABC,abc在oracle老是兩條數據,而在mysql中默認是不符合惟一約束的 sql

就以上兩個問題咱們分別來看一下,第一是大小寫的問題 shell

ORACLE中建表TTT,插入兩條大小寫的數據 oracle

INSERT INTO TTT VALUES (1,'name1');
INSERT INTO TTT VALUES (2,'NAME1');
SELECT DISTINCT("name") from TTT;
結果是:

NAME1
name1

一樣的操做在mysql中直接結果以下: code

INSERT INTO ttttt VALUES (1,'name1');
INSERT INTO ttttt VALUES (2,'NAME1');

SELECT DISTINCT(`name`) from ttttt;
返回的結果爲:

name1
也就是是說mysql默認是大小寫不敏感的,下面我來看下mysql中關於大小寫敏感的成熟的解決方案:

ALTER TABLE `TTTTT`
MODIFY COLUMN `name`  varchar(64) CHARACTER SET gbk COLLATE gbk_bin NULL DEFAULT NULL AFTER `id`;
再次在mysql中執行

SELECT DISTINCT(`name`) from ttttt;
name1
NAME1
結果OK.所作的操做就是把字符集和排序規則改了一下

第二個問題就是mysql中的空格問題 排序

先在oracle中執行 class

INSERT INTO TTT VALUES (1,'name1');
INSERT INTO TTT VALUES (2,' name1');
INSERT INTO TTT VALUES (3,'name1 ');
INSERT INTO TTT VALUES (4,' name1 ');
SELECT DISTINCT("name") FROM TTT
所得的結果爲:

name1
 name1
 name1 
name1
也就是說oracle中name1,空格name1,空格name1空格,name1空格是4種不一樣的數據

分別對應下他們的長度: im

SELECT "LENGTH"("name") FROM TTT
5
6
6
7
接下來一樣的操做在msyql中執行一下:

SELECT DISTINCT(`name`) from ttttt
執行結果以下:

name1
 name1
也就是說mysql會把name1,name1空格合併,空格name1,空格name1空格合併,即在作distinct的時候其實mysql作了一次righttrim,即去掉右邊的空格

那麼在存儲的時候mysql也作了這樣的操做麼?即只存righttrim後結果? 總結

SELECT LENGTH(`name`) from ttttt
5
6
6
7
從上面的結果來看,空格的長度是包含在其中的。

那麼咱們能夠多作幾個實驗,distinct的時候mysql有作righttrim,那麼查詢的時候是否有相似操做呢?另外若是自己是惟一鍵的時候判斷惟一的時候是否也會作righttrim呢? 數據

首先是查詢的時候

SELECT * from ttttt where `name` ='name1'
1	name1
3	name1
結果是mysql認爲name1和name1空格是同樣的

那麼惟一約束的時候是否會作一樣的操做呢?

ALTER TABLE `TTTTT`
ADD UNIQUE INDEX `uniname` (`name`) ;
清空表再從新插入

INSERT INTO ttttt VALUES (1,'name1');
INSERT INTO ttttt VALUES (2,' name1');
INSERT INTO ttttt VALUES (3,'name1 ');
INSERT INTO ttttt VALUES (4,' name1 ');
[SQL] INSERT INTO ttttt VALUES (1,'name1');
受影響的行: 1
時間: 0.074ms
[SQL] 
INSERT INTO ttttt VALUES (2,' name1');
受影響的行: 1
時間: 0.071ms
[SQL] 
INSERT INTO ttttt VALUES (3,'name1 ');
[Err] 1062 - Duplicate entry 'name1 ' for key 'uniname'
從結果能夠看出來,仍是會認爲後置空格是同樣的。

那麼這個問題在mysql怎麼解決呢?解決方案是在字段前加一個binary關鍵字

SELECT DISTINCT(BINARY `name`) from ttttt
查詢結果以下:

name1
 name1
name1 
 name1

也就是說mysql解決了空格的識別問題,會認爲後置空格是不一樣的數據,這點也很容易理解,由於以前咱們看各個字段的length的時候發現了其實各個數據的length仍是不同的

總結一下,mysql中的空格處理及大小寫的處理和oralce仍是有很大的差異的,對於mysql中的大小寫問題咱們能夠設置排序規則,而mysql的後置空格問題咱們可使用binary關鍵字來強制檢測空格

相關文章
相關標籤/搜索