插入数据
INSERT / 插入单行 / 插入多行 / 插入检索结果
前面一直在查数据,但数据从哪来?——当然是插进去的。这一章开始真正动手改数据。
INSERT 基础:插入一行
语法一眼就懂:
INSERT INTO users (name, age, city, salary)
VALUES ('马十一', 24, '成都', 9000.00);拆开看:
INSERT INTO users— 往哪张表里插(name, age, city, salary)— 要填哪些列VALUES (...)— 对应列的值
跑完 SELECT * FROM users; 就能看到多了一行,id 自动分配为 9。
列的顺序可以换
只要列名和值对应上就行:
INSERT INTO users (city, name, salary, age)
VALUES ('重庆', '何十二', 11000.00, 28);省略列名
如果 VALUES 给的值和表定义的列顺序完全一致,可以省掉列名:
INSERT INTO users
VALUES (11, '丁十三', 31, '武汉', 7500.00);
-- 注意 id 也得手动给(虽然平时 AUTO_INCREMENT 自动填)⚠️ 不建议省列名。表结构一改(比如加了一列),没写列名的 INSERT 直接报废。老老实实写明列名,安全第一。
省略列:用默认值
不是每列都必须给值。不写的列,MySQL 会用默认值或 NULL 来填:
INSERT INTO users (name, city, salary)
VALUES ('林十四', '南京', 8200.00);age 没写,这一行的 age 就是 NULL。
哪些列可以不写?满足以下任一条件即可:
- 列定义了
DEFAULT值 - 列允许
NULL
id 是 AUTO_INCREMENT,不用写——MySQL 自动分配。
一次插入多行
一行一行插太慢。VALUES 后面接多组括号,逗号隔开:
INSERT INTO users (name, age, city, salary) VALUES
('马十一', 24, '成都', 9000.00),
('何十二', 28, '重庆', 11000.00),
('丁十三', 31, '武汉', 7500.00);三行一次性写入,比单条 INSERT 跑三次快得多。
💡 批量插入时,一条 INSERT 比多条 INSERT 性能好很多——减少网络来回次数。
插入检索出来的数据
INSERT 和 SELECT 可以组合使用,把查出来的结果直接插到另一张表。
场景:创建一个 users_backup 表,把北京员工备份过去。
-- 先建备份表(结构一样)
CREATE TABLE users_backup (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age INT,
city VARCHAR(50),
salary DECIMAL(8,2)
);
-- 把北京员工的数据插进去
INSERT INTO users_backup (name, age, city, salary)
SELECT name, age, city, salary
FROM users
WHERE city = '北京';一次性把 3 行北京员工数据复制到了 users_backup 表。这就是 INSERT SELECT——不用先把数据读出来再插,MySQL 内部直接搬运。
📝
INSERT SELECT的列数和类型规则和 UNION 一样:列数一致,类型兼容,列名无所谓。
插入时的常见错误
主键冲突
INSERT INTO users (id, name, city, salary)
VALUES (1, '重复了', '北京', 5000.00);
-- ERROR: Duplicate entry '1' for key 'PRIMARY'id=1 已经存在,主键不能重复。要么不写 id 让 MySQL 自动分配,要么用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE(后面讲)。
类型不匹配
INSERT INTO users (name, age, city, salary)
VALUES ('测试', '不是数字', '北京', 5000.00);
-- ERROR: Incorrect integer value: '不是数字' for column 'age'age 是 INT,塞字符串进去 MySQL 不认。
NOT NULL 列不给值
INSERT INTO users (age, city, salary) VALUES (25, '北京', 5000.00);
-- ERROR: Field 'name' doesn't have a default valuename 定义了 NOT NULL 又没有默认值,必须给值。
安全写法建议
-- ✅ 好的写法:列名写全(除了自增主键),值一一对应
INSERT INTO users (name, age, city, salary)
VALUES ('新人', 26, '长沙', 8800.00);
-- ❌ 偷懒的写法:不写列名,出问题了都不知道哪列对不上
INSERT INTO users VALUES (15, '新人', 26, '长沙', 8800.00);小结
增删改的第一步——插入数据,记住这几个要点:
- INSERT INTO 表(列) VALUES(值) — 基本句式,列和值一一对应
- 写列名是好习惯 — 不写列名看似省事,表结构一变就炸
- 一次插多行 —
VALUES (行1), (行2), (行3)性能好很多 - INSERT SELECT 批量搬运 — 把查询结果直接插入另一张表
- NOT NULL 列必须给值 — 否则直接报错,AUTO_INCREMENT 列不用管
💡 插入是最简单的写操作,但从这章开始你真正在改数据了——养成"先 SELECT 确认、再 INSERT"的好习惯。
自主练习
- 往
users表插入一条自己的信息 - 一次插入 3 条新员工,城市各不相同
- 新建一张
users_copy表(和 users 结构一样),用 INSERT SELECT 把所有工资 > 10000 的人复制过去 - 试一下不写 age 列会怎样?不写 name 列会怎样?
建表语句参考
02.安装与环境里的CREATE TABLE users,改个表名就行。