数据操作语言 (DML)
DML (Data Manipulation Language) 用于对数据库中的数据进行增删改操作。
INSERT 插入数据
基本语法
-- 语法
INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);插入单行数据
-- 指定列名插入(推荐)
INSERT INTO employees (name, department, salary, age, hire_date)
VALUES ('新员工', '技术部', 12000, 26, '2024-01-15');
-- 省略列名(需要按顺序提供所有列的值,不推荐)
INSERT INTO employees
VALUES (NULL, '新员工2', '市场部', 11000, 24, '2024-02-01');插入多行数据
-- 一次插入多行(高效)
INSERT INTO employees (name, department, salary, age, hire_date) VALUES
('员工A', '技术部', 13000, 27, '2024-01-10'),
('员工B', '市场部', 11000, 25, '2024-01-12'),
('员工C', '人事部', 10000, 23, '2024-01-15');插入查询结果
-- 从其他表复制数据
INSERT INTO employees_backup (name, department, salary)
SELECT name, department, salary
FROM employees
WHERE department = '技术部';插入或更新 (UPSERT)
-- MySQL: ON DUPLICATE KEY UPDATE
INSERT INTO employees (id, name, salary)
VALUES (1, '张三', 16000)
ON DUPLICATE KEY UPDATE salary = VALUES(salary);
-- MySQL 8.0+: INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO employees (id, name, salary)
VALUES (1, '张三', 16000) AS new
ON DUPLICATE KEY UPDATE salary = new.salary;
-- PostgreSQL: ON CONFLICT
INSERT INTO employees (id, name, salary)
VALUES (1, '张三', 16000)
ON CONFLICT (id) DO UPDATE SET salary = EXCLUDED.salary;忽略重复插入
-- MySQL: INSERT IGNORE
INSERT IGNORE INTO employees (id, name, salary)
VALUES (1, '张三', 16000); -- 如果 id=1 存在,则忽略
-- PostgreSQL: ON CONFLICT DO NOTHING
INSERT INTO employees (id, name, salary)
VALUES (1, '张三', 16000)
ON CONFLICT DO NOTHING;UPDATE 更新数据
基本语法
-- 语法
UPDATE 表名 SET 列1 = 值1, 列2 = 值2 WHERE 条件;更新单列
-- 给张三加薪
UPDATE employees
SET salary = 18000
WHERE name = '张三';更新多列
-- 更新多个字段
UPDATE employees
SET salary = 20000, department = '研发部'
WHERE id = 1;基于计算更新
-- 所有人薪资上涨 10%
UPDATE employees
SET salary = salary * 1.1;
-- 技术部员工薪资上涨 15%
UPDATE employees
SET salary = salary * 1.15
WHERE department = '技术部';使用子查询更新
-- 将薪资更新为部门平均薪资
UPDATE employees e
SET salary = (
SELECT AVG(salary)
FROM employees
WHERE department = e.department
)
WHERE salary < 10000;更新注意事项
-- ⚠️ 危险:不加 WHERE 会更新所有行!
UPDATE employees SET salary = 0; -- 这会清空所有人的薪资!
-- ✅ 安全:先用 SELECT 验证条件
SELECT * FROM employees WHERE department = '技术部';
-- 确认无误后再执行 UPDATE
UPDATE employees SET salary = salary * 1.1 WHERE department = '技术部';DELETE 删除数据
基本语法
-- 语法
DELETE FROM 表名 WHERE 条件;删除指定行
-- 删除指定员工
DELETE FROM employees WHERE id = 10;
-- 删除离职员工
DELETE FROM employees WHERE status = 'resigned';删除多行
-- 删除所有实习生
DELETE FROM employees WHERE department = '实习生';
-- 删除薪资低于 8000 的员工
DELETE FROM employees WHERE salary < 8000;删除所有数据
-- 方式1:DELETE(可回滚,保留表结构和自增值)
DELETE FROM employees;
-- 方式2:TRUNCATE(更快,重置自增值,不可回滚)
TRUNCATE TABLE employees;DELETE vs TRUNCATE
| 特性 | DELETE | TRUNCATE |
|---|---|---|
| 删除方式 | 逐行删除 | 删除整个表数据 |
| 速度 | 慢(大数据量) | 快 |
| WHERE 条件 | 支持 | 不支持 |
| 事务回滚 | 支持 | 不支持(DDL) |
| 自增值 | 保留 | 重置 |
| 触发器 | 触发 | 不触发 |
删除注意事项
-- ⚠️ 危险:不加 WHERE 会删除所有数据!
DELETE FROM employees; -- 删除所有员工!
-- ✅ 安全:先用 SELECT 验证
SELECT * FROM employees WHERE hire_date < '2018-01-01';
-- 确认后再删除
DELETE FROM employees WHERE hire_date < '2018-01-01';
-- ✅ 使用 LIMIT 限制删除数量
DELETE FROM employees WHERE status = 'inactive' LIMIT 100;事务中的 DML
-- 开启事务
START TRANSACTION; -- 或 BEGIN;
-- 执行多个 DML 操作
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
-- 如果都成功,提交
COMMIT;
-- 如果有问题,回滚
-- ROLLBACK;返回受影响的行
-- MySQL: 使用 ROW_COUNT()
UPDATE employees SET salary = salary * 1.1 WHERE department = '技术部';
SELECT ROW_COUNT(); -- 返回更新的行数
-- PostgreSQL: 使用 RETURNING
UPDATE employees
SET salary = salary * 1.1
WHERE department = '技术部'
RETURNING *; -- 返回更新后的数据
DELETE FROM employees
WHERE id = 10
RETURNING id, name; -- 返回删除的数据实践示例
批量更新优化
-- 方式1:CASE WHEN(一条语句批量更新)
UPDATE employees
SET salary = CASE id
WHEN 1 THEN 15000
WHEN 2 THEN 18000
WHEN 3 THEN 12000
ELSE salary
END
WHERE id IN (1, 2, 3);
-- 方式2:临时表 JOIN 更新
CREATE TEMPORARY TABLE salary_updates (
id INT,
new_salary DECIMAL(10, 2)
);
INSERT INTO salary_updates VALUES (1, 15000), (2, 18000), (3, 12000);
UPDATE employees e
JOIN salary_updates s ON e.id = s.id
SET e.salary = s.new_salary;安全删除(软删除)
-- 添加删除标记列
ALTER TABLE employees ADD COLUMN is_deleted BOOLEAN DEFAULT FALSE;
-- 软删除:更新标记而非真正删除
UPDATE employees SET is_deleted = TRUE WHERE id = 10;
-- 查询时过滤已删除数据
SELECT * FROM employees WHERE is_deleted = FALSE;总结
| 操作 | 关键字 | 示例 |
|---|---|---|
| 插入 | INSERT | INSERT INTO t (a, b) VALUES (1, 2) |
| 更新 | UPDATE | UPDATE t SET a = 1 WHERE id = 1 |
| 删除 | DELETE | DELETE FROM t WHERE id = 1 |
| 清空 | TRUNCATE | TRUNCATE TABLE t |
最佳实践
- UPDATE/DELETE 前先 SELECT:验证 WHERE 条件
- 使用事务:保证数据一致性
- 避免无 WHERE 的 UPDATE/DELETE:防止误操作
- 考虑软删除:保留数据可追溯
上一节:02-数据查询基础 下一节:04-高级查询技巧 — JOIN 与子查询