什么是更好的数据库设计:更多表或更多列?

时间:2008-09-12 16:45:24

标签: database database-design normalizing

一位前同事坚持认为,每个数据库中包含更多表的列数越多,每个表的列越多,表越少。例如,而不是具有名称,地址,城市,州,邮政等列的客户表,您将拥有名称表,地址表,城市表等。

他认为这种设计更有效,更灵活。也许它更灵活,但我没有资格对其效率发表评论。即使效率更高,我认为增加的复杂性可能会超过这些收益。

那么,对于包含更少列的更少列的更少列,是否有任何显着优势?

18 个答案:

答案 0 :(得分:55)

我在设计数据库时遵循一些相当简单的经验法则,我认为可以用来帮助做出像这样的决定....

  1. 赞成规范化。非规范化是一种优化形式,具有所有必要的权衡,因此应以YAGNI态度接近。
  2. 确保引用数据库的客户端代码与模式完全分离,重新设计它不需要重新设计客户端。
  3. 当它为性能或查询复杂性提供明显的好处时,不要害怕反规范化。
  4. 使用视图或下游表来实现非规范化,而不是在数据量和使用方案允许的情况下对模式的核心进行非规范化
  5. 这些规则的通常结果是初始设计将有利于表格而不是列,重点是消除冗余。随着项目的进展和非规范化点的确定,整体结构将朝着平衡方向发展,这种平衡会在有限的冗余和列扩散的情况下妥协,以换取其他有价值的好处。

答案 1 :(得分:11)

我会支持更多的表格,但只能达到某一点。使用您的示例,如果您将用户的信息分成两个表,例如USERS和ADDRESS,这使您可以灵活地为每个用户分配多个地址。一个明显的应用是具有单独的计费和送货地址的用户。

支持拥有单独的CITY表的论点是,您只需存储一个城市的名称,然后在需要时引用它。这确实减少了重复,但在这个例子中我认为这是过度的。它可能更节省空间,但是当您从数据库中选择数据时,您将为连接付出代价。

答案 2 :(得分:10)

它听起来不像关于表/列的问题,而是关于规范化。在某些情况下,具有高度normalization(在这种情况下“更多表格”)是好的,干净的,但通常需要大量的JOIN来获得相关结果。如果数据集足够大,可能会降低性能。

Jeff wrote关于StackOverflow设计的一点点。另请参阅Dare Obasanjo发布的Jeff链接。

答案 3 :(得分:5)

这取决于您的数据库风格。例如,MS SQL Server倾向于选择较窄的表。这也是更“规范化”的方法。其他引擎可能更喜欢它。大型机往往属于该类别。

答案 4 :(得分:5)

完全规范化的设计(即“更多表格”)更灵活,更易于维护,并避免重复数据,这意味着您的数据完整性将更容易实施。

这些是规范化的有力理由。我会首先选择规范化,然后在 之后只对特定的进行非规范化,你会发现性能正在成为一个问题。

我的经验是,在现实世界中,即使数据集非常大,也无法达到非规范化的程度。

答案 5 :(得分:4)

每个表应仅包含与主键唯一标识的实体相关的列。如果数据库中的所有列都是同一实体的所有属性,那么您只需要一个包含所有列的表。

但是,如果任何列可能为null,则需要将每个可空列放入其自己的表中,并使用主表的外键来对其进行规范化。这是一种常见的情况,因此对于更简洁的设计,您可能会为现有表添加更多表而不是列。此外,通过将这些可选属性添加到它们自己的表中,它们将不再需要允许空值,并且可以避免一系列与NULL相关的问题。

答案 6 :(得分:3)

如果这些一对一关系中的任何一个在将来可能变为一对多或多对多,则多表数据库会更加灵活。例如,如果您需要为某些客户存储多个地址,那么如果您有客户表和地址表,则会更容易。我真的看不到你可能需要复制地址的某些部分但不能复制其他部分的情况,因此单独的地址,城市,州和邮政编码表可能会有点过头。

答案 7 :(得分:3)

和其他一切一样:这取决于。

关于列数与表计数没有硬性规定。

如果您的客户需要拥有多个地址,那么单独的表是有意义的。如果你有一个很好的理由将City列标准化为自己的表,那么也可以这样,但我之前没有看到它,因为它是一个自由的表单字段(通常)。

表重,标准化设计在空间方面是高效的,看起来“教科书好”但可能变得非常复杂。它看起来很不错,直到您必须进行12次连接才能获得客户的姓名和地址。这些设计在最重要的性能方面不是自动太棒了:查询。

