如何将此数据库规范化为3nf?

时间:2018-03-21 00:22:28

标签: database database-normalization

enter image description here

我非常困惑,不知道如何处理joistcost,floorcost和projecttotal。

joistcost是单个组件的成本

floorcost是托梁成本乘以宽度

projecttotal是项目中所有楼层的成本

我非常感谢任何帮助,我不知道如何正确地将其正常化。

2 个答案:

答案 0 :(得分:0)

从我的观点来看,你不需要对JoistCost做任何事情。根据我的理解,此列与tblJoist候选键之间存在直接关系。

至于其余部分,您需要在表格中识别候选键,并确保关注列与候选键本身之间存在直接关系。如果现在存在间接关系,则需要将其分隔到不同的表,以获得直接关系。

答案 1 :(得分:0)

您无法对其进行规范化,因为根据定义存储这些小计是非规范化设计。

规范化是为了确保每条信息都存储一次,因此无法使值不同步。

由于您存储的FloorCost应该是Width * tblJoist.JoistCost的产品,因此如果JoistCost发生变化,那么FloorCost就会出现不准确的风险。存储这样的计算结果与规范化规则冲突。

事实上,你还有另外一个问题:我猜想托梁的成本可能会逐年变化。因此单位成本会发生变化并不出人意料。当您设计这样的项目数据库时,您应该在执行项目时复制单位成本。这样,它在项目完成时保留了值,tblJoist中的单位成本可以随后更新。

这并不违反规范化,因为当您将单位成本复制到tblFloor时,它会变成不同的信息。它是您在完成项目之日的托梁的单位成本。 tblJoist中的托梁成本是当前托梁成本,明年会有所不同。

因此,我设计tblFloorWidthJoistCost(已复制),以及可选FloorCost,您可以使用触发器保持同步或者某些数据库具有根据同一行中的其他列自动计算列的功能(例如MySQL's generated columns)。

tblProject.ProjectTotal是另一个问题。它是该项目中所有楼层的总和。如果您为了方便起见将它存储在tblProject中,这取决于您,但这在技术上是多余的信息,因为您也应该得到相同的结果:

SELECT SUM(FloorCost) FROM tblFloor WHERE ProjectID = ?

如果这给出了与tblProject.ProjectTotal不同的总和,则有人犯了错误。问题是:如果你发现这样的差异,这是正确的吗?

非规范化有时是值得的,但它存在数据不同步的风险。您必须编写应用程序代码以防止这种情况发生。