[英]MySQL bulk INSERT or UPDATE
有没有办法在 MySQL 服务器上批量执行查询,如INSERT OR UPDATE
?
INSERT IGNORE ...
将不起作用,因为如果该字段已经存在,它将简单地忽略它并且不插入任何内容。
REPLACE ...
将不起作用,因为如果该字段已经存在,它将首先DELETE
它然后再次INSERT
它,而不是更新它。
INSERT ... ON DUPLICATE KEY UPDATE
可以,但不能批量使用。
所以我想知道是否有像INSERT... ON DUPLICATE KEY UPDATE
这样的命令可以批量发布(同时多行)。
您可以使用 INSERT... ON DUPLICATE KEY UPDATE 插入/更新多行。 该文档具有以下示例:
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
还是我误解了你的问题?
一种可能的方法是创建一个临时表,将数据插入其中,然后使用连接执行 1 次查询以插入不存在的记录,然后更新到确实存在的字段。 基本情况是这样的。
CREATE TABLE MyTable_Temp LIKE MyTable
LOAD DATA INFILE..... INTO MyTable_Temp
UPDATE MyTable INNER JOIN
MyTable_Temp
ON MyTable.ID=MyTable_Temp.ID
SET MyTable.Col1=MyTable_Temp.Col1, MyTable.Col2=MyTable_Temp.Col2.....
INSERT INTO MyTable(ID,Col1,Col2,...)
SELECT ID,Col1,Col2,...
FROM MyTable_Temp
LEFT JOIN MyTable
ON MyTable_Temp.ID = MyTable.ID
WHERE myTable.ID IS NULL
DROP TABLE MyTable_Temp
语法可能不准确,但这应该为您提供基础知识。 另外,我知道它不漂亮,但它完成了工作。
更新
我交换了插入和更新的顺序,因为先插入会导致在调用更新时更新所有插入的行。 如果您先更新,则仅更新现有记录。 这应该意味着服务器的工作量要少一些,尽管结果应该是相同的。
虽然这个问题已经得到了正确的回答(MySQL 确实通过 ON DUPLICATE UPDATE 和预期的多值集语法支持这个),但我想通过提供一个演示来扩展这个问题,任何拥有 MySQL 的人都可以运行:
CREATE SCHEMA IF NOT EXISTS `test`;
DROP TABLE IF EXISTS test.new_table;
CREATE TABLE test.new_table (`Key` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`Key`)) ENGINE=InnoDB AUTO_INCREMENT=106 DEFAULT CHARSET=utf8;
SELECT * FROM test.new_table;
INSERT INTO test.new_table VALUES (1),(2),(3),(4),(5) ON DUPLICATE KEY UPDATE `Key`=`Key`+100;
SELECT * FROM test.new_table;
INSERT INTO test.new_table VALUES (1),(2),(3),(4),(5) ON DUPLICATE KEY UPDATE `Key`=`Key`+100;
SELECT * FROM test.new_table;
output如下:
Empty set (0.00 sec)
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
+-----+
| Key |
+-----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+-----+
5 rows in set (0.00 sec)
Query OK, 10 rows affected (0.00 sec)
Records: 5 Duplicates: 5 Warnings: 0
+-----+
| Key |
+-----+
| 101 |
| 102 |
| 103 |
| 104 |
| 105 |
+-----+
5 rows in set (0.00 sec)
尝试添加一个插入触发器,该触发器执行飞行前检查并取消重复键上的插入(在更新现有行之后)。
不确定它是否适合批量插入,更不用说加载数据文件了,但这是我能想到的最好的。 :-)
如果您使用的是 Oracle 或 Microsoft SQL,则可以使用MERGE
。 但是,MySQL 与该语句没有直接关联。 您提到了单行解决方案,但正如您所指出的,它的批量处理效果不是很好。 这是我在 Oracle 和 MySQL 之间的区别以及如何执行 Oracle 与MERGE
在 Oracle 中对 Oracle 所做的操作:Oracle:1
http://blog.mclaughlinsoftware.com/2009/05/25/mysql-merge-gone-awry/
这不是一个漂亮的解决方案,它可能不像你想要的那样完整,但我相信这是最好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.