我对我的E-R架构和第二个普通形式的表格有疑问。 该表有一个属性,取决于另一个,我不知道是否 这会导致规范化问题。
表结构如下:
| contract_id | start_date | end_date |
主键是* contract_id *。 问题是* end_date *的值恰好是* start_date *之后的1年。
行示例:
| 1 | 2013-01-01 | 2014-01-01 |
| 2 | 2012-02-03 | 2013-02-03 |
此表是否在2NF?
答案 0 :(得分:1)
我不明白为什么它不应该是2NF。 要保留2NF,不应该对复合/复合主键中的任何列具有部分依赖性(这不是这种情况)。
您的问题更可能是3NF的问题。
答案 1 :(得分:0)
它不受2NF或3NF的保护,但此模型违反了域/密钥正常形式。如果间隔始终为一年或添加检查约束,则只需删除其中一个属性 例如CHECK(end_date - start_date = 365),365是财政年度,日历年不是常数。
答案 2 :(得分:0)
同一行中其他列的计算列违反了3-NF。有些人会告诉您不要将计算列存储在数据库中以符合3-NF,这确实对 当前 模型有效。但是,您必须评估这是否对您的业务有效。假设在3个月的时间内,业务规则发生变化,end_date不再等于start_date + 1年,你会做什么?
答案 3 :(得分:0)
可以说不是2NF(大概是start_date
是唯一的),但它不是3NF,因为你可以使用表达式
adddate(start_date, interval 1 year)
或者更好地创建一个end_date
作为此表达式的视图。
您还必须问自己数据完整性:如果在开始日期后一年内您的结束日期是不,那么您的数据库会发生什么?如果计算结束日期,则无法实现这种情况 - 您可以获得内置的数据完整性。
如果结束日期是一个单独的列,则应检查这些列的每次插入和更新是否正确,这是更多工作,可能还有更多错误。
最后,如果没有存储结束日期,每一行都会更小,这会带来很小的性能提升,但增益可能微不足道。
答案 4 :(得分:0)
不违反2NF,但它确实是3NF。您不需要在数据库中存储coitateational字段。据说你没有掌握在数据库中计算价值所需的所有信息。如上所述,我会删除end_date
,但我会添加contract_term
字段。现在它很容易做到1年或12个月,或者你选择计算它,而不是将来它们可能会改变。那么即使业务需求发生变化,您也可以忠实地计算到期日期,此外您还没有存储计算字段。此外,由于contract_term
描述了您未违反2NF或3NF的实体。
答案 5 :(得分:0)
如果start_date-> end_date和end_date-> start_date,那么(start_date,end_date)不是候选键,因为该组合不是最小超级键。因此,2NF是满意的,因为没有任何候选键的适当子集是决定因素。
3NF意味着对于您需要满足的每个依赖项,要么是行列式是超级键,要么是从属属性是候选键的一部分。因此,相关问题是start_date和end_date是否都是候选键。当且仅当它们满足时,3NF才满足。如果start_date和end_date是nonprime(不是候选键),那么你的表满足2NF但不满足3NF。