2017-06-21 88 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;