前两天在大家一起review我们系统的稳定性底盘的时候,忽然想起来部分我们系统中比较重的模型的删除,级联删除似乎没有做完整。删除功能的实现不好,会导致脏数据,这是个很危险的事情,但是这种问题的暴露需要足够完整的数据链才能暴露出来,这让他更危险。 那么就有几种情况可以讨论一下:
- 不好的删除实现会造成什么
- 什么样子的数据可以删除 什么不能
- 删除数据时候 一定需要级联的删除所有相关的数据吗?
- 如果要级联删除,有哪些需要注意的地方
以下提到的删除都指的是物理删除而非逻辑,逻辑删除私以为有些滥用了,他只应该出现在合同、发票等管理中,它增加了很多实现时候需要注意的地方,一切查询都要显式的带上条件,即使是使用mybatisPlus这种逻辑删除友好的orm也麻烦:(而且还有麻烦的唯一索引的问题,我不喜欢它
不好的删除实现
因为数据库大都不使用物理外键,阿里规约也要求外键在应用层解决(刚工作的时候 还在论坛上提问过这件事 hhh青涩:[传送门][123]),所以在删除的时候只删除模型 没有删除关联关系的话,那么关联关系所指向的地址就是空 就会引起问题,导致查询不到对应的模型,进而可能阻断流程。
什么样子的数据可以删除 什么不能
需要看这个模型在整个系统中有多“重”,如果是一个主打营销/获客平台的系统,那么设计上肯定是围绕着“活动”这个概念展开,如果删除活动,那活动的点击数据 停留数据是不是需要删除?否则很容易被以非活动的其他维度统计到 导致数据不准;活动的报名表单数据是不是该删除掉?报名数据是客户直接提交的和活动有关联的一切数据是不是都需要做删除?有的时候,用系统的人并不清楚他们的操作会造成多大的影响,比如他并不想让他的xx数据消失,但是你做了级联删除把那些数据也清掉了,所以我觉得比较重的一些模型,不应该设计删除功能,而是应该转而做“下架”(可以认为是另一种意义上的“逻辑删除”);
如果一定要做,那么需要明确删除的影响范围和注意删除的权限控制。
删除数据时候 一定需要级联的删除所有相关的数据吗?
我觉得不一定 但是大多数时候是需要的,如果我有一个党组织,如果我删除党组织(如果下面没有党员),那么跟他绑定的很多数据也应该删掉,比如党组织和部门的映射关系,但是,归属于某个党组织的文章数据/活动数据是不是也需要删除掉?这里就可以讨论了: 大部分操作系统文件管理设计中,删除操作基本是不会直接删除对应的文件的,而是会删除指向文件的指针,这才有恢复数据的可能,也正因为如此,mv命令/windows同磁盘剪切粘贴 才会那么快:毕竟只改变了指针的指向,同样的设计在git中也有类似的,比如checkout。所以不做级联删除也是可以的,但是这种情况是有前提的,就是文件的查询几乎是强关联于他的关联关系:即不会脱离文件目录去查询文件,所以是很少的情况。 我觉得如果是强关联的数据,比如党组织和部门的映射关系 党组织下角色的映射关系,是需要清除掉的,因为这种数据一般会有反查的情况,即根据某人 去查询他拥有的角色列表,自然也会需要显示他角色绑定的客体(党组织)。 但是如果是文章、活动等其他弱关联的模型,如果不删除可以的,因为他们的关联关系只是该模型一个不重要的一个属性,他的重心在于其内容 而非挂名的党组织,但是如果不做删除的话,就需要在查询/使用的地方有两个要求:托底策略和非强校验:查询不出来默认显示空串or展示冗余出来的党组织名称(新建模型时候冗余在模型表的)or根党组织名称,如果没有托底并且做了强校验,那就直接会报错了。 其实怎么操作:无非是三种:保护(有关联数据的情况下不允许删除) 级联删除(删除干净所有数据) 忽略关联的强行删除(部分数据不考虑完整性,忽略他们 直接删除元数据)。