INSERT INTO vs REPLACE INTO vs INSERT IGNORE INTO
前言
在看某块功能的代码的时候,看到了比较有意思的 SQL
语句,如下:
INSERT IGNORE INTO ...
INSERT INTO
用的最多的插入语句了,直接插入一条数据,如果主键冲突,会报错。
REPLACE INTO
替换数据,SQL
语句中必须存在主键或者唯一键,如果存在,则更新,否则插入。
单个 INSERT INTO
语句插入多个值时,InnoDB
表中,会认为这是单个事务,要么都成功,要么都失败。
如果用了 INSERT IGNORE INTO
语句插入多个值时,InnoDB
表中,会按先后顺序插入,冲突的更新。
mysql> DROP TABLE IF EXISTS tb;
mysql> CREATE TABLE `tb` (
-> `v1` int(11),
-> `v2` int(11),
-> UNIQUE KEY `u_v2` (`v2`)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.03 sec)
mysql> -- 下面一条语句会整体失败
mysql> INSERT INTO tb VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
ERROR 1062 (23000): Duplicate entry '5' for key 'u_v2'
mysql> SELECT * FROM tb;
Empty set (0.00 sec)
mysql> -- 下面一条语句会成功4个
mysql> REPLACE INTO tb VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
Query OK, 6 rows affected (0.01 sec)
Records: 5 Duplicates: 1 Warnings: 0
mysql> -- 可以看到 (7, 5) 替换了 (2, 5)
mysql> SELECT * FROM tb;
+------+------+
| v1 | v2 |
+------+------+
| 7 | 5 |
| 6 | 10 |
| 3 | 1 |
| 1 | 9 |
+------+------+
4 rows in set (0.00 sec)
INSERT IGNORE INTO
插入数据,SQL
语句中必须存在主键或者唯一键,如果存在,则忽略,否则插入。
单个 INSERT INTO
语句插入多个值时,InnoDB
表中,会认为这是单个事务,要么都成功,要么都失败。
如果用了 INSERT IGNORE INTO
语句插入多个值时,InnoDB
表中,会按先后顺序插入,冲突的失败。
mysql> DROP TABLE IF EXISTS tb;
mysql> CREATE TABLE `tb` (
-> `v1` int(11),
-> `v2` int(11),
-> UNIQUE KEY `u_v2` (`v2`)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.03 sec)
mysql> -- 下面一条语句会整体失败
mysql> INSERT INTO tb VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
ERROR 1062 (23000): Duplicate entry '5' for key 'u_v2'
mysql> SELECT * FROM tb;
Empty set (0.00 sec)
mysql> -- 下面一条语句会成功4个
mysql> INSERT IGNORE INTO tb VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
Query OK, 4 rows affected, 1 warning (0.00 sec)
Records: 5 Duplicates: 1 Warnings: 1
mysql> -- 可以看到
mysql> SELECT * FROM tb;
+------+------+
| v1 | v2 |
+------+------+
| 2 | 5 |
| 6 | 10 |
| 3 | 1 |
| 1 | 9 |
+------+------+
4 rows in set (0.00 sec)
最后
有些场景可以直接用 SQL
来处理了,减少一些代码。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!