【问题标题】:How to prevent orphaned records in detail tables of normalized database?如何防止规范化数据库明细表中的孤立记录?
【发布时间】:2010-10-01 16:57:07
【问题描述】:

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

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

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

我想过以下几种方式来处理:

  • 添加新的明细记录,并在主表的更新触发器中检查是否必须删除旧的明细记录。这将需要所有与详细表有关系的表的知识,在所有表中或在存储过程中。我不喜欢这种失去分离的感觉。它还会在活动事务中涉及更多表。

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

  • 使用孤立记录,并执行定期维护任务清理所有详细信息表。

在链接到多个主表的明细表中处理数据更改的首选方法是什么?阅读此内容的任何提示?

【问题讨论】:

    标签: database-design normalizing


    【解决方案1】:

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

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

    例如,如果您希望每个联系人有多个地址,请将地址设为详细表,并使用指向父联系人的外键,不要担心重复的地址值,因为 它们只是值。否则,让 Address 成为一个真实的实体:添加一个标题或描述字段和一个 CRUD 屏幕,这样它就可以作为一个实体独立存在。

    【讨论】:

    • 原来的schema设计没有外键,想往这个方向修改schema。我将不得不考虑你的答案,看起来键指向错误的方式可能会有所帮助。
    • 经过一番思考,我有点同意你的最后一段 - 但“它们只是价值观”的真正含义是什么?这不是完全忽略规范化规则吗?我对这样一个表的想法感到不舒服
    • 从某种意义上说,这就像担心图像中有这么多具有​​相同颜色值的像素,它们仅在坐标上有所不同。您可能希望使用某种压缩方式——空间优化——用于传输或存储目的,但压缩的图像文件不能有效地读取和写入单个任意像素。
    【解决方案2】:

    使用孤立的记录,并定期进行维护任务以清理所有详细信息表。

    【讨论】:

      【解决方案3】:

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

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

      我认为,如果两个客户端共享地址并且客户端 a 不正确,那么客户端 b 也将不正确(即数据输入错误),但如果您确定不希望客户端 a 更改为对基地址信息进行设置,删除关联记录(从 ClientAddresses 中删除)并添加新地址。当您从关系表中执行删除(可能是从存储过程中)时,请检查是否有任何其他记录引用正在取消关联的地址记录,如果没有从基表中删除。

      【讨论】:

      • 考虑输入一个新客户,该客户与另一个客户或什至也具有地址条目的不同实体共享地址。我担心只有其中一个地址后来发生变化(比如客户搬迁)的情况。两个地址都正确,但不再相等。
      • 在搬迁的情况下,我们删除旧地址,并添加一个新地址。因此,从关系表中删除 1 次(如果没有其他关系,我们也从基表中删除 1 次),一次插入基表,一次插入关系表。
      猜你喜欢
      • 2022-11-24
      • 1970-01-01
      • 2017-09-04
      • 2012-09-19
      • 1970-01-01
      • 2018-07-26
      • 2021-01-09
      • 2016-06-06
      相关资源
      最近更新 更多