Database design 使用自然键,或使用代理键和审核表进行审核/更改日志

Database design 使用自然键,或使用代理键和审核表进行审核/更改日志,database-design,denormalization,audit-trail,Database Design,Denormalization,Audit Trail,我在这里的第一个问题,所以要友善 我是一个没有太多经验的初级开发人员,在这个问题上遇到了麻烦 我有一张桌子需要审核。假设此表记录呼叫中心拨打的电话(不是,但只是一个示例)。我叫它“CallHistory” 我原本计划保留一个名为“Callees”的单独表,其中包含被叫人的姓名、电话号码等。此表将使用代理主键 CallHistory表将具有被调用方表的外键 我最初这样做是为了,如果我更改了被叫人的电话号码,它将在整个系统中传播,而不必在多个表中更改电话号码 问题是,CallHistory表的全部目

我在这里的第一个问题,所以要友善

我是一个没有太多经验的初级开发人员,在这个问题上遇到了麻烦

我有一张桌子需要审核。假设此表记录呼叫中心拨打的电话(不是,但只是一个示例)。我叫它“CallHistory”

我原本计划保留一个名为“Callees”的单独表,其中包含被叫人的姓名、电话号码等。此表将使用代理主键

CallHistory表将具有被调用方表的外键

我最初这样做是为了,如果我更改了被叫人的电话号码,它将在整个系统中传播,而不必在多个表中更改电话号码

问题是,CallHistory表的全部目的是记录呼叫的历史记录,包括误拨的呼叫(例如,呼叫方拨打了错误的号码)。使用此代理键方法将丢失历史记录

工作中的一位高级开发人员建议,在CallHistory表中保留来电者在特定时间每次拨号的电话号码副本,以保留历史记录

我正在考虑为同样的目的保留一个审计/变更日志表

我的方法是否足以满足这一目的,还是我完全偏离了轨道?你喜欢哪种方法

干杯,
安德鲁

你的问题是非常典型的设计难题。例如,如果您有正常形式的数据库,并且有以下表格:销售、经理(销售人员)和地区(经理工作的地方)。您正在构建类似“按区域分组的年度销售”的报告,其中您将销售与经理以及经理与区域合并。但是,如果其中一位经理在这一年内将调到另一个办公室,那么您的报告似乎会显示不正确的数据,对吗

三种解决方案是什么

1) 在某些情况下,开发人员和分析人员决定:嗯,我们的数据不是很正确,但现在还可以,我们希望保持正常形式,不复制数据。这个解决方案不那么复杂。在这种情况下,您可以以正常形式创建呼叫者和CallHistory表,即电话号码将仅位于呼叫者表中

2) 有一个要求,就是不要失去任何历史性的变化。我们希望我们的报告和查询速度非常快(以数据库大小为代价)。在这种情况下,人们决定复制所有字段。例如,您可以创建包含电话号码、呼叫者姓名、地址等的CallHistory表,因为您预计这些字段中的每个字段将来都可以更改。当然,您也可以创建被调用者表(可能出于其他目的需要),但它可能会被CallHistory重新保护,而不是。假设您认为需要从被叫方删除一些记录,但希望它们位于CallHistory中。当开发人员经常认为他们可能会破坏数据的引用完整性,而不从CallHistory表创建任何外键时,就会出现这种情况。这是合理的,因为没有外键,插入操作会更快

3) 我更喜欢这种方法,但从实现的角度来看,它是最复杂的:CallHistory表应该引用CalleeHistory表。CalleeHistory表将拥有被调用方表拥有的所有文件,但它也有一个代理项键,如CalleeID+DateModified(有时开发人员使用ModificationVersionNumber代替DateModified)。在CallHistory中,我们有一个引用CalleeID+DateModified的代理外键。在这种情况下,您有标准化的数据(即电话号码不在不同的表中重复),并且您没有丢失任何历史更改

正如我所说的,在实现的复杂性、数据库性能、数据库大小、数据完整性和系统的功能需求之间常常存在权衡。如果您是一名初级开发人员,最好考虑所有可能的解决方案,但您可能应该听取高级开发人员的意见,他们比任何人都更了解您的系统和堆栈溢出需求

p、 美国


如果你想了解其他方法,请阅读缓慢变化的维度,例如,

我认为你被一个关于范式的微妙之处误导了。问题是,与被叫人相关联的电话号码与被叫人拨打的电话号码不相同。在一般情况下,它们可能具有相同的值,但这是另一个问题


因此,在我看来,CallHistory应该既有numbre dialed,又有对callee表的引用。

我同意Rik的观点。是的,冗余数据非常、非常糟糕、邪恶、难闻,而且在其他方面不受欢迎。但仅仅因为两个字段被称为“电话号码”,并不意味着它们是一样的。“客户的当前电话号码”和“我们上次与他通话时的客户电话号码”不一定是同一回事

我目前正在使用一个保存销售和商品信息的数据库。项目记录包括描述、库存编号和价格等信息。我们的销售记录还包括描述、库存编号和价格。说明和库存编号是多余的,应该删除。这是个糟糕的设计。但价格必须包括在这两个地方。当前价格与特定销售时的价格有很大差异。那笔买卖可能是几年前的事了。从那时起,价格可能已经改变了十几次

一般来说,在您描述的应用程序中,我只需将电话号码放在历史记录表中,然后就可以使用它了。拥有一个“电话号码历史记录”表并链接到当时适用的电话号码记录几乎没有什么好处。它可能会为每条记录节省一些字节,但会增加一些复杂性。但是,如果存在多个相关字段,则故事会发生变化。如果,比方说,我只是在发明一个