1

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

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

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

我考虑过以下方法来处理这个问题:

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

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

  • 与孤立记录一起生活,并定期进行维护任务以清理所有详细信息表。

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

4

3 回答 3

6

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

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

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

于 2009-01-15T22:02:29.743 回答
3

与孤立记录一起生活,并定期进行维护任务以清理所有详细信息表。

于 2009-01-15T21:49:50.440 回答
0

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

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

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

于 2009-01-15T22:07:17.707 回答