以最佳方式插入和删除行

时间:2015-06-13 11:01:00

标签: mysql

我有一张现有的表

id, name, user
15, bob, 1
25, alice, 2
30, ann, 1
55, bob, 2
66, candy, 1

我们希望用户1的名称记录现在设置为此字符串中的值:

"ann, candy, dave"

如果我这么做的话很简单

delete from table where user = 1
insert into table (name,user) values (ann,1), (candy,1), (dave,1)`

然后表格现在看起来像这样

id, name, user
25, alice, 2
55, bob, 2
67, ann, 1
68, candy, 1
69, dave, 1

即。新行已创建。我不想要新的身份,随着时间的推移,这会导致碎片和身份漏洞等等。 SQL中最有效的方法是将其减少到实际的2个所需操作:

从表中删除user = 1且name不在字符串" ann,candy,dave"中,以便表格为:

25, alice, 2
30, ann, 1
55,鲍勃,2 66,糖果,1 `

插入表user = 1,name =来自" ann,candy,dave"的任何值与name / user = 1不匹配,因此表格为: 25, alice, 2 30, ann, 1 55, bob, 2 66, candy, 1 67, dave, 1

2 个答案:

答案 0 :(得分:1)

听起来你有一个列表,想要处理两次,一次用于删除,一次用于插入。将列表存储在临时表中并将其用于处理。

一路上,从user, name上的唯一索引开始,以防止更新到表中:

create unique index idx_table_user_name on table(user, name);

这似乎是您数据的要求,因此请让数据库强制执行。然后处理代码如下:

create temporary table toprocess as (
     select 1 as user, 'ann' as name union all
     select 1, 'candy' union all
     select 1, 'dave'
    );

create index idx_toprocess_user_name on toprocess(user, name);

delete t
    from table t
    where t.user in (select p.user from toprocess p) and
          not exists (select 1 from toprocess p where p.user = t.user and p.name = t.name);

insert into table(user, name)
    select user, name
    from toprocess
    on duplicate key update user = values(user);

虽然这可能看起来有点复杂,但它允许您同时处理多个用户。并且,处理列表只输入一次,这减少了错误的范围。

答案 1 :(得分:0)

目前尚不清楚,但可能是您想要的:

delete from table where user = 1 and name not in('ann', 'candy', 'dave')

insert into table
select * from(select 'ann' as name
              union all
              select 'candy'
              union all
              select 'dave') t
where t.name not in(select name from table where user = 1)