MySQL 批量插入与数据迁移
在单次操作中插入多行数据,比执行多个独立的 INSERT 语句效率更高,因为它减少了客户端与 MySQL 服务器之间的通信开销。与其为每一行数据发送一条单独的命令,不如将它们打包到一个事务中执行。
1. 批量插入多行数据
要插入多条记录,只需在 VALUES 子句中提供一个以逗号分隔的值集列表。语法遵循一个简单的模式:INSERT INTO table_name (column1, column2) VALUES (val1, val2), (val3, val4), (val5, val6);。
考虑一个你需要填充 suppliers(供应商)表的场景:
-- 向供应商表中批量插入三条记录
INSERT INTO suppliers (supplier_name, city, country)
VALUES
('Global Tech Solutions', 'San Francisco', 'USA'),
('Mountain Peak Gear', 'Denver', 'USA'),
('Alpine Logistics', 'Bern', 'Switzerland');当你执行这段代码时,MySQL 会一次性处理所有三行数据。如果你正在插入大量数据——例如,数百或数千行——使用这种多行语法比执行单独的 INSERT 语句要快得多。
2. 使用 INSERT INTO ... SELECT 进行数据迁移
INSERT INTO ... SELECT 语句允许你将数据从一个表复制到另一个表。这是在 ETL(提取、转换、加载)过程中进行数据归档、创建数据备份或在表之间转换数据的标准做法。
与使用字面量的标准 INSERT 语句不同,这种方法从 SELECT 查询中提取结果集,并将其直接推送到目标表中。
-- 假设存在一个 'inactive_suppliers'(未激活供应商)表,且其列与 'suppliers' 表匹配
INSERT INTO inactive_suppliers (supplier_name, city, country)
SELECT supplier_name, city, country
FROM suppliers
WHERE country = 'Switzerland';3. INSERT ... SELECT 的关键注意事项
在使用此功能时,需要牢记以下几个核心原则:
3.1 列对齐 (Column Alignment)
你的 SELECT 语句中的列数必须与你在 INSERT 语句中指定的列数相匹配。如果你要插入到目标表的所有列中,你可以省略列名列表,但最佳实践是明确定义它们,以防止在表结构(Schema)发生更改时出现错误。
3.2 数据类型兼容性 (Data Types)
SELECT 语句返回的数据类型必须与目标列兼容。MySQL 会尝试自动转换(Cast)值,但是如果你尝试将一个很长的字符串插入到一个很小的 VARCHAR 列中,操作将会失败。
3.3 主键冲突 (Primary Key Conflicts)
如果目标表具有 PRIMARY KEY(主键)或 UNIQUE(唯一)约束,并且你的 SELECT 语句生成了一个在该目标列中已经存在的值,那么整个操作将会失败,除非你对冲突进行了处理(例如,使用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE)。