【问题标题】:Is 3rd normal form ok for databases?数据库的第三范式可以吗?
【发布时间】:2011-05-21 18:42:01
【问题描述】:
在设计数据库时我是否应该始终以第四范式为目标?
我觉得第三范式更接近我的业务领域。
例如,我有一张带有PartNumber 的表。在我的业务领域中,它是唯一的密钥,任何两个部分都不应该有相同的数字。然而,这是一个 VARCHAR,将主键放入 VARCHAR,然后将其作为外键链接到其他表对我来说是一种巨大的气味。
我应该把自动增量 ID 放在各处吗?我并没有马上明白这一点,它使代码复杂化了很多。
【问题讨论】:
标签:
database
database-design
normalization
【解决方案1】:
学习如何规范化数据需要几周时间。学习何时无视规范化规则需要几个月甚至几年的时间。当然,如果你无视规范化的规则,就会有后果。如果你彻底学习规范化,你就会知道后果是什么。
与遵循其他一些设计模式的好处相比,有时不遵循给定的正常形式的后果是轻微的。例如,在构建 OLAP 数据库或数据仓库时,星型模式或雪花模式通常比完全规范化更高效。
对于 OLTP 数据库,我倾向于以 Boyce-Codd 范式为目标,只处理由于偏离第 4 或第 5 范式而出现的任何修改异常。但这真的取决于具体情况。
【解决方案2】:
作为一般规则,您的数据库应至少处于 Boyce-Codd 范式或理想的第五范式。仅在存在重要的依赖关系时才考虑 3NF,否则 5NF 无法满足这些依赖关系。
4NF 与您在密钥中使用 varchar 还是整数无关,我不确定您为什么认为它会这样做。
【解决方案3】:
您是否允许您的用户编辑零件编号?如果是这样,这是反对将其用作主键的一个很好的论据。作为(一般)经验法则,PK 不应该是用户可编辑的,因为通过数据库复制更改的 PK 可能会变得非常昂贵。
另外 - 是不是两个部分都不能有相同的编号,或者没有两个 活动 部分可以有相同的编号?如果是后者,您是否需要保留足够长的历史记录,以至于最终可能会得到两个相同的零件编号?
【解决方案4】:
虽然您的问题是关于 4NF,但您的具体情况并非如此。使用 VARCHAR 字段作为主键并没有错误,如果它相对较小,那么我更愿意使用它而不是代理键。
回到 4NF - 从 Wikipedia's example 开始,这似乎在很多时候会自然而然地落实到位。争取 4NF 肯定不会有什么坏处——同时非规范化也有它的位置。
【解决方案5】:
这取决于数据库;使用 varchar 字段作为 PK 会浪费数据库存储空间和 MySQL 中的索引(例如)。为您的零件编号提供一个表格和唯一的整数 id 可能看起来不那么纯粹,但在性能方面,这些东西有时是必要的。
(此外,它确实允许您在必要时在一个地方更新产品编号,尽管我怀疑这在您的业务逻辑中可能不太可能。)