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