在重复键更新时排除插入中的唯一索引

时间:2017-10-09 09:52:31

标签: mysql sql indexing transactions ddl

假设我有一张桌子:

vegetable_ids = []
fruit_ids = []

for product <- products do
  case product do
    %Abc.Products.Vegetable{__meta__: _, id: id, inserted_at: _, name: _, updated_at: _} -> vegetable_ids = vegetable_ids ++ [id]
    %Abc.Products.Fruit{__meta__: _, id: id, inserted_at: _, name: _, updated_at: _} -> fruit_ids = fruit_ids ++ [id]
  end
end

此外,假设此表可以包含数百万条记录,并且可以添加或更新数百万条记录。对于此任务,我计划在重复密钥更新时使用插入。

列a,b和c是唯一列,但我可能必须在表中交换b和c的列值。例如:

a b c
1 2 3
2 4 5

我想交换专栏b的值。我想将其更新为:

a b c
1 4 3
2 2 5

现在,在重复键更新操作的整个插入过程中,列a的值无法更改。但是列b和c可以。

出于这个原因,我想在重复键更新中使用插入列a的索引,而不是所有索引。也就是说,当重复键更新上的插入决定更新行时,查询应为:

create table sample(
i int(5) primary key auto_increment,
a int(5) not null unique,
b int(5) not null unique,
c int(5) not null unique);

而不是

update sample set a=?, b=?c=? where a=?

\有可能吗?

我想到这样做的一种方法是在执行查询之前删除索引并再次放回索引。

update sample set a=?, b=?c=? where a=? or b=? or c=?

但是,如果我在一个事务中,这会导致一个隐式提交,我根本不喜欢这个。

有没有更好的方法来做我想要的事情?

1 个答案:

答案 0 :(得分:1)

您似乎想要在值的组合上使用唯一索引,而不是在每个列上(至少,您的示例数据表明这一点)。

如果是这样,那么您需要将表定义为:

create table sample (
    i int(5) primary key auto_increment,
    a int(5) not null,
    b int(5) not null,
    c int(5) not null,
    unique (a, b, c)
);