本节摘要:INSERT 向表里添加行。本节讲单行插入、多行插入、INSERT ... SELECT 从查询结果插入,以及插入的常见坑。
阅读完本节,你应当能够:
INSERT INTO Customers (CustomerID, FirstName, LastName, City) VALUES (101, 'Alice', 'Smith', '北京');
列名和值按顺序对应。可以只插部分列,未指定的列填默认值或 NULL:
INSERT INTO Customers (FirstName, LastName) VALUES ('Bob', 'Johnson'); -- CustomerID 自动生成或 NULL,City 为 NULL
一条 INSERT 插多行,效率比多条单行高(一次提交):
INSERT INTO Customers (CustomerID, FirstName, LastName, City) VALUES (101, 'Alice', 'Smith', '北京'), (102, 'Bob', 'Jones', '上海'), (103, 'Carol', 'Brown', '广州');

从查询结果插入,常用于复制数据、ETL:
-- 把订单表里金额大于 100 的复制到大额订单表 INSERT INTO BigOrders (OrderID, CustomerID, Amount) SELECT OrderID, CustomerID, Amount FROM Orders WHERE Amount > 100;
INSERT ... ON DUPLICATE KEY UPDATE,或 INSERT IGNORE 忽略。-- MySQL 主键冲突时更新 INSERT INTO Customers (CustomerID, FirstName, City) VALUES (101, 'Alice', '上海') ON DUPLICATE KEY UPDATE City = '上海';
⚠️ 常见坑:循环里一条一条单行 INSERT,性能极差。批量插入一条语句插多行,或用事务包一批,效率高几个数量级。
💡 关键直觉:INSERT 是最安全的 DML(只增不改不删)。批量插入比单条循环快得多,主键冲突用 IGNORE 或 ON DUPLICATE KEY 处理。
INSERT INTO 表(列) VALUES(值),列值按序对应,可只插部分列。下一节讲 UPDATE——改数据,WHERE 是它的命根子。
Q1:INSERT 时列名可以省略吗?
可以,INSERT INTO 表 VALUES (值1,值2,...) 会按表定义顺序填值。但强烈不建议省略:表结构一旦变化(加列、调顺序),省略写法就会错位。显式写列名更安全、可读性更好,是生产标准写法。
Q2:部分列没给值会怎样?
有默认值(DEFAULT)的列用默认值,允许 NULL 的列存 NULL,NOT NULL 且无默认值的列会报错。所以建表时给列设好 DEFAULT(如状态、创建时间),能减少插入时的心智负担。
Q3:批量插入为什么快?
一条 INSERT 多条 VALUES 是一次网络往返、一次提交;循环单条插入是 N 次往返、N 次日志写入。批量插入把事务日志、锁开销摊薄,速度可差几十倍。数据导入场景(ETL)一定要用批量方式。
Q4:插入重复的主键会怎样?
报主键冲突错误。想"存在就更新、不存在就插入",MySQL 用 ON DUPLICATE KEY UPDATE,PostgreSQL 用 ON CONFLICT DO UPDATE(upsert)。先了解报错行为,再按需用 upsert。
Q5:INSERT...SELECT 有什么用?
数据迁移、表归档、建测试数据都靠它:从线上表把满足条件的数据复制到归档表,无需逐条读再逐条插。语法上注意两边的列要一一对应。
Q6:插入超长字符串会怎样?
严格模式下报错(Data too long);非严格模式可能静默截断,数据悄悄丢失。建议开启严格 SQL 模式,让超长直接报错,暴露问题而不是掩盖。
插入操作本身简单,但容易在细节上踩坑,建议动手练一遍。
准备一张练习表,设置好主键、非空列、带默认值的列、允许空值的列。
第一个练习:分别用完整列名、省略列名两种写法插入数据,观察省略列名时如果表和值顺序对不上会发生什么,体会显式列名的价值。
第二个练习:只填部分列,观察哪些列用了默认值、哪些列成了空值、哪些列直接报错,理解默认值和空值约束在插入时的作用。
第三个练习:一次插入多行,再对比多次单行插入,体会批量插入的效率优势。
第四个练习:试着插入一条主键冲突的记录,看报错信息;再插入一条超长的字符串,看严格模式下的报错,理解数据库在写入时的把关作用。
这四个练习做完,插入的写法、默认值的应用、批量的优势、冲突与超长的处理,就都变成你的实战经验了。插入是所有数据写入的起点,练扎实了后面更新删除都顺。
插入是把数据写进表的第一步。显式列名更安全,批量插入更高效,主键冲突要处理,超长内容在严格模式下会被拦住。这些细节记住,写入就不会出乱子。