我正在尝试插入一些没有重复的数据,可能来自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 :(得分:0)
沿着这些方向:
insert into target
select * from source1
union
(select * from source2 where not (source2.id in (select id from source1)))
为更多表添加更多联合子句。
答案 1 :(得分: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的行,这将成功。