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

4

2 に答える 2

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 に答える
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 は主キーであるため、明らかに起こりません。しかし、そのような行がない場合は、ID として NULL を持つ行を挿入しようとし、成功します。

于 2012-08-22T17:24:31.420 に答える