数据库规范化

时间:2010-07-19 15:32:49

标签: database database-design normalization database-normalization

我是数据库设计的新手,我已经阅读了很多关于规范化的内容。如果我有三张桌子:住宿,火车站和机场。我是否在每个表中都有地址列或其他表引用的地址表?是否存在过度规范化的问题?

由于

13 个答案:

答案 0 :(得分:5)

数据库规范化就是构建维护某些功能的关系(表) 关系(表)中的事实(列)之间以及各种关系(表)之间的依赖关系 构成模式(数据库)。有点满口,但这就是它的全部。

A Simple Guide to Five Normal Forms in Relational Database Theory 是正常形式的经典参考。本文简单地定义了每种常规形式的本质 及其对数据库表设计的意义。这是一个非常好的“触摸石”参考。

要正确回答您的具体问题,需要提供更多信息。你要问的一些关键问题 是:

  • 地址是一个简单的事实(例如文本blob)还是复合事实(例如 由多个属性组成:地址线,城市名称,邮政编码等。)
  • 与“住宿”有关的其他“事实”是什么, “机场”和“火车站”?
  • 什么样的“事实”唯一且最低限度地标识“机场”,“住宿” 和“火车站”(这些事实通常被称为钥匙或候选钥匙)?
  • 地址事实和事实之间存在哪些功能依赖关系 撰写每个关系密钥?

所有这些都说,你的问题的答案并不像人们希望的那样直截了当!

是否存在“过度正常化”这样的事情?也许。这取决于是否 您已识别并用于构建表的函数依赖项 对您的应用程序域有重要意义。

例如,假设确定了一个地址 由多个属性组成;其中一个是邮政编码。从技术上说是一个邮政 代码也是一个复合项目(至少加拿大邮政编码是)。进一步规范你的 识别这些事实的数据库可能会过度规范化。这是因为 邮政编码的组成部分与您的申请无关,因此也是因素 他们进入数据库设计会过度规范化。

答案 1 :(得分:4)

对于地址,我几乎总是创建一个单独的地址表。不仅用于标准化,还用于存储字段的一致性。

过度正常化这样的东西,绝对有!因为我认为它主要来自经验,所以很难为你提供过度正常化的指导。但是,按照每个标准化水平的书籍,然后一旦开始变得很难看到你可能已经走得太远的地方。

查看您可以使用的所有示例/示例数据库。它们将为您提供关于何时应该分割数据以及何时不应该分配数据的良好指示。

此外,请充分了解您要存储的数据类型和数量,以及访问速度等。许多现代Web软件因许多性能和可伸缩性原因而完全无法正常化。值得研究的原因是什么以及何时应该而且不应该去标准化。

答案 2 :(得分:4)

  

我是否在每个表中都有地址列或其他表引用的地址表?

机场,火车站和住宿每个都有不同的地址格式吗?

单个ADDRESS表最大限度地减少了处理地址所需的工作 - 套件,RR,邮政/邮政编码,州/省......

  

是否存在过度规范化的问题?

有不同程度的标准化。我只遇到过我认为设计不好而不是标准化的东西。

答案 3 :(得分:2)

就个人而言,我会去另一张桌子。

我认为它使设计更清晰,使地址报告更加简单,并且可以更轻松地对地址模式进行任何更改。

如果您需要稍后对其进行非规范化,您可以随时创建两个包含火车站和机场信息的视图以及您需要的任何地址信息。

答案 4 :(得分:1)

这不是我通过规范化所理解的。您似乎没有谈论删除冗余,只是如何划分存储或数据模型。我假设住宿,火车站和机场地址的例子都是不相交的吗?

据我所知,如果你开始思考这个问题,那只会是正常化。邮政编码在功能上取决于街道地址,因此应该在其自己的表格中加以考虑。

在这种情况下,根据上下文,这可能是期望的或不合需要的。如果你管理记录并且可以确保正确性,也许是可取的,如果用户可以更新他们自己的记录,则不太可取。

相关问题是 Is normalizing a person’s name going too far

答案 5 :(得分:1)

如果您的项目/功能对性能非常敏感,那么在某些情况下对数据库进行非规范化可能是明智之举。但是,由于各种原因,这可能导致维护问题。您可能希望使用缓存表复制数据,但也存在缺陷。这实际上是一个案例,但在正常情况下,数据库规范化是一件好事。我见过的99%的非规范化数据库不是设计,而是开发人员的误解/错误。

答案 6 :(得分:1)

  

我是否在每个表中都有地址列或其他表引用的地址表?

正如其他人所提到的,这不是一个规范化的问题,因为你并没有试图减少冗余或组织依赖。无论哪种方式都完全可以接受。如果您要具有特定于地址的集中验证或业务逻辑,则将地址移动到单独的表可能是有意义的。

  

