代码之家  ›  专栏  ›  技术社区  ›  mghie

如何防止规范化数据库明细表中的孤立记录?

  •  1
  • mghie  · 技术社区  · 17 年前

    我必须维护一个未正确规范化的旧数据库。例如,对于项目从订购到交付日期的不同里程碑,有一个项目表已经增长(或者可能迅速增长)到有5个或更多不同的日期列。还有几个表,每个表都有用于街道地址、邮件地址或web链接的列。

    我想规范化结构,为地址、计划日期等创建表,并创建必要的表以允许1:N关系(每个客户的地址、每个项目的截止日期等等)。

    现在我完全不确定如何处理对细节表中数据的更改。例如,考虑客户交付地址的变更。更改地址表中的数据是不可能的,因为多个记录(可能在多个表中)可以引用该记录。如果没有其他行与旧记录有外键关系,则添加新地址记录可能会使旧记录成为孤立记录。

    我考虑过以下处理方法:

    • 让触发器尝试删除旧的详细信息记录,并捕获任何错误。这感觉不对。

    处理链接到多个主表的明细表中的数据更改的首选方法是什么?有没有阅读这篇文章的技巧?

    3 回复  |  直到 17 年前
        1
  •  6
  •   Jeffrey Hantin    17 年前

    问题的一部分可能是原始的模式设计:外键指向错误的方向,将地址、电话号码等视为主要内容而不是细节。当您希望同时更新给定地址的所有用途时,这可能很方便,但根据我的经验,它总是会演变为太多困难的例外情况,例如某个位置的一个人移动,因此您需要断开他们与整个家庭或办公室移动的链接,以便更新现有记录。如果您试图在CRUD屏幕上对用户隐藏此详细信息,那么最终会出现这样一种情况,即它无法满足您的需要。

    如果这样做只是为了折叠重复的值,那么实际上是数据库的非规范化:仅仅存在地址行是没有意义的。唯一的区别是,与大多数非规范化不同,它试图获得空间效率而不是速度。在这一点上创建链接表只会使问题更加复杂。

    例如,如果您希望每个联系人有多个地址,请将地址设置为一个带有外键的详细信息表,外键指向父联系人,并且不必担心重复的地址值,因为 它们只是价值观 . 否则,将Address设置为真实实体:添加标题或描述字段和CRUD屏幕,使其能够作为实体独立存在。

        2
  •  3
  •   l_39217_l    17 年前

        3
  •  0
  •   cmsjr    17 年前

    我认为您正在模糊删除和更新案例。

    如果您有客户机a和客户机b,并且两者都使用相同的地址,这将通过关系表中的记录反映出来(比如说客户机地址,尽管如果您存储多个实体的地址,我相信它会比这更复杂)