項目去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關鍵字來強制檢測空格