您的问题是非常典型的设计困境。例如,如果您有标准格式的数据库,并且您有以下表格:销售、经理(销售人员)和区域(经理工作的地方)。您正在构建诸如“按地区分组的年度销售额”之类的报告,您可以在其中将销售与经理和经理与地区联系起来。但是,如果其中一位经理将在年内调到另一个办公室,您的报告似乎会显示错误的数据,对吧?
什么是3个解决方案
1)在某些情况下,开发人员和分析师决定:好吧,我们的数据不是很正确,但现在还可以,我们希望保持正常形式,不要重复数据。该解决方案不太复杂。在这种情况下,您可以以正常形式创建 Callers 和 CallHistory 表,即电话号码将仅在 Callers 表中。
2) 要求不丢失任何历史变化。我们希望我们的报告和查询非常快(以数据库大小为代价)。在这种情况下,人们决定复制所有字段。例如,您可以创建包含电话号码、呼叫者姓名、地址等的 CallHistory 表,因为您预计将来每个字段都可以更改。当然,您也可以创建 Callee 表(可能您将需要它用于其他目的),但它可能会被 CallHistory 重新定义,并且可能不会。假设您认为某些记录需要从 Callee 中删除,但希望它们在 CallHistory 中。当开发人员经常认为他们可以违反数据的参照完整性时,就是这种情况,不要从 CallHistory 表中创建任何外键。这是合理的,因为没有外键,
3)方法我更喜欢,但从实现的角度来看它是最复杂的:CallHistory 表应该引用 CalleeHistory 表。CalleeHistory 表将包含 Callee 表具有的所有文件,但它也有一个代理键,例如 CalleeID + DateModified(有时开发人员使用 ModificationVersionNumber 而不是 DateModified)。在 CallHistory 中,我们有一个引用 CalleeID + DateModified 的代理外键。在这种情况下,您已经标准化了数据(即电话号码不在不同的表中重复),并且您没有丢失任何历史更改。
正如我所说,在实现的复杂性、数据库性能、数据库大小、数据完整性和系统的功能要求之间经常存在权衡。如果您是初级开发人员,最好考虑所有可能的解决方案,但您可能应该听取高级开发人员的意见,他比 Stack Overflow 上的任何人都更了解您的系统和需求。
ps
如果您想了解其他方法,请阅读有关渐变维度的信息,例如http://en.wikipedia.org/wiki/Slowly_sharing_dimension