删除数据指将数据从数据库表中删除,实际开发中,通常需要根据条件删除一些不要的、废弃的数据,如用户数据、商品数据等等,这样可以避免无效数据占用数据库表空间,数据表的大小会影响 SQL 查询性能。
在数据库操作中,删除数据也是核心的、非常重要的操作之一。本文将结合 user 表结构,详细讲解 SQL 中删除数据的核心语法、使用场景及注意事项。
DELETE 是 SQL 中删除表中单行或多行数据的核心语句,不会删除表结构,仅删除数据行。
语法结构如下:
DELETE FROM 表名 [WHERE 条件] [ORDER BY 字段] [LIMIT 数量];
详细说明:
FROM:指定要删除数据的表名(本文以 user 表为例);
WHERE:可选,指定删除条件,无此子句时会删除表中所有数据。实际开发中,甚至一些公司明确要求删除语句必须携带 WHERE 条件,因为不携带 WHERE 条件太危险了,一不小心真个表的数据就没有了。除非明确需要删除整个表的数据。
ORDER BY:可选,指定删除数据的顺序(常与 LIMIT 配合);
LIMIT:可选,限制删除的行数。
为了演示删除操作,这里使用 CREATE TABLE ... SELECT 语句创建 user 表的备份表,我们对备份表进行删除操作。
(1)创建备份表 user_backup
> CREATE TABLE user_backup SELECT * FROM user 17 row(s) modified.
验证备份表中的数据,如下:
> SELECT * FROM user_backup user_id|name |gender|age|phone |email |address |create_time |update_time | -------+---------+------+---+-----------+----------------------+---------------+-------------------+-------------------+ 1|张三-UPDATE|男 | 25|13800138000|zhangsan@example.com |北京市朝阳区建国路88号 |2025-01-18 02:03:00|2026-01-05 07:01:50| 2|李四 |女 | 30|13800138099|zhangsan99@example.com|北京市朝阳区99号 |2025-01-14 13:09:00|2026-01-05 07:08:38| 3|王五 |男 | 28|13800138002|wangwu@example.com |广州市天河区天河路385号 |2025-01-17 11:38:00|2025-12-31 03:18:07| 4|赵六 |女 | 23|13800138003|zhaoliu@example.com |深圳市南山区科技园10号 |2025-01-12 18:42:00|2026-01-05 07:11:20| 5|孙七 |男 | 35|13800138004| |杭州市西湖区西湖路58号 |2025-01-10 10:38:00|2025-12-31 03:18:07| 6|周八 |女 | 27|13800138005|zhouba@example.com |成都市武侯区武侯祠大街231号|2025-01-12 21:04:00|2025-12-31 03:18:07| 7|吴九 | | 32|13800138006|wujiu@example.com |重庆市渝中区解放碑路18号 |2025-01-02 01:26:00|2025-12-31 03:18:07| 8|郑十 |女 | 29|13800138007|zhengshi@example.com |武汉市武昌区中南路99号 |2025-01-30 16:00:00|2025-12-31 03:18:07| 9|钱十一 |男 | 25|13800138008|qianshiyi@example.com |西安市雁塔区雁塔路15号 |2025-01-26 03:42:00|2026-01-05 07:11:20| 10|孙十二 |女 | 31|13800138009| |南京市玄武区玄武湖路78号 |2025-01-07 18:32:00|2025-12-31 03:18:07| 11|TEST |男 | 22|13800138901|test@example.com |成都市天府大道27号 |2026-01-05 03:42:42|2026-01-05 07:11:20| 12|TEST2 |男 | 22|13800138902|test2@example.com |成都市天府大道27号 |2026-01-05 05:45:00|2026-01-05 07:11:20| 13|TEST3 |男 | 22|13800138903|test3@example.com |成都市天府大道27号 |2026-01-05 05:48:06|2026-01-05 07:11:20| 14|TEST4 |男 | 22|13800138904|test4@example.com |成都市天府大道27号 |2026-01-05 05:52:19|2026-01-05 07:11:20| 15|TEST5 |男 | | | | |2026-01-05 05:58:39|2026-01-05 07:05:25| 16|TEST6 |男 | | | | |2026-01-05 06:00:16|2026-01-05 07:05:25| 17|TEST7 |男 | | | | |2026-01-05 06:02:30|2026-01-05 07:05:25| 17 row(s) fetched.
使用 DELETE 语句删除性别为 “男”,且对 user_id 递减排序的前 5 条记录,例如:
> DELETE FROM `user_backup` WHERE gender='男' ORDER BY user_id DESC LIMIT 5 5 row(s) modified.
再次查看备份表中的数据:
> SELECT * FROM user_backup user_id|name |gender|age|phone |email |address |create_time |update_time | -------+---------+------+---+-----------+----------------------+---------------+-------------------+-------------------+ 1|张三-UPDATE|男 | 25|13800138000|zhangsan@example.com |北京市朝阳区建国路88号 |2025-01-18 02:03:00|2026-01-05 07:01:50| 2|李四 |女 | 30|13800138099|zhangsan99@example.com|北京市朝阳区99号 |2025-01-14 13:09:00|2026-01-05 07:08:38| 3|王五 |男 | 28|13800138002|wangwu@example.com |广州市天河区天河路385号 |2025-01-17 11:38:00|2025-12-31 03:18:07| 4|赵六 |女 | 23|13800138003|zhaoliu@example.com |深圳市南山区科技园10号 |2025-01-12 18:42:00|2026-01-05 07:11:20| 5|孙七 |男 | 35|13800138004| |杭州市西湖区西湖路58号 |2025-01-10 10:38:00|2025-12-31 03:18:07| 6|周八 |女 | 27|13800138005|zhouba@example.com |成都市武侯区武侯祠大街231号|2025-01-12 21:04:00|2025-12-31 03:18:07| 7|吴九 | | 32|13800138006|wujiu@example.com |重庆市渝中区解放碑路18号 |2025-01-02 01:26:00|2025-12-31 03:18:07| 8|郑十 |女 | 29|13800138007|zhengshi@example.com |武汉市武昌区中南路99号 |2025-01-30 16:00:00|2025-12-31 03:18:07| 9|钱十一 |男 | 25|13800138008|qianshiyi@example.com |西安市雁塔区雁塔路15号 |2025-01-26 03:42:00|2026-01-05 07:11:20| 10|孙十二 |女 | 31|13800138009| |南京市玄武区玄武湖路78号 |2025-01-07 18:32:00|2025-12-31 03:18:07| 11|TEST |男 | 22|13800138901|test@example.com |成都市天府大道27号 |2026-01-05 03:42:42|2026-01-05 07:11:20| 12|TEST2 |男 | 22|13800138902|test2@example.com |成都市天府大道27号 |2026-01-05 05:45:00|2026-01-05 07:11:20| 12 row(s) fetched.
从输出可知,已经删除了 5 条记录,ID 分别为 13、14、15、16、17。
下面示例将结合 user_backup 表的字段(user_id、name、gender、age 等)进行删除操作。
最常用的场景是通过唯一标识(如 user_id)删除指定用户,避免误删其他数据。例如:
-- 删除 user_id 为 1 的用户数据 > DELETE FROM `user_backup` WHERE user_id = 1 1 row(s) modified.
注意,user_id 是主键,唯一标识一条用户数据,此操作仅删除该用户的所有信息。
根据业务条件删除符合要求的一批用户数据,例如,删除性别为 “男”,姓名以 “TEST” 开头的用户信息:
> DELETE FROM `user_backup` WHERE gender='男' AND name LIKE 'TEST%' 2 row(s) modified.
补充场景示例:
-- 删除手机号为 13800138000 的用户(phone 是唯一索引,通常仅一条) DELETE FROM `user_backup` WHERE phone = '13800138000'; -- 删除创建时间在 2023-01-01 之前的用户 DELETE FROM `user_backup` WHERE create_time < '2023-01-01 00:00:00';
当需要删除符合条件数据量较大,且只需删除部分时,使用 LIMIT 限制行数:
-- 删除性别为 “男” 用户,最多删除 2 条 -- 查询数据,有3条符合条件的数据 > SELECT * FROM `user_backup` WHERE gender='男' user_id|name|gender|age|phone |email |address |create_time |update_time | -------+----+------+---+-----------+---------------------+-------------+-------------------+-------------------+ 3|王五 |男 | 28|13800138002|wangwu@example.com |广州市天河区天河路385号|2025-01-17 11:38:00|2025-12-31 03:18:07| 5|孙七 |男 | 35|13800138004| |杭州市西湖区西湖路58号 |2025-01-10 10:38:00|2025-12-31 03:18:07| 9|钱十一 |男 | 25|13800138008|qianshiyi@example.com|西安市雁塔区雁塔路15号 |2025-01-26 03:42:00|2026-01-05 07:11:20| 3 row(s) fetched. -- 删除两条数据 > DELETE FROM `user_backup` WHERE gender='男' LIMIT 2 2 row(s) modified. -- 验证数据,现在仅剩余一条数据 > SELECT * FROM `user_backup` WHERE gender='男' user_id|name|gender|age|phone |email |address |create_time |update_time | -------+----+------+---+-----------+---------------------+------------+-------------------+-------------------+ 9|钱十一 |男 | 25|13800138008|qianshiyi@example.com|西安市雁塔区雁塔路15号|2025-01-26 03:42:00|2026-01-05 07:11:20| 1 row(s) fetched.
注意:若需按指定顺序删除(如先删创建时间最早的),可结合 ORDER BY:
-- 按创建时间升序,删除最早的 5 条未知性别的用户数据 DELETE FROM `user_backup` WHERE gender='未知' ORDER BY create_time ASC LIMIT 5;
若需清空 user 表的所有数据(保留表结构),可省略 WHERE 子句:
-- 清空 user_backup 表所有数据(无 WHERE 条件,谨慎使用!) DELETE FROM `user_backup`;
重要提醒:此操作会删除表中所有用户数据,且无法通过普通事务回滚(若未开启事务),执行前务必确认。
TRUNCATE 是 SQL 中的数据定义语言(DDL) 语句,核心作用是快速清空数据库表中的所有数据行,同时保留表的结构(包括字段、索引、约束等),常被用于批量清空表数据的场景。
那么,DELETE 与 TRUNCATE 有哪些区别呢?二者主要区别如下:
特性 | DELETE | TRUNCATE |
操作类型 | DML(数据操作语言) | DDL(数据定义语言) |
条件删除 | 支持 WHERE 条件,可删指定数据 | 不支持,只能清空全表 |
自增主键 | 自增 ID 继续从上次最大值递增 | 重置自增 ID 为初始值(如 1) |
事务回滚 | 支持(InnoDB 引擎下开启事务时) | 不支持(执行后立即生效) |
执行效率 | 逐行删除,数据量大时效率低 | 直接清空表,效率极高 |
示例:清空 user 表并重置自增 ID):
-- 慎用:清空 user_backup 表所有数据,重置 user_id 自增为 1 TRUNCATE TABLE `user_backup`;
(1)先查后删:执行 DELETE 前,先用 SELECT 验证条件是否正确,避免误删:
-- 先查询符合条件的用户,确认无误后再删除 SELECT * FROM `user_backup` WHERE gender='未知' LIMIT 10;
(2)开启事务:InnoDB 引擎下,建议在事务中执行删除操作,便于出错时回滚:
BEGIN; -- 开启事务 DELETE FROM `user` WHERE user_id = 12; -- 确认无误后提交,否则执行 ROLLBACK; 回滚 COMMIT;
(3)索引影响:删除操作会触发索引更新(如 phone、email 唯一索引),大批量删除时可先临时禁用索引,数据删除后重建,提升效率。
(4)权限控制:确保操作账号仅拥有必要的删除权限,避免误操作全库数据。