今天这篇文章要讲的是我在做项目开发时,遇到的一个思路性的问题:即如何通过删除某张表的一条数据,完成其关联表中相关数据的快速、便捷删除。
问题重现:
我的数据库中设计了A、B、C、D……等多张表,其中A表的主键uuid是B、C、D……表的外键。而我在页面上进行数据展示时,默认展示的是C表中的基础数据(表1),当用户需要查看更多的信息时,可以通过点击 button 来查看选中状态下的一条数据对应的A、B、D……表中的更多关联数据(表2)。
eg:(加粗表示选中状态,倾斜字体表示按钮)
表1
—————————————
序号 | 姓名 | 年龄 | 性别 |操作 班级信息
—————————————
1 | 张三 | 14 | 男 | 删除
—————————————
2 | 李四 | 15 | 女 | 删除
—————————————
当我点击过“班级信息”按钮后图表如下:
表2
—————————————
序号 | 姓名 | 年龄 | 性别 | 操作 班级信息
—————————————
1 | 张三 | 14 | 男 | 删除
—————————————
1.1 | 学校 | 年级 | 班号
—————————————
| 小学 | 小班 | 一班
—————————————
2 | 李四 | 15 | 女 | 删除
—————————————
此时,当我删除“张三”这条数据后,其他表中的相关联的数据就将成为垃圾数据。为了解决这个问题,我想到了以下两种方式:
- 在 controller 层中,调用“张三”基础数据删除方法的同时调用其他相关连表的删除方法。然而,这样的弊端将会是“大大的”。首先,我们为了调用其他表的删除方法,我们不得不在“张三”基础数据的controller 层中注入其他表的 service 层接口来帮我们完成其他表的删除操作。这样无形中就增加了我们的代码量。其次,这样一来会消耗更多的内存空间,并且由于频繁的与数据库进行连接操作,直接影响到了代码的执行效率。
- 通过在mysql数据库中编写触发器,进行相关数据的删除操作。如此我们就不用注入多个service 层接口,节省了内存空间;而且只需要对数据库进行一次连接操作即可删除剩余垃圾数据;同时,由于触发器是数据库中自身的功能所以要比java代码执行sql更快。
eg:
create trigger deleteAllInfo
after
delete
on vip
for each row
begin
delete from daily where daily.dai_col_uuid = old.vip_col_uuid;
delete from dining where dining.din_col_uuid = old.vip_col_uuid;
delete from environment where environment.env_col_uuid = old.vip_col_uuid;
delete from medicalhistory where medicalhistory.med_col_uuid = old.vip_col_uuid;
delete from otherbehavior where otherbehavior.oth_col_uuid = old.vip_col_uuid;
delete from relatives where relatives.rel_col_uuid = old.vip_col_uuid;
delete from sport where sport.spo_col_uuid = old.vip_col_uuid;
delete from `work` where `work`.wor_col_uuid = old.vip_col_uuid;
delete from collectivity where collectivity.col_uuid = old.vip_col_uuid;
end
PS:1>触发器相关知识请自行度娘
2>细心的同学不难发现,上面的代码中单词 work 前后添加的两个特殊符号,究其原因是 work 为mysql中的关键字,所以 work 表无法直接被识别,故加上了转义符号。该符号为英文状态下 tab 键上方的 ~ 键
3>数据表设计时尽量避免数据库中的关键字出现在字段或表名中