INSERT INTO 语句的基本写法和常见错误
MySQL 插入数据最常用的是
INSERT INTO,但新手常因字段顺序、值类型不匹配或忽略主键约束而报错。比如执行
INSERT INTO users VALUES ('alice', 25); 却提示 Column count doesn't match value count,大概率是表有 3 列(含自增
id),却只给了 2 个值。
安全写法永远显式指定字段名:
INSERT INTO users (name, age) VALUES ('alice', 25);
避免因表结构变更(如新增字段)导致插入失败
字段顺序与 VALUES严格对应,不依赖表定义顺序 未列出的字段若设了默认值或允许 NULL,会自动填充;否则报错
批量插入比逐条执行快得多,但要注意限制
一次性插入多行能显著减少网络往返和事务开销。用逗号分隔多组
VALUES即可:
INSERT INTO logs (level, message, created_at) VALUES
('ERROR', 'timeout', '2024-06-01 10:00:00'),
('WARN', 'disk usage >90%', '2024-06-01 10:05:00'),
('INFO', 'service restarted', '2024-06-01 10:10:00');
单次插入行数建议控制在 1000 行以内,过大可能触发 max_allowed_packet限制 InnoDB 在事务中批量插入比分开
INSERT更快,但也要注意事务日志膨胀 如果主键冲突,整条语句会失败——此时该用
INSERT IGNORE或
ON DUPLICATE KEY UPDATE
处理重复数据:IGNORE 和 ON DUPLICATE KEY UPDATE 的区别
当表有唯一索引(如
UNIQUE或主键),重复插入会报
Duplicate entry错误。两种常用兜底方式:
INSERT IGNORE INTO users (email, name) VALUES ('a@b.com', 'Alice'); —— 冲突时静默跳过,不报错也不插入
INSERT INTO users (email, name) VALUES ('a@b.com', 'Alice') ON DUPLICATE KEY UPDATE name = VALUES(name); —— 冲突时更新指定字段,VALUES(name)指本次想插入的值
注意:
IGNORE会抑制所有警告(包括非主键冲突的警告),而
ON DUPLICATE KEY UPDATE只响应唯一键/主键冲突,语义更明确。
从查询结果插入数据(INSERT ... SELECT)的坑
用
INSERT INTO ... SELECT批量导入时,容易忽略目标列与源列的数据类型、长度或 NULL 约束是否兼容:
INSERT INTO archive_logs (level, message, archived_at) SELECT level, message, NOW() FROM logs WHERE created_at < '2024-01-01';SELECT 返回的列数、顺序、类型必须与 INSERT 目标列严格匹配 如果目标列定义为
NOT NULL,而 SELECT 出来是
NULL,会直接报错 没有
WHERE条件时慎用,可能误塞全表数据 大表 SELECT + INSERT 可能锁表或拖慢查询,考虑加
LIMIT分批操作
真正难的不是语法,是搞清你要插进哪几列、它们是否允许空、有没有唯一约束、以及要不要覆盖旧数据——这些不确认清楚,
INSERT写得再顺也会在生产环境卡住。
