我是数据库设计的新手,我已经阅读了很多关于规范化的内容。如果我有三张桌子:住宿、火车站和机场。我会在每个表中都有地址列还是由其他表引用的地址表?是否存在过度规范化之类的事情?
谢谢
我是数据库设计的新手,我已经阅读了很多关于规范化的内容。如果我有三张桌子:住宿、火车站和机场。我会在每个表中都有地址列还是由其他表引用的地址表?是否存在过度规范化之类的事情?
谢谢
数据库规范化是关于构建关系(表),维护关系(表)内的事实(列)之间以及构成模式(数据库)的各种关系(表)之间的某些功能依赖关系。有点吃饱了,但这就是它的全部意义所在。
关系数据库理论中五个范式的简单指南 是范式的经典参考。本文简单地定义了每种范式的本质是什么以及它在数据库表设计中的意义。这是一个很好的“试金石”参考。
要正确回答您的具体问题,需要额外的信息。您必须提出的一些关键问题是:
综上所述,您的问题的答案并不像人们希望的那样直截了当!
是否存在“过度规范化”之类的东西?也许。这取决于您已识别并用于构建表的功能依赖项对您的应用程序域是否重要。
例如,假设确定一个地址由多个属性组成;其中之一是邮政编码。从技术上讲,邮政编码也是一个复合项目(至少加拿大邮政编码是)。进一步规范化您的数据库以识别这些事实可能是过度规范化。这是因为邮政编码的组件与您的应用程序无关,因此将它们纳入数据库设计将是过度规范化。
对于地址,我几乎总是会创建一个单独的地址表。不仅为了规范化,而且为了存储字段的一致性。
至于过度归一化这种东西,绝对有!很难就什么是过度规范化和不过度规范化给你指导,因为我认为它主要来自经验。但是,请遵循有关每个标准化级别的书籍,然后一旦开始变得难以看清事物在哪里,您可能已经走得太远了。
您也可以查看所有示例/示例数据库。它们会给你一个很好的指示,告诉你什么时候应该拆分数据,什么时候不应该。
此外,请充分了解您存储的数据类型和数量,以及访问速度等。由于许多性能和可扩展性原因,许多现代 Web 软件正在完全去规范化。值得研究一下为什么以及何时应该和不应该去规范化。
我会在每个表中都有地址列还是由其他表引用的地址表?
机场、火车站和住宿可以有不同的地址格式吗?
单个 ADDRESS 表最大限度地减少了处理地址所需的工作 - 套件、RR、邮政/邮政编码、州/省...
是否存在过度规范化之类的事情?
有不同程度的标准化。我只遇到了我认为糟糕的设计而不是规范化的东西。
这不是我真正理解的规范化。您似乎不是在谈论消除冗余,而是在谈论如何对存储或数据模型进行分区。我假设住宿、火车站和机场的地址示例都是不相交的?
据我所知,如果您开始按照思路进行思考,那只会是规范化。邮政编码在功能上取决于街道地址,因此应将其分解到自己的表中。
在这种情况下,这可能是可取的或不可取的,具体取决于上下文。如果您管理记录并且可以确保正确性,则可能是可取的,如果用户可以更新自己的记录,则不太可取。
一个相关的问题是规范一个人的名字是否太过分了?
我个人会去另一张桌子。
我认为它使设计更简洁,使地址报告更简单,并使您需要对地址架构进行的任何更改变得更容易。
如果您以后需要对其进行非规范化,您始终可以创建两个视图,其中包含火车站和机场信息以及您需要的任何地址信息。
如果您有一个对性能非常敏感的项目/功能,在某些情况下对数据库进行非规范化可能是明智之举。但是,由于各种原因,这可能会导致维护问题。相反,您可能希望使用缓存表复制数据,但这也有缺点。这确实是个案,但在正常实践中,数据库规范化是一件好事。我见过的 99% 的非规范化数据库不是设计使然,而是开发人员的误解/错误造成的。
我会在每个表中都有地址列还是由其他表引用的地址表?
正如其他人所暗示的那样,这并不是真正的规范化问题,因为您并没有试图减少冗余或组织依赖关系。无论哪种方式都是完全可以接受的。如果您要进行集中验证或特定于地址的业务逻辑,则将地址移动到单独的表中可能是有意义的。
是否存在过度规范化之类的事情?
是的。如前所述,在大型系统(大量数据、大量事务或两者兼有)中,您可以标准化到性能成为问题的程度。这就是为什么许多系统使用非规范化数据库进行报告和查询的原因。
除了性能之外,还有数据查询的难易程度的问题。在最终用户对数据进行大量查询的系统中(可能很危险!),非规范化结构对于大多数非技术人员或非数据库人员来说更容易理解。
像我们处理的大多数事情一样,这是理解、性能和未来可维护性之间的权衡,并且很少有明确的答案来确定在任何给定系统中划定界限的位置。
凭借经验,您将了解最适合您编写的系统的界限。
话虽如此,我的偏好是在更多与更少标准化方面犯错。
如果您使用的是 Oracle 9i,您可以在表中存储地址对象。这将消除对地址格式的(合理的)担忧。
我同意 S.Lott 的观点,并想补充:
一个好的答案取决于你已经知道什么。然而,关系数据库理论的基本“数学”定义了非常明确的、不同的规范化级别。当您达到最终的正常形式时,您将无法再正常化。
根据您想用三个实体建模的内容以及识别它们的方式,您可以提出非常不同的概念数据模型,所有这些模型都可以用范式混合表示 - 或根本不规范化(如 1所有带有描述符和空洞的数据的表......)。考虑将您的三个实体规范化为最终的正常形式。我现在可以介绍一个新的需求、用例或扩展,如果你查看它的内容,它会赋予迄今为止的描述性属性以某种方式排序、引用或结构化的性质。然后,模型应该表示这种行为,而过去的属性可能会更好地成为其他实体引用的单独实体。
过度标准化?只有在某种意义上,您才能规范化给定模型,以便在给定数据库平台上存储或处理效率低下。根据那里可以有效处理的内容,您可能希望对某些方面进行非规范化,以牺牲冗余换取速度(数据仓库数据库一直这样做)和洞察力,反之亦然。
到目前为止,我看到的所有(工作)数据库设计要么有一个相当规范化的概念数据模型,在逻辑和/或物理数据模型级别(用 Sybase PowerDesigner 术语来说)进行了相当多的非规范化,以使模型“易于管理” - 要么,要么他们不工作,即失败,因为维护问题变得非常快。
当您说“地址”时,我认为您的意思是完整的地址,例如街道、城市、州/省、国家/地区和邮政编码。那是 4 或 5 个字段,如果您允许“地址行 1”和“地址行 2”、转交等,可能会更多。这肯定应该在一个单独的表中,并带有一个“addressid”链接到站,等表。否则,您将创建同一组字段定义的 3 个单独副本。这是个坏消息,因为它需要额外的努力来保持它们的一致性。比如,如果最初你只处理美国地址(我是美国人,所以我假设美国),但后来你发现你还需要允许加拿大人。您需要扩大邮政编码字段的大小并添加国家/地区代码。如果有一张普通的桌子,那么你只需要这样做一次。如果没有,那么你必须这样做三遍。“三次”很可能不仅仅是更改数据库模式,而是更改程序中处理地址的每个地方。
规范化的好处之一是最大程度地减少更改的影响。
有时您希望进行非规范化以提高查询效率。但这应该非常谨慎地进行,只有在你有充分的理由相信完全标准化的模型会产生严重的低效率问题之后。以我卑微的经验,大多数程序员都无法快速进行非规范化,通常会快速“哦,将其分解为单独的表太麻烦了”。
我只能在此处已发布的答案中添加一个更具建设性的注释。无论您选择标准化您的数据库,当地址标准化(看起来相同)时,这个过程几乎变得微不足道。这是因为当您努力防止重复时,实际上相同的所有地址看起来都相同。
现在,标准化地址并非易事。有经过 USPS 认证的 CASS 服务可以为您执行此操作(针对美国地址)。我实际上在SmartyStreets工作,这是我们的专长,所以我建议您从那里开始搜索。您可以执行批处理或使用 API 在收到地址时对其进行标准化。
如果没有这样的东西,您的数据库可能会被规范化,但是重复的地址数据(无论是正确的还是不完整的和无效的等)仍然会渗入,因为它们可以采用很多很多形式。如果您对此还有任何疑问,我会亲自为您提供帮助。
我认为在这种情况下,每个表中都有地址列是可以的。您几乎不会有一个会被使用超过两次的地址。大多数地址将仅用于每个实体一个。
但是,额外的表格中可能包含街道、城市、国家/地区的名称……
最重要的是,每个火车站、住宿和机场可能只有一个地址,所以它是 n:1 关系。