先说结论
on duplicate key update
主键冲突 ,会根据主键修改相应字段,主键递增值不受影响,影响两行
唯一键冲突 ,,会根据主键修改相应字段,主键递增值会增加,影响两行
replace into
replace into 主键冲突 先删除 再插入 主键不会增加
replace into 唯一键冲突 先删除 再利用新的主键插入,行的主键增加
当主键和唯一键都冲突的时候,走唯一键逻辑
创建表
CREATE TABLE `test` (
`a` int NOT NULL AUTO_INCREMENT,
`b` varchar(10) COLLATE utf8mb4_0900_as_ci DEFAULT NULL,
`c` varchar(10) COLLATE utf8mb4_0900_as_ci DEFAULT NULL,
`d` int DEFAULT NULL,
PRIMARY KEY (`a`),
UNIQUE KEY `c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_ci;
主键冲突 与主键递增的关系
mysql> insert into test (b,c,d) values('5','1',1) on duplicate key update c=VALUES(c), d=VALUES(d);
Query OK, 1 row affected (0.06 sec)
无冲突的时候,只影响一行
mysql> select * from test;
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 5 | 1 | 1 |
+---+---+---+---+
1 row in set (0.09 sec)
模拟主键冲突
mysql> insert into test (a,b,c,d) values(1,'51','11',11) on duplicate key update c=VALUES(c),d=VALUES(d);
Query OK, 2 rows affected (0.06 sec)
mysql> select * from test;
+---+---+----+----+
| a | b | c | d |
+---+---+----+----+
| 1 | 5 | 11 | 11 |
+---+---+----+----+
1 row in set (0.08 sec)
主键冲突 会根据主键修改响应字段
再下来看主键冲突对主键序列的影响
insert into test (b,c,d) values('2','2',2) on duplicate key update b=VALUES(b), d=VALUES(d);
mysql> insert into test (b,c,d) values('2','2',2) on duplicate key update c=VALUES(c), d=VALUES(d);
Query OK, 1 row affected (0.06 sec)
mysql> select * from test;
+---+---+----+----+
| a | b | c | d |
+---+---+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 2 | 2 | 2 |
+---+---+----+----+
2 rows in set (0.09 sec)
主键冲突 ,会根据主键修改相应字段,主键递增值不受影响,影响两行
唯一键冲突 ,,会根据主键修改相应字段,主键递增值会增加,影响两行
mysql> insert into test (b,c,d) values('22','2',22) on duplicate key update b=VALUES(b), d=VALUES(d);
Query OK, 2 rows affected (0.06 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
+---+----+----+----+
2 rows in set (0.09 sec)
mysql> insert into test (b,c,d) values('3','3',3) on duplicate key update b=VALUES(b), d=VALUES(d);
Query OK, 1 row affected (0.09 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
| 4 | 3 | 3 | 3 |
+---+----+----+----+
3 rows in set (0.19 sec)
replace into 主键冲突 先删除 再插入 主键不会增加
mysql> replace into test (a,b,c,d) values(4,'4','4',4);
Query OK, 2 rows affected (0.07 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
| 4 | 4 | 4 | 4 |
+---+----+----+----+
3 rows in set (0.11 sec)
mysql> replace into test (b,c,d) values('5','5',5);
Query OK, 1 row affected (0.06 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
| 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 |
+---+----+----+----+
4 rows in set (0.11 sec)
replace into 唯一键冲突 先删除 再利用新的主键插入,行的主键增加
mysql> replace into test (b,c,d) values('55','5',55);
Query OK, 2 rows affected (0.07 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
| 4 | 4 | 4 | 4 |
| 6 | 55 | 5 | 55 |
+---+----+----+----+
4 rows in set (0.13 sec)
mysql> replace into test (b,c,d) values('6','6',6);
Query OK, 1 row affected (0.07 sec)
mysql> select * from test;
+---+----+----+----+
| a | b | c | d |
+---+----+----+----+
| 1 | 5 | 11 | 11 |
| 2 | 22 | 2 | 22 |
| 4 | 4 | 4 | 4 |
| 6 | 55 | 5 | 55 |
| 7 | 6 | 6 | 6 |
+---+----+----+----+
5 rows in set (0.11 sec)
当主键和唯一键都冲突的时候,走唯一键逻辑