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,
...

where address 对于 where 的条目应该是唯一的deleted == 0

4

2 回答 2

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 的行,这将成功。

于 2012-08-22T17:24:31.420 回答
0

沿着这些思路:

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

为更多表添加更多联合子句。

于 2012-08-22T16:36:14.910 回答