2017-06-21 85 views
1

我將一個MySQL數據庫移植到SQLite中,並且遇到SQLite允許重複值的問題。SQLite多列唯一約束允許重複

CREATE TABLE altnames (
    Prime  CHAR (20), 
    Alternate CHAR (20), 
    UNIQUE (Prime, Alternate) 
); 

CREATE INDEX prime  ON altnames (Prime ); 
CREATE INDEX alternate ON altnames (Alternate); 

CREATE UNIQUE INDEX Combined ON altnames (
    Prime, 
    Alternate 
); 

我使用HeidiSQL導出爲CSV,並從那裏使用SQLiteStudio導入。它會捕獲我手動輸入的值的重複值,但是一旦我從MySQL表中導入數據,它就不會捕獲這些值的重複值。

該表的目的是鏈接各種形式的名稱。一些樣本數據:

"Al","Alan" 
"Al","Albert" 
"Al","Alfred" 
"Al","Allan" 
"Al","Allen" 
"Al","Alvin" 
"Alan","Al" 
"Alan","Allan" 
"Alan","Allen" 
"Albert","Al" 
"Albert","Bert" 
"Albert","Bertie" 
"Alfred","Al" 
"Alfred","Fred" 
"Alfred","Freddie" 
"Alfred","Freddy" 
"Allan","Al" 
"Allan","Alan" 
"Allan","Allen" 
"Allen","Al" 
"Allen","Alan" 
"Allen","Allan" 

如果我通過SQLiteStudio接口或編程添加這些項目中,約束被觸發,但如果我導入,插入這些值不會觸發它。例如,insert into altnames values ('Al', 'Alan')會成功,給我兩行這些值。

編輯:

我發現了一些相當奇怪的行爲。根據the documentationON CONFLICT的默認行爲是ABORT,這應該會生成SQLITE_CONSTRAINT錯誤並回滾衝突的數據。我發現,如果我從CSV文件導入數據,它會進行回滾,但不會生成錯誤。如果我包含ON CONFLICT子句,它將執行回滾並生成錯誤。 然而,而不是CSV,如果我的數據導出爲SQL:

INSERT INTO `altnames` (`Prime`, `Alternate`) VALUES 
    ('Al', 'Alan'), 
    ('Al', 'Albert'), 
    ('Al', 'Alfred'), 
    ('Al', 'Allan'), 
    ...... 

並導入這樣...然後我得到了記錄的行爲,不管我是否指定ON CONFLICT

+0

你並不需要的最後一個索引; UNIQUE約束已經創建了一個內部約束。無論如何,展示一個例子。 –

+0

@CL。但是索引不會加速約束檢查嗎?或者,如果有'UNIQUE'約束,它會自動編入索引嗎? – alanlittle

+0

UNIQUE約束已經創建了一個內部索引。顯示一個失敗數據的例子。 –

回答

0

使用sqlite3的命令行工具來打開數據庫文件,然後執行:

CREATE TEMP TABLE import(prime, alternate); 
.sep ',' 
.import tabledata.csv import 
INSERT OR IGNORE INTO altnames SELECT * FROM import;