是否存在过度规范化的问题?

是。如前所述,在大型系统(大量数据,大量事务或两者)中,您可以将性能标准化到性能成为问题的程度。这就是为什么许多系统使用非规范化数据库进行报告和查询的原因。

除了性能之外,还存在数据查询容易的问题。在会有大量最终用户查询数据的系统中(可能很危险!),非规范化结构对于大多数非技术人员或非数据库人员来说更容易理解。

与我们处理的大多数事情一样,它是理解,性能和未来可维护性之间的权衡,并且很少有明确的答案来确定在任何给定系统中绘制线的位置。

根据经验,您将了解为您编写的系统最佳绘制线条的位置。

话虽如此,我更倾向于在更多与较不正常化的方面犯错误。

答案 7 :(得分:0)

我认为在这种情况下,在每个表中都有地址列。你几乎没有一个地址可以使用两次以上。大多数地址每个实体只使用一个。

但在额外的表中可能是街道,城市,国家的名字......

最重要的是,每个火车站,住宿和机场可能只有一个地址,所以这是一个n:1的关系。

答案 8 :(得分:0)

如果您使用的是Oracle 9i,则可以在表中存储地址对象。这将消除对地址格式的(合理的)担忧。

答案 9 :(得分:0)

我同意S.Lott的意见,并想补充一下:

  1. 一个好的答案取决于你已经知道的。然而,关系数据库理论的基本“数学”定义了非常明确的,不同的标准化水平。当你达到最终的正常形态时,你不能再正常化。

  2. 根据您想要使用三个实体建模的内容以及如何识别它们,您可以提出截然不同的概念数据模型,所有这些模型都可以以正常形式的形式表示 - 或者根本没有标准化(就像所有带有描述符和空洞的数据的1个表一样......)。 考虑将三个实体标准化为最终的正常形式。我现在可以引入一个新的要求,或者用例或扩展,如果你查看它的内容,它会以某种方式排序,引用或结构化的属性给出一个现在描述性的属性。然后,模型应该表示此行为,以及曾经是属性的内容可能更好地是由其他实体引用的单独实体。

  3. 过归一化?只有在能够规范化给定模型的意义上,才能在给定的数据库平台上存储或处理效率低下。根据可以在那里有效处理的内容,您可能希望对某些方面进行去规范化,为了速度而牺牲冗余(数据仓库dbs一直这样做)和洞察力,反之亦然。

  4. 到目前为止,我见过的所有(工作)数据库设计都有一个相当标准化的概念数据模型,在逻辑和/或物理数据模型级别(在Sybase PowerDesigner术语中)完成了相当多的非规范化以制作模型“可管理的” - 或者说,或者他们没有工作,即失败,因为维护问题真的很快就成了特大号。

答案 10 :(得分:0)

当你说“地址”时,我认为你的意思是一个完整的地址,如街道,城市,州/省,国家和邮政编码。这是4或5个字段,如果您允许“地址行1”和“地址行2”,小心等等,可能更多。这应该在一个单独的表中,其中“addressid”链接到Station,等表。否则,您将创建同一组字段定义的3个单独副本。这是个坏消息,因为它会产生额外的努力来保持它们的一致性。比如,如果最初你只处理美国地址(我是美国人,所以我会假设美国),但后来你发现你也需要允许加拿大人。您需要扩大邮政编码字段的大小并添加国家/地区代码。如果有一个共同的表,那么你只需要做一次。如果没有,那么你必须这样做三次。并且“三次”可能不只是改变数据库模式,而是改变程序中处理地址的每个地方。

规范化的一个好处是尽量减少变化的影响。

答案 11 :(得分:0)

有时您希望进行非规范化以提高查询效率。但是,只有在你有充分的理由相信完全正常化的模型会造成严重的低效问题之后,才应该非常谨慎地做到这一点。在我不起眼的经历中,大多数程序员都很快就会非常规化,通常快速“哦,打破这个单独的表格太麻烦了”。

答案 12 :(得分:0)

我只能在此处发布的答案中再添加一条建设性的说明。但是,如果您选择规范化数据库,那么当地址标准化(看起来相同)时,该过程将变得几乎无关紧要。这是因为当您努力防止重复时,实际上相同的所有地址看起来都是相同的

现在,标准化地址是微不足道的。有CASS服务为您(美国地址)执行此操作已经过USPS认证。我实际上为SmartyStreets工作,这是我们的专长,所以我建议你在那里开始搜索。您可以执行批处理,也可以使用API​​在收到地址时对其进行标准化。

如果没有这样的东西,您的数据库可能会被标准化,但重复的地址数据(无论是正确的还是不完整的和无效的等)仍会渗透,因为它们可以采用多种形式。如果您对此有任何疑问,我个人会帮助您。