尽可能避免复杂性。例如,如果客户只能有两个地址(不是任意多个),那么将它们全部保存在一个表(CustomerID,Name,ShipToAddress,BillingAddress,ShipToCity,BillingCity等)中可能是有意义的。

关于该主题的

Here's Jeff's post

答案 8 :(得分:2)

拥有较少列的表有一些优点,但您还需要查看上面的场景并回答以下问题:

客户是否可以拥有多个地址?如果没有,则不需要单独的地址表。如果是这样,那么单独的表会变得有用,因为您可以根据需要轻松添加更多地址,这样就可以更难以向表中添加更多列。

答案 9 :(得分:1)

我会考虑将规范化作为第一步,因此城市,县,州,国家会更好地作为单独的列... SQL语言的强大功能以及今天的DBMS-es允许您稍后对数据进行分组需要在其他非规范化视图中查看它。

在开发系统时,如果您认为这是一项改进,您可能会考虑将某些部分“非标准化”。

答案 10 :(得分:1)

嗯。

我认为这是一种洗涤,取决于您的特定设计模型。肯定会将具有多个字段的实体分解到他们自己的表中,或者当您的应用程序的需求发生变化时,其组成可能会发生变化的实体(例如 - 我会因为它有很多字段而将因素分解出来,但是我如果您认为有可能需要处理外国国家/地区的地址,可能会采用不同的形式,尤其是

那就是说,当你开始工作时,要注意性能。如果你想要一个需要你做大而昂贵的连接的实体,那么将这个表重新转换成原始表可能是一个更好的设计决定。

答案 11 :(得分:1)

这有很多方面,但从应用效率的角度来看,mote表有时会更有效率。如果每次数据库执行操作时都有一些包含一堆列的表,则它有可能进行锁定,在锁定期间会有更多数据不可用。如果锁被升级到页面和表(希望不是表:) :)你可以看到这会如何减慢系统速度。

答案 12 :(得分:1)

在这种情况下,我认为平衡是有序的。如果将列放在表中是有意义的,那么将它放在表中,如果没有,则不要。您的同事方法肯定有助于规范化数据库,但如果您必须将50个表连接在一起以获取所需信息,那么这可能不是非常有用。

我想我的回答是,用你最好的判断。

答案 13 :(得分:0)

我认为在做出决定之前,您必须先查看您存储的数据类型。拥有一个地址表很好,但前提是多人共享​​同一地址的可能性很高。如果每个人都有不同的地址,那么将这些数据保存在不同的表中只会引入不必要的连接。

我没有看到拥有城市表的好处,除非城市本身就是您在应用程序中关心的实体。或者,如果您想限制用户可用的城市数量。

底线是这样的决定必须在开始拍摄效率之前考虑应用程序本身。 IMO。

答案 14 :(得分:0)

查询使用尽可能少的列有很多好处。但表本身可以有很多。 Jeff也对此有所说明。

基本上,请确保在进行查询时不要求超出所需数量 - 查询的性能与您要求的列数直接相关。

答案 15 :(得分:0)

在设计数据库时,您应该尽可能接近数据的含义,而不是您的应用程序需要!

良好的数据库设计应该有20多年没有变化。

客户可以拥有多个地址,这就是现实。如果您认为您的应用程序仅限于第一个版本的一个adresse,则关注的是应用程序的设计而不是数据!

最好有多个表而不是多个列,如果要简化查询,请使用视图。

大多数情况下,您会遇到数据库的性能问题,这与网络性能(带有一行结果的链查询,您不需要的提取列等)有关,而与查询的复杂性无关。

答案 16 :(得分:0)

首先,规范化表格。这可确保您避免冗余数据,从而减少扫描数据行数,从而改善查询。然后,如果您遇到正在加入的规范化表导致查询需要很长时间才能处理(昂贵的连接子句)的点,那么在更合适的地方进行非规范化。

答案 17 :(得分:0)

很高兴看到这么多鼓舞人心且基础良好的答案。

我的回答是(不幸的):这取决于。

两种情况: *如果您创建一个将要使用多年的数据模型,因此可能必须熟悉未来的许多变化:更多的表和更少的行以及非常严格的规范化。 *在其他情况下,您可以选择更多表格更少的行或更少的表格 - 更多行。特别是对于相对较新的人来说,最后一种方法可以更直观,更容易理解。

同样适用于面向对象方法和其他选项之间的选择。