数据增删改
数据增删改
就像管理一个仓库——进货入库(INSERT)、调整货架标签(UPDATE)、清理过期商品(DELETE)、清空整个仓库(TRUNCATE),数据库的增删改操作是日常数据管理的核心。学会安全地操作数据,比学会操作本身更重要。
1. 核心概念
| 概念 | 说明 |
|---|---|
INSERT INTO |
向表中插入新数据,支持单行和多行插入 |
UPDATE ... SET |
修改表中已有数据,必须搭配 WHERE 限定范围 |
DELETE FROM |
删除表中指定行,必须搭配 WHERE 限定范围 |
TRUNCATE TABLE |
快速清空整张表的所有数据,比 DELETE 快但更危险 |
| 安全操作习惯 | 执行 DELETE/UPDATE 前,先用 SELECT 确认影响范围 |
⚠️ 核心警告: 没有 WHERE 的 UPDATE 和 DELETE 会操作整张表的所有行!这是新手最常犯的灾难性错误。
2. 基本语法
INSERT INTO — 插入数据
SQL
-- 插入单行(指定列)
INSERT INTO 表名 (列1, 列2, 列3)
VALUES (值1, 值2, 值3);
-- 插入单行(所有列,按建表顺序)
INSERT INTO 表名
VALUES (值1, 值2, 值3);
-- 插入多行
INSERT INTO 表名 (列1, 列2)
VALUES (值1, 值2),
(值3, 值4),
(值5, 值6);
💡 提示:强烈建议指定列名,不要依赖列的默认顺序。如果表结构发生变化(比如新增列),不指定列名的 INSERT 语句可能会报错或插入错误数据。
UPDATE — 更新数据
SQL
-- 更新指定行
UPDATE 表名
SET 列1 = 新值1, 列2 = 新值2
WHERE 条件;
-- 结合表达式更新
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 1;
💡 提示:执行 UPDATE 前,先用 SELECT 确认 WHERE 条件匹配的行。比如先执行
SELECT * FROM employees WHERE department_id = 1; 看看会涉及多少行。
DELETE — 删除数据
SQL
-- 删除指定行
DELETE FROM 表名
WHERE 条件;
-- 删除所有行(逐行删除,保留表结构)
DELETE FROM 表名;
💡 提示:DELETE 删除的数据可以通过事务回滚恢复(如果在事务中),但提交后就无法恢复了。养成习惯:先 SELECT 再 DELETE。
TRUNCATE — 清空表
SQL
-- 清空整张表(保留表结构)
TRUNCATE TABLE 表名;
💡 提示:TRUNCATE 在 SQLite 中等价于
DELETE FROM 表名(SQLite 不支持 TRUNCATE 语法)。在 MySQL/PostgreSQL 中,TRUNCATE 比 DELETE 快得多,因为它不逐行删除,且会重置自增 ID。
INSERT vs DELETE vs TRUNCATE 对比
| 操作 | 作用 | 可回滚 | 重置自增ID | 速度 |
|---|---|---|---|---|
INSERT |
插入新行 | ✅ | — | — |
DELETE |
逐行删除(可带 WHERE) | ✅ | ❌ | 慢 |
TRUNCATE |
清空整张表 | ❌ | ✅ | 快 |
3. 示例代码
示例:插入员工和部门数据(难度⭐)
向部门表和员工表插入初始数据。
SQL
-- 先插入部门数据
INSERT INTO departments (name, location)
VALUES ('技术部', '北京'),
('市场部', '上海'),
('财务部', '北京');
-- 再插入员工数据
INSERT INTO employees (name, department_id, salary, hire_date)
VALUES ('张三', 1, 15000.00, '2023-01-15'),
('李四', 1, 18000.00, '2022-06-01'),
('王五', 2, 12000.00, '2023-03-20'),
('赵六', 3, 13000.00, '2021-11-10');
-- 验证插入结果
SELECT * FROM departments;
输出:
TEXT
id name location
-- ------ --------
1 技术部 北京
2 市场部 上海
3 财务部 北京
示例:安全更新员工薪资(难度⭐⭐)
给技术部所有员工加薪 10%,先确认再执行。
SQL
-- 第一步:用 SELECT 确认影响范围
SELECT name, salary
FROM employees
WHERE department_id = 1;
确认前:
TEXT
name salary
------ --------
张三 15000.00
李四 18000.00
SQL
-- 第二步:确认无误后执行更新
UPDATE employees
SET salary = salary * 1.1
WHERE department_id = 1;
-- 第三步:验证更新结果
SELECT name, salary
FROM employees
WHERE department_id = 1;
更新后:
TEXT
name salary
------ --------
张三 16500.00
李四 19800.00
示例:删除与清空操作对比(难度⭐⭐⭐)
对比 DELETE 和 TRUNCATE 的行为差异。
SQL
-- 创建临时测试表
CREATE TABLE test_delete (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT
);
-- 插入测试数据
INSERT INTO test_delete (name) VALUES ('A'), ('B'), ('C');
-- 用 DELETE 删除指定行
DELETE FROM test_delete WHERE name = 'B';
SELECT * FROM test_delete;
输出:
TEXT
id name
-- ----
1 A
3 C
SQL
-- 用 DELETE 清空剩余数据
DELETE FROM test_delete;
-- 再插入新数据,观察自增 ID
INSERT INTO test_delete (name) VALUES ('D');
SELECT * FROM test_delete;
输出(注意 ID 从 4 开始,自增 ID 没有重置):
TEXT
id name
-- ----
4 D
💡 在 MySQL 中,如果用
TRUNCATE TABLE test_delete; 清空,再插入时 ID 会从 1 重新开始。
4. 常见应用场景
场景一:批量导入数据
从临时表或外部数据源批量导入:
SQL
-- 将高薪员工复制到备份表
INSERT INTO employees_backup (name, department_id, salary, hire_date)
SELECT name, department_id, salary, hire_date
FROM employees
WHERE salary > 15000;
场景二:条件性批量更新
调整特定条件下的数据:
SQL
-- 将入职超过3年的员工薪资上调 5%
UPDATE employees
SET salary = salary * 1.05
WHERE hire_date < DATE('now', '-3 years');
❓ 常见问题
Q DELETE 和 TRUNCATE 都能清空表,该用哪个?
A 如果需要清空整张表且不关心自增 ID,用 TRUNCATE(更快);如果需要删除部分数据或想保留回滚能力,用 DELETE。日常开发中 DELETE 更安全,TRUNCATE 通常只在初始化测试数据时使用。
Q 忘记写 WHERE 条件把整张表都更新了怎么办?
A 如果还没提交事务,立即 ROLLBACK 回滚。如果已经提交,在 MySQL 中可以通过 binlog 恢复;在 SQLite 中如果没有备份就很难恢复了。所以执行 UPDATE/DELETE 前一定要先 SELECT 确认。
Q INSERT 时某些列不想填值怎么办?
A 不写在 INSERT 的列列表中即可,这些列会使用默认值(DEFAULT)或 NULL。例如
INSERT INTO employees (name, salary) VALUES ('新员工', 10000); 不填 department_id 和 hire_date,它们会是 NULL。Q SQLite 支持 TRUNCATE 吗?
A 不支持。SQLite 中用
DELETE FROM 表名; 代替,效果相同但自增 ID 不会重置。如果需要重置自增 ID,可以在删除后执行 DELETE FROM sqlite_sequence WHERE name='表名';。📖 小节
- INSERT INTO 用于插入数据,建议始终指定列名,支持一次插入多行
- UPDATE SET 用于更新数据,必须搭配 WHERE 条件,否则会更新整张表
- DELETE FROM 用于删除数据,必须搭配 WHERE 条件,否则会删除整张表
- TRUNCATE TABLE 用于快速清空整张表,比 DELETE 快但不可回滚
- 安全习惯:执行 DELETE 或 UPDATE 前,先用 SELECT 确认影响范围
- SQLite 不支持 TRUNCATE,用
DELETE FROM 表名代替
📝 作业
练习 1(⭐)
向 products 表插入以下商品数据,然后查询验证:
| name | category | price | stock |
|---|---|---|---|
| iPhone 15 | 手机 | 5999.00 | 100 |
| MacBook Pro | 电脑 | 12999.00 | 50 |
| AirPods Pro | 配件 | 1899.00 | 200 |
| iPad Air | 平板 | 4799.00 | 80 |
练习 2(⭐⭐)
完成以下操作,每步操作前先写 SELECT 确认:
- 将所有库存低于 100 的商品价格上调 5%
- 将"配件"类别的商品库存增加 50
- 删除价格低于 2000 的商品
练习 3(⭐⭐⭐)
模拟一个"商品下架"流程:
- 将 products 表中 stock = 0 的商品复制到 products_offline 表(先建表)
- 从 products 表中删除这些无库存商品
- 验证两个表的数据是否正确



