多个UNIQUE字段的ON DUPLICATE KEY UPDATE的MySQL行为

时间:2013-05-04 19:06:13

标签: mysql sql-update sql-insert upsert

从MySQL 4.1.0开始,可以添加ON DUPLICATE KEY UPDATE语句来指定插入值(INSERTSETVALUES)时的行为目的地表PRIMARY KEY或某个UNIQUE字段。如果PRIMARY KEY或某些UNIQUE字段的值已在表中,INSERT将替换为UPDATE

  • 如果有多个,ON DUPLICATE KEY UPDATE如何表现? 我桌上的UNIQUE个字段?

  • 如果UNIQUE字段匹配,我是否只能有一个更新?

  • 只有同时匹配两个UNIQUE字段,才能更新吗?

2 个答案:

答案 0 :(得分:23)

考虑

INSERT INTO table (a,b,c) VALUES (1,2,3)
    -> ON DUPLICATE KEY UPDATE c=c+1;

如果a和b是UNIQUE字段,则UPDATE上会出现a = 1 OR b = 2。此外,当条件a = 1 OR b = 2被两个或更多条目满足时,更新仅执行一次。

此处的表格包含Id和名称UNIQUE字段

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6

如果查询

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)

然后我们得到

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

违反了Id和Name的唯一性。现在用

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7

我们得到了

Id     Name     Value 
1      P        7 
2      C        7 
3      D        29 
4      A        6

多个键上的行为如下

如果UPDATE字段中的一个等于要插入的值,则会执行ON DUPLICATE KEY UPDATE中的{p> UNIQUE。在UPDATE执行Id = 1 OR Name = C。它相当于

UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C

如果我只需要一次更新,对于任一键

,该怎么办?

可以在UPDATE关键字

中使用LIMIT语句
UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C
LIMIT 1;

将给出

Id     Name     Value 
1      P        7 
2      C        3 
3      D        29 
4      A        6

如果仅在两个键的值匹配时才需要更新

,该怎么办?

一个解决方案是ALTER TABLE,并使PRIMARY KEY(或唯一性)适用于这两个字段。

ALTER TABLE table 
DROP PRIMARY KEY
ADD PRIMARY KEY (Id, Name);

现在,

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7

我们得到了

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

因为没有找到重复(在两个键上)。

答案 1 :(得分:0)

  1. MySQL如何表现...... 它的行为符合预期,即执行ON DUPLICATE KEY子句。

  2. 我可以为其中一个更新吗? 实际上,您只有一个ON DUPLICATE KEY子句,因此您需要放置一些代码来区分涉及哪个约束。幸运的是,它是可能的。您应该知道的唯一事情,分配顺序很重要,您可以分配多次。假设您对a和b有唯一约束,并且只有在涉及唯一性时才想更新c:     ...     KEY UPDATE c = IF(a = VALUES(a)和b<> VALUES(b),VALUES(c),c),b = VALUES(b)

    但是如果你改变了作业的顺序,那么if中的第二个条件总是假的。

  3. 见2.