MySQL数据插入 #
一、INSERT语句概述 #
1.1 基本语法 #
sql
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
1.2 示例表结构 #
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
email VARCHAR(100),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
二、基本插入 #
2.1 指定列插入 #
sql
INSERT INTO users (name, age, email)
VALUES ('John', 25, 'john@example.com');
2.2 全列插入 #
sql
INSERT INTO users
VALUES (NULL, 'Jane', 30, 'jane@example.com', NOW());
-- 自增列可以传NULL或0
INSERT INTO users
VALUES (0, 'Bob', 28, 'bob@example.com', DEFAULT);
2.3 省略列名 #
sql
-- 省略列名时,必须按表定义顺序提供所有列的值
INSERT INTO users
VALUES (NULL, 'Alice', 22, 'alice@example.com', NOW());
三、批量插入 #
3.1 多行插入 #
sql
INSERT INTO users (name, age, email) VALUES
('John', 25, 'john@example.com'),
('Jane', 30, 'jane@example.com'),
('Bob', 28, 'bob@example.com'),
('Alice', 22, 'alice@example.com');
3.2 批量插入优势 #
sql
-- 推荐方式:一条语句插入多行
INSERT INTO users (name, age, email) VALUES
('User1', 20, 'user1@example.com'),
('User2', 21, 'user2@example.com'),
('User3', 22, 'user3@example.com');
-- 不推荐:多条单行插入
INSERT INTO users (name, age, email) VALUES ('User1', 20, 'user1@example.com');
INSERT INTO users (name, age, email) VALUES ('User2', 21, 'user2@example.com');
INSERT INTO users (name, age, email) VALUES ('User3', 22, 'user3@example.com');
四、INSERT其他形式 #
4.1 INSERT SET语法 #
sql
INSERT INTO users
SET name = 'John',
age = 25,
email = 'john@example.com';
4.2 INSERT SELECT #
sql
-- 从其他表复制数据
INSERT INTO users_backup (name, age, email)
SELECT name, age, email FROM users;
-- 带条件复制
INSERT INTO users_2024 (name, age, email)
SELECT name, age, email
FROM users
WHERE YEAR(created_at) = 2024;
4.3 INSERT IGNORE #
sql
-- 忽略重复键错误
INSERT IGNORE INTO users (id, name, email)
VALUES (1, 'John', 'john@example.com');
-- 如果id=1已存在,不会报错,只是跳过
4.4 ON DUPLICATE KEY UPDATE #
sql
-- 如果存在则更新,不存在则插入
INSERT INTO users (id, name, age, email)
VALUES (1, 'John', 25, 'john@example.com')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
age = VALUES(age),
email = VALUES(email);
-- MySQL 8.0+ 新语法
INSERT INTO users (id, name, age, email)
VALUES (1, 'John', 25, 'john@example.com') AS new
ON DUPLICATE KEY UPDATE
name = new.name,
age = new.age,
email = new.email;
4.5 REPLACE INTO #
sql
-- 如果存在则删除后插入,不存在则插入
REPLACE INTO users (id, name, age, email)
VALUES (1, 'John', 26, 'john@example.com');
-- 注意:REPLACE会删除旧行再插入新行
-- 自增ID会改变
五、插入默认值 #
5.1 使用DEFAULT #
sql
INSERT INTO users (name, age, email, created_at)
VALUES ('John', 25, 'john@example.com', DEFAULT);
-- created_at使用默认值CURRENT_TIMESTAMP
5.2 省略有默认值的列 #
sql
-- age有默认值0,created_at有默认值
INSERT INTO users (name, email)
VALUES ('John', 'john@example.com');
六、插入NULL值 #
6.1 显式插入NULL #
sql
INSERT INTO users (name, age, email)
VALUES ('John', NULL, 'john@example.com');
6.2 省略允许NULL的列 #
sql
-- 如果age允许NULL,可以省略
INSERT INTO users (name, email)
VALUES ('John', 'john@example.com');
七、插入特殊值 #
7.1 插入表达式 #
sql
INSERT INTO users (name, age, email, created_at)
VALUES ('John', 25, 'john@example.com', NOW());
INSERT INTO products (name, price, discount_price)
VALUES ('Product', 100.00, 100.00 * 0.9);
7.2 插入函数结果 #
sql
INSERT INTO logs (message, created_at)
VALUES ('System started', CURRENT_TIMESTAMP);
INSERT INTO users (name, uuid)
VALUES ('John', UUID());
八、获取插入ID #
8.1 LAST_INSERT_ID() #
sql
INSERT INTO users (name, age, email)
VALUES ('John', 25, 'john@example.com');
SELECT LAST_INSERT_ID();
-- 返回最后插入的自增ID
-- 在应用程序中使用
-- PHP: $id = $pdo->lastInsertId();
// Java: long id = statement.getGeneratedKeys();
8.2 批量插入获取ID #
sql
INSERT INTO users (name, age, email) VALUES
('User1', 20, 'user1@example.com'),
('User2', 21, 'user2@example.com'),
('User3', 22, 'user3@example.com');
SELECT LAST_INSERT_ID();
-- 返回第一个插入的ID
-- 后续ID依次递增
九、插入性能优化 #
9.1 批量插入 #
sql
-- 推荐:一次插入多行
INSERT INTO users (name, age, email) VALUES
('User1', 20, 'user1@example.com'),
('User2', 21, 'user2@example.com'),
('User3', 22, 'user3@example.com');
-- 不推荐:多次单行插入
INSERT INTO users (name, age, email) VALUES ('User1', 20, 'user1@example.com');
INSERT INTO users (name, age, email) VALUES ('User2', 21, 'user2@example.com');
INSERT INTO users (name, age, email) VALUES ('User3', 22, 'user3@example.com');
9.2 禁用索引(大批量导入) #
sql
-- 禁用索引
ALTER TABLE users DISABLE KEYS;
-- 批量插入数据
INSERT INTO users (name, age, email) VALUES
-- ... 大量数据
-- 启用索引
ALTER TABLE users ENABLE KEYS;
9.3 使用LOAD DATA #
sql
-- 从文件导入(更快)
LOAD DATA INFILE '/path/to/users.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(name, age, email);
十、常见错误处理 #
10.1 重复键错误 #
sql
-- 错误信息
INSERT INTO users (id, name) VALUES (1, 'John');
-- ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
-- 解决方案
INSERT IGNORE INTO users (id, name) VALUES (1, 'John');
-- 或
INSERT INTO users (id, name) VALUES (1, 'John')
ON DUPLICATE KEY UPDATE name = 'John';
10.2 非空约束错误 #
sql
-- 错误信息
INSERT INTO users (age, email) VALUES (25, 'john@example.com');
-- ERROR 1364 (HY000): Field 'name' doesn't have a default value
-- 解决方案:提供name值
INSERT INTO users (name, age, email) VALUES ('John', 25, 'john@example.com');
10.3 数据类型错误 #
sql
-- 错误信息
INSERT INTO users (name, age) VALUES ('John', 'abc');
-- ERROR 1366 (HY000): Incorrect integer value: 'abc' for column 'age'
-- 解决方案:提供正确类型
INSERT INTO users (name, age) VALUES ('John', 25);
十一、总结 #
插入数据要点:
| 方式 | 语法 | 适用场景 |
|---|---|---|
| 基本插入 | INSERT INTO … VALUES | 单行插入 |
| 批量插入 | INSERT INTO … VALUES (…), (…) | 多行插入 |
| 查询插入 | INSERT INTO … SELECT | 复制数据 |
| 存在更新 | ON DUPLICATE KEY UPDATE | 插入或更新 |
最佳实践:
- 使用批量插入提高性能
- 指定列名,避免依赖顺序
- 处理重复数据时使用INSERT IGNORE或ON DUPLICATE KEY UPDATE
- 大批量导入考虑使用LOAD DATA
下一步,让我们学习数据更新!
最后更新:2026-03-26