2012-08-22 71 views
0

我試圖插入一些數據沒有重複,可能來自2+併發進程。插入數據沒有重複

不幸的是,在這種情況下,由於數據庫設計(刪除的行用deleted=1標記,這些可以作爲重複項存在),我不能使用唯一約束。

看來一個簡單的事務將不起作用 - 我能想到的最好的是SELECT ... FOR UPDATE,但這還不夠 - 如果沒有行存在,沒有行將被鎖定,因此它不會阻止插入。另一方面,我想避免鎖定整個桌子來寫作。

有沒有一些很好的方法來解決這個問題?表引擎是InnoDB。 (次要的問題是 - 如何使它在SQLAlchemy的工作,但我可以,如果用普通的工作解決翻譯)

編輯:你可以假設模式:

deleted tinyint(1) default null, 
id int(11) not null auto_increment, 
address varchar(255) default null, 
... 

其中地址應該是唯一用於deleted == 0的條目。

+0

我們可以看到示例模式,索引,數據嗎? – Kermit

+0

@njk更新,我認爲應該足夠了 – viraptor

+0

你看過'INSERT ... ON DUPLICATE KEY UPDATE'語法嗎? http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html – Kermit

回答

0

沿着這一思路:

insert into target 
    select * from source1 
    union 
    (select * from source2 where not (source2.id in (select id from source1))) 

的多個表添加更多union子句。

+0

我的場景是兩個進程將'insert into thetable(deleted,address)values(0,'123')',而不是從一個進程中的兩個源插入。 – viraptor

0

你可以試試這個插入查詢:

INSERT IGNORE INTO tbl(id,deleted,address) 
SELECT CASE WHEN EXISTS (SELECT id FROM tbl 
         WHERE deleted=0 AND address='new_address') 
     THEN id ELSE NULL END, 
     0, 
     'new_address' 
FROM tbl 
LIMIT 1 

如果給定的地址行和刪除= 0在表中已經存在,它將嘗試插入行具有相同的ID,這顯然不會因爲id是主鍵。 但是,如果沒有這樣的行,它會嘗試插入一個NULL作爲id行,這將成功。