在MySQL中使用“replace into”和“Insert into … on duplicate key update …”

有时,当我们想在包含重复键的表中插入行时,我们考虑在重复键更新时使用“替换为”或“插入...”。在最近的工作中,我发现使用它们时会遇到一些陷阱,而本文旨在说明会发生什么以及为什么发生。

 

1)replace into

 
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `t1` (
 
  `a` int(11) NOT NULL AUTO_INCREMENT,
 
  `b` int(11) DEFAULT NULL,
 
  `c` int(11) DEFAULT NULL,
 
  PRIMARY KEY (`a`),
 
  UNIQUE KEY `uniq_b` (`b`)
 
) ENGINE=InnoDB DEFAULT CHARSET=utf8
 

 

替换重复的行:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1; 
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    2 |
 
| 2 |    2 | NULL |
 
+---+------+------+

 

 
1
2
3
mysql> replace into t1(b,c) values (1,9); 
 
Query OK, 2 rows affected (0.07 sec)

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 2 |    2 | NULL |
 
| 3 |    1 |    9 |
 
+---+------+------+

 

在唯一键上使用“替换为...”之后,删除了(1,1,2)并插入了新行(3,1,9),它不仅是替换(1,1,2)的值)行,因为列“ a”使用了AUTO_INCREMENT值“ 3”。

 

必须指定列名:

如果未指定列名,例如:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    2 |
 
| 2 |    2 | NULL |
 
+---+------+------+

 

 
1
2
3
mysql> replace into t1(b) values (1);
 
Query OK, 2 rows affected (0.06 sec)

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 2 |    2 | NULL |
 
| 3 |    1 | NULL |
 
+---+------+------+

 

列'a'和'c'已更改为'3'和'null',因此当使用'replace into'时,它将删除重复的行并插入具有默认值的新行 。

 

同时替换重复的主键和重复的唯一键:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 2 |    2 |    2 |
 
| 3 |    1 |    2 |
 
+---+------+------+

 

 
1
2
3
mysql> replace into t1(a,b,c) values (2,1,9);
 
Query OK, 3 rows affected (0.10 sec)

 

 
1
2
3
4
5
6
7
8
9
10
11
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 2 |    1 |    9 |
 
+---+------+------+

 

在“替换为...”之后,它显示“受影响三行 ”,两行已被删除,仅一行插入到t1中。

如前所述,“替换为..”将在插入之前删除重复的行,因此,当“替换为t1(a,b,c)的值(2,1,9);”时,在执行时,它首先检查主键,将其复制,因此(2,2,2)被删除,然后列'b'也被复制,因此(3,1,2)被删除,之后,没有重复的键,然后插入新行(2,1,9)。

 

2)Insert into … on duplicate key update …

使用同一表t1进行测试:

插入重复的主键行:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1; 
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    2 |
 
| 2 |    2 | NULL |
 
+---+------+------+

 

 
1
2
3
mysql> insert into t1(a,b,c) values (2,3,4) on duplicate key update c=4;
 
Query OK, 2 rows affected (0.02 sec)

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    2 |
 
| 2 |    2 |    4 |
 
+---+------+------+

 

“在重复键更新中插入...”只是检查了主键,发现主键“ a”具有重复值“ 2”之后,便将列“ c”更新为新值“ 4”,并被忽略了。同样重复的“ b”列。所以我们得到了新行(2,2,4)而不是(2,3,4)。

 

在重复的键行上插入:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    2 |
 
| 2 |    2 |    4 |
 
+---+------+------+

 

 
1
2
3
mysql> insert into t1(b,c) values (1,5) on duplicate key update c=5;
 
Query OK, 2 rows affected (0.20 sec)

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select * from t1;
 
+---+------+------+
 
| a | b    | c    |
 
+---+------+------+
 
| 1 |    1 |    5 |
 
| 2 |    2 |    4 |
 
+---+------+------+

 

这与“替换为..”不同,它只是更新重复行上的值,而没有删除。

简而言之,在对重复键更新使用“替换为...”和“插入...”之前,您必须知道它们的实际作用,否则会得到意想不到的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值