8

考虑以下关系来说明我的问题:

Person( name, street, city, zipcode )

name -> street , city , zipcode
street + city -> zipcode

所以如果我们知道名字,我们也知道这个人住在哪里。但是邮政编码也(瞬态)依赖于街道+城市。因此,这种关系中断3NF,应该分成两个表以符合要求。

但是在这种情况下,我们对将邮政编码作为一个单独的实体不感兴趣。它是地址的一部分,恰好是一个瞬态依赖。我们永远不会单独使用它。

我明白为什么标准化是一件好事。但是真的有必要总是规范化(从而使数据库更复杂)吗?如果没有,你怎么知道什么时候可以跳过?

(如果我的术语或符号有误,欢迎您纠正我)

4

5 回答 5

8

除了性能之外,未完全规范化的另一个原因可能是您的数据中是否存在某种“模糊性”。

据我了解1,ZIP 可能特定于城市街区或区域,这意味着一条特别长的街道可能有多个 ZIP。即使 ZIP 确实对应于美国的城市+街道,如果您决定走向国际,其他国家的邮政编码可能并非如此。

但即使假设ZIP 确实是特定于城市+街道的,人类也可能自己输入地址信息,这意味着他们可能会犯错误,包括不正确的 ZIP。因此,您最终可能会为相同的城市和街道组合使用两个 ZIP。

完全规范化的数据库根本无法表示 - 您必须以某种方式选择其中一个 ZIP 。除非您有权访问所有 ZIP 的完整、最新数据库,否则您没有解决此冲突的好方法。如果您最终选择了错误的 ZIP,同一城市+街道上的所有人都将拥有错误的 ZIP。

另一方面,去规范化的数据库会让每个人都保留自己的 ZIP,然后在与其他人隔离的情况下承受后果。你甚至可以实现一个自动完成的建议,然后“你确定吗?” 警告如果用户为已经有 ZIP 的现有城市+街道输入不同的 ZIP,但如果他表示确定,则让他(或她)继续。


1而且我不住在美国,所以我可能会离开。

于 2012-09-23T16:10:25.060 回答
7

规范化是一种用于分析依赖关系并确保正确实施表示为依赖关系的数据完整性规则(业务规则)的工具。规范化的一个基本假设是您知道或可以确定您实际想要实施的业务规则。如果您已经确定不想或不需要执行给定的业务规则,那么在为其设计数据库时将其视为依赖项可能没有什么价值。请记住,依赖关系的要点是,对于数据库中所有可能的数据,一条规则始终有效;不仅适用于当前数据或某些特定的数据子集。

可能存在依赖关系 {street,city} -> {zipcode} 并不是系统真正需要的业务规则,因此不应强制执行。例如,如果必须在没有地址验证软件的情况下输入数据,那么以这种方式确保邮政编码一致可能是不切实际的。这并不意味着您违反了任何规范化规则。它只是意味着函数依赖不打算持有也不持有,因此它不是任何真正意义上的传递依赖。

于 2012-09-23T20:35:49.830 回答
3

一路推动规范化的价值和成本取决于。这主要取决于您将如何处理数据。

(至少)有两种完全不同的方式来使用数据。一种是在线事务处理 (OLTP)。另一种是在线分析处理(OLAP)。

在 OLTP 中,不规范化的成本可能相当高。事务变得更复杂和更慢,并且瓶颈会降低性能。在 OLAP 中,规范化的好处是有限的,而且还有其他设计规程可以为同样的工作产生更多的好处。这些替代方案之一是星型模式设计,您可以查找它。

但与其说是不规范化或反规范化,不如说是遵循不同的设计原则,即使它不会产生规范化的数据库。

回到您概述的特定情况,有很多系统在客户活动中存在繁重的事务负载,但客户表在这些事务中用于只读目的。

不符合 3NF 只会在您必须输入新客户时伤害您,而当已经有其他客户具有相同的城市、街道和邮政编码时,您必须重新输入邮政编码。如果邮局更改给定街道的邮政编码分配,您将不得不更新大量地址,而不仅仅是规范化表中的一行。

这不是一个很高的成本,也不是一个很可能发生的事件。

另一方面,邮局选择一条街道并将这条街道分成两个邮政编码的可能性有多大,具体取决于地址所在街道的哪个街区?如果后一种情况发生,实际上你最好使用违反 3NF 的结构。您可以使用邮局提供的有关拆分的信息,为每个地址自由输入不同的邮政编码。

那么,第二种情况的可能性有多大?我认为这比第一次更有可能。但是您需要根据自己的猜测进行猜测,而不是我的猜测。

于 2012-09-23T20:26:05.610 回答
2

我不是美国人,所以我很犹豫要不要这么说,但我认为你不了解邮政编码。一些单独的建筑物有自己的邮政编码。邮政编码可以跨越州界。邮政编码可以代表具有任何地理意义的邮政信箱。

所以,不管规范化的好处如何,你的例子都是一个不好的选择。(街道,城市)和邮政编码之间没有明确的相关性。

有可能我错了,但我知道在英国的街道(即使是很短的街道)可以有多个邮政编码。

于 2012-09-23T22:31:08.233 回答
0

如果 {street, city}->{zipcode},则需要让 dbms 知道该约束,以便 dbms 可以强制执行它。否则,您很快就会得到如下所示的数据。

name           street              city              zipcode
--
Barack Obama   Pennsylvania Ave    Washington, DC    90210

90210 是一个邮政编码,但它是针对加利福尼亚州比佛利山庄的。

这是一个罕见的应用程序,可以真正容忍这样的不良数据。

于 2012-09-23T14:04:20.747 回答