我必须维护一个未正确规范化的旧数据库。例如,对于项目的不同里程碑从订购到交货日期,有一个项目表已经增长(或可能是如雨后春笋般出色),有5个或更多不同的日期列。还有几个表,每个表都有街道地址,邮件地址或网络链接的列。
我想规范化结构,创建地址表,计划日期等,以及允许1:N关系的必要表(每个客户的地址,每个项目的截止日期等)。
现在我完全不确定如何处理详细信息表中数据的更改。例如,考虑更改客户交货地址。更改地址表中的数据是不可能的,因为多个记录(可能在多个表中)可以引用该记录。如果没有其他行与它有外键关系,添加新地址记录可能会使旧记录成为孤立状态。
我已经考虑过以下方法来解决这个问题:
添加新的详细记录,并检查主表的更新触发器是否必须删除旧的详细记录。这需要了解所有与详细信息表有关系的表,在所有表中或在sproc中。我不喜欢这种失去分离。它还将涉及活动事务中的更多表。
让触发器尝试删除旧的详细记录,并捕获任何错误。这只是感觉不对。
使用孤立记录,并定期维护任务清理所有详细信息表。
在链接到多个主表的详细信息表中处理数据更改的首选方法是什么?有关阅读的任何提示吗?
答案 0 :(得分:6)
部分问题可能是原始架构设计:外键指向错误的方式,将地址,电话号码等视为主设备而不是详细信息。当您希望一次性更新给定地址的所有用途时,这可能很方便,但根据我的经验,它总是会转移到太多困难的特殊情况,例如某个位置的一个人移动,因此您需要打破他们的链接而不是整个家庭或办公室搬家,以便您更新现有记录。如果您尝试在CRUD屏幕上隐藏用户的这些详细信息,您最终会遇到无法满足要求的情况。
如果这样做只是为了折叠重复值,它实际上是数据库的非规范化:仅仅存在地址行是没有意义的。唯一的区别是,与大多数非规范化不同,它试图获得空间效率而不是速度。此时创建链接表只会使问题复杂化。
如果你想要,例如,每个联系人多个地址,使地址成为一个详细信息表,外键指向父联系人,并且不要担心重复的地址值,因为他们只是值的。否则,将地址设为真实实体:添加标题或说明字段和CRUD屏幕,使其可以作为实体独立存在。
答案 1 :(得分:3)
使用孤立记录,并定期维护任务清理所有详细信息表。
答案 2 :(得分:0)
我认为你正在模糊删除和更新案例。
如果你有客户端a和客户端b,并且两者都使用相同的地址,那将由关系表中的记录反映出来(比如ClientAddresses,尽管如果你要存储多个实体的地址,我相信它会是比那更复杂)
我认为如果两个客户共享和地址并且它对客户端不正确,那么对于客户端b也是不正确的(即数据输入错误),但如果您确定不希望客户端更改为对基本地址信息进行删除,删除关联记录(从ClientAddresses中删除)并添加新地址。当你从关系表(可能是从存储过程)执行删除时,检查是否有任何其他记录引用地址记录被解除关联,如果不是从基表中删除。