SQL 规范化有 2 个日期和一个持续时间都在一列中

SQL normalizing having 2 dates & a duration that is both in one column

我是 SQL 的初学者。

在 SQL table 的第一范式 (1NF) 中,值不应重复,列应具有原子值。

我有一个 table,其中有列 StartDate | 结束日期 | 持续时间

StartDate 的值为 01/01/2000,EndDate 的值为 03/03/2003,因此持续时间为 2 个日期,01/01/2000 - 03/03/2003,使用与 StartDate 中相同的两个值和 EndDate 字段。

我是否完全摆脱了 Duration 列并假设可以通过查询找到信息,或者是否有办法对其进行规范化以遵循规则而不丢失任何数据?

当我将这 3 列从其他信息中分离到另一个 table 时,我在 3NF 点注意到了这个问题,但我认为这应该在此之前完成?

如果 StartDate 和 EndDate 只是 Duration 中的日期,那么它在功能上确定它们,并且它们两个一起在功能上确定它。所以归一化(保留 FD(函数依赖))到足够高的范式会让你把它们三个分开成一个单独的 table.

但很明显,将 {Duration} 或 {StartDate, EndDate} 作为列的子集就足够了。如果您添加另一个属性,它是多余的。规范化对此无济于事,因为它只会删除冗余,其中 table 可以替换为加入它的投影。

一般来说,区间端点存放比较好。关系设计的一般思想是为您可能想要单独查询的某些事物的任何部分设置一个列。如果您想控制这种冗余,请了解 computed/calculated 列。

PS 1 请参阅 this answer 重新 'atomicity'。

PS 2. 规范化 而不是 通过将规范形式移动到最高要求来完成。 (应该是 5NF,然后出于某些原因可以反规范化。规范化为较低的规范形式可以排除良好的高级设计的出现。找到规范化为 3NF 或 BCNF 的算法。

我不熟悉您域中的业务规则和要求,但是例如,如果我们知道持续时间始终相同 - 我们可以删除 EndDate 字段,或者在拳击回合的情况下(始终为 3分钟)——我们可以删除 EndDate 和 Duration!但是,如果您的项目负载很高并且性能对于 你 - 你可能会考虑微优化选项并拥有所有 3 个字段,只是为了赢得一些微时间。

我的观点 - 没有人能够说 table 中包含所有 3 个字段(StartDate、EndDate 或 Duration),这是一种糟糕的方法。

我必须承认我从来不太关心规范化形式,因为为了避免数据库中的冗余和不一致,您会自动应用它们而不考虑 1NF、2NF 等

使用您当前的 table 设计(3 列:StartDate、EndDate、Duration 等)满足 1NF,因为您既不能将 StartDate、EndDate 或 Duration 拆分成有意义的部分。

如果我没有记错的话,2NF是关于主键的。我猜 3NF 是我们违反给定 table 设计的那个。这是因为如果我们有两个具有相同 StartDate 和 EndDate 的记录,它们将具有相同的 Duration,因此该字段不仅仅依赖于某个主键。 StartDate 和 EndDate 也是如此。因此,三列,我们可以删除一列以满足 3NF 要求。您可以自由选择。