欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySQL删除数据(八)

程序员文章站 2024-03-08 17:12:52
...

我看到了那天的夕阳,美得如此骄艳,我便决定,追寻夕阳,拼尽余生。

上一章简单介绍了 MySQL更新数据(七),如果没有看过,请观看上一章

MySQL删除数据,是将符合条件的一行或者多行从数据库中进行删除。 但在实际的业务过程中,通常是不能删除数据的,要保留历史,常常会定义一个标识位,如write_status, 1是正常状态, 2是删除状态。 当插入,修改时,write_status的值是1, 当删除时,会将write_status更新成2,来达到删除的目的。 前台展示时,展示不出来, 但是从数据库中查询时,可以查询到。

仍然用的是 yuejl 数据库 里面的 user 表, 并修改 user表中的内容。

MySQL删除数据(八)

一. 删除命令 delete

	delete from 表名 [where 条件];

删除用的是 delete 关键字, 后面一般都要跟条件,如果不跟条件,表示删除数据表里面的所有的内容。

可以简单分为, 删除一条记录 和删除多条记录,和删除有外键的记录三种情况。

二. 删除一条记录

删除一条记录时,通常是用 主键进行指定,这样就可以唯一确定一条记录了,达到只删除一条记录的目的。

二.一 指定主键id删除一条记录

如删除 id=6的 名称叫做 小蝴蝶的数据。

	delete from user where id=6;

MySQL删除数据(八)

二.二 删除时指定的id 不存在

如删除 id=7的数据,然而 表user 中并没有这一条记录。

	delete from user where id=7;

MySQL删除数据(八)

Query OK, 0 rows affected (0.00 sec)

并不会报错,而是执行成功,只是影响的条数是0行。

这一点,与 update 更新时,不存在记录导致的结果一样(具体可以看上一章节update修改单条记录主键不存在的问题)

所以,在删除之前,我们常常验证一下, 该条记录是否还存在于数据库里面, 如果不存在了,则抛出异常,在前台提示用户 ‘该条数据已经被删除,请刷新后再提交’, 如果存在,则才执行数据库的删除语句。

三. 删除多条记录

删除多条记录时, 老蝴蝶把它分成两种情况, 一种是指定的where 条件,可以筛选出多条, 第二种是 不指定条件,全部删除。

三.一 指定的where 条件 可以筛选多条记录

如 指定 id>3 的数据, 有4和5 两条数据。 除了指定主键外,还可以指定其他的列, 如age=24 的记录, 或者 name=‘老蝴蝶的’,也或者 age 在 18到30岁之间的。

这儿用 name=‘老蝴蝶’ 的进行举例验证。

	delete from user where name='老蝴蝶';

MySQL删除数据(八)

删除了两行,还剩下三行数据。

三.二 不指定where 条件,全表删除数据

	delete from user;

MySQL删除数据(八)

发现, user 表里面的数据全部被删除了。

四. 删除有外键的记录

用 以前的 表 u和 dept 表进行验证。 dept表是父表, u表是子表。

MySQL删除数据(八)

四.一 删除父表中的没有被引用的数据

如 部门编号是 3的记录, 里面并没有相应的员工与其进行关联。 看是否能直接删除该部门?

	delete from dept where id=3;

MySQL删除数据(八)

可以直接被删除。

四.二 删除父表中被引用的数据。

如 部门编号为2的记录, 里面有岳泽霖和精小妹 两个员工。 看是否能直接删除?

	delete from dept where id=2;

MySQL删除数据(八)

Cannot delete or update a parent row: a foreign key constraint fails (yuejl.u, CONSTRAINT FK_U_deptId FOREIGN KEY (deptId) REFERENCES dept (id))

删除错误,提示有外键关联.

有两种解决方案, 一是删除外键关联,断开结构的关系,二是将子表中的deptId 修改成null, 断开数据的关系。

下面,老蝴蝶分别演示这两种情况。

四.二.一 将子表的外键属性更新为null,断开数据关系

还是以 部门编号为2的数据进行演示。 开发部下面有岳泽霖和精小妹,员工编号为 3和5.

1 .将员工3和5的 deptId 更新为 null. 然后查询

	update u set deptId=null where id=3 or id=5;

MySQL删除数据(八)

2 . 再重新删除 id=2的部门数据。

	delete from dept where id=2;

MySQL删除数据(八)

可以正常的删除了。

四.二.二 删除外键关联,断开结构的关系

这个时候,删除 id=1的部门, 还是会报错的,同样是外键关联的错误。

MySQL删除数据(八)

上面断开数据关系,仅仅是断开了 deptId=2的,并没有断开 deptId=1的,所以删除id=1的,同样会报错。

1 . 断开 外键关联。 外键的名称叫做 FK_U_deptId

	alter table u drop foreign key FK_U_deptId;

MySQL删除数据(八)

2 . 重新删除 id=1的部门记录

	delete from dept where id=1;

MySQL删除数据(八)

其中,很容易明白, 四.二.一 只是针对的某些数据进行删除外键,四.二.二 是针对父表中的所有数据,从结构上断开的。

四.二.三 删除子表数据

无论 deptId 是有值的,还是无值的,都是可以直接删除的。 外键关联,是在删除父表时起作用, 在插入子表和修改子表时起作用。 所以,删除子表,是可以直接删除的。

		 delete from u where id=3 or id=4;

MySQL删除数据(八)

四.二.四 删除父表时的引用方式

MySQL删除数据(八)

实际上 SQL 有五种方式:
1 . Restrict
2 . No Action
3 . Cascade
4. Set NULL
5. Set Default

MySQL 不支持 set Default , 故只有四种。

其中, Restrict 是默认的方式, 删除和修改时的默认方式。

Restrict : 会检查约束,如果子表中有数据,则不允许删除或者更新。
No Action: 会检查约束,如果子表中有数据,则不允许删除或者更新,与 Restrict 相同。
Cascade: 级联操作。 如果是删除的话,父表可以删除,同时将子表的中数据也删除。 如果是更新的话,父表可以更新,同时将子表 中的外键属性值数据也更新。 (hibernate 常用级别操作)

set null: 父表可以进行删除和更新,同时将 子表中的外键值设置成 null值。

五. Drop, truncate, delete 的区别

删除数据库表中的记录,有三种方式:

1 .drop table 表名

2 . truncate 表名

3 . delete from 表名

三者的侧重点是不一样的,是有很大区别的。 使用者应该根据不同的情况,使用不同的命令执行。

drop 是删除表, 不但会删除表中的数据,而且连表的结构都会删除。

truncate 只会删除表的数据,不会删除表的结构。 是一次性删除数据,相比较于 delete, 效率较高。 会释放空间,自动增长 auto_increment 也会重新开始。

delete 只会删除表的数据,不会删除表的结构。 删除时,是一行一行的删除,相比较于 truncate, 效率低。 不会释放空间, 自动增长 auto_increment 是不会重新开始的。