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

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

What's the better database design: more tables or more columns?

一位前同事坚持认为,拥有更多表且每列更少的数据库要比拥有更少表且每列更多的数据库更好。 例如,您将没有名称表,地址表,城市表等,而不是具有名称,地址,城市,州,邮政编码等列的客户表。

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

因此,具有较少列的更多表相对于具有较多列的较少表有什么显着的好处?


设计数据库时,我遵循一些非常简单的经验法则,我认为这些规则可用于帮助做出这样的决策。

  • 支持规范化。非规范化是优化的一种形式,它具有所有必要的折衷,因此应以YAGNI的态度进行处理。
  • 确保引用数据库的客户端代码与架构进行了充分的分离,以至于对其进行重做不需要对客户端进行重大的重新设计。
  • 当它为性能或查询复杂性带来明显好处时,不要害怕进行非规范化。
  • 在数据量和使用场景允许的情况下,使用视图或下游表来实现规范化而不是规范化架构的核心。
  • 这些规则的通常结果是,初始设计将偏爱表而不是列,重点是消除冗余。随着项目的进展和非规范化点的确定,总体结构将朝着平衡的方向发展,以有限的冗余和色谱柱扩散为代价,以换取其他有价值的利益。


    我会主张使用更多的表,但只能使用到一定程度。以您的示例为例,如果将用户信息分为两个表(例如:USERS和ADDRESS),则可以灵活地为每个用户拥有多个地址。一个明显的应用是拥有单独帐单和送货地址的用户。

    支持使用单独的CITY表的论据是,您只需要存储每个城市的名称一次,然后在需要时引用它。这确实减少了重复,但是在此示例中,我认为这是多余的。这样做可能更节省空间,但是当您从数据库中选择数据时,您将在联接中付出代价。


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

    Jeff就StackOverflow的设计写了一些有关它的内容。另请参阅Jeff链接到Dare Obasanjo的文章。


    这取决于您的数据库风格。例如,MS SQL Server倾向于更窄的表。这也是更"规范化"的方法。其他引擎可能更喜欢它。大型机通常属于此类。


    完全标准化的设计(即"更多表")更灵活,更易于维护,并且避免了数据重复,这意味着您的数据完整性将更容易实施。

    这些是进行规范化的有力理由。我会选择先进行规范化,然后在看到性能成为问题后才对特定表进行规范化。

    我的经验是,在现实世界中,即使有非常大的数据集,也不会达到需要进行非规范化的程度。


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

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


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


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

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

    如果您的客户需要有多个地址,则可以使用一个单独的表。如果确实有充分的理由将City列标准化为其自己的表,那么也可以这样做,但是我以前从未见过,因为它是一个自由格式的字段(通常)。

    表格繁重的规范化设计在空间方面非常有效,看起来"教科书很好",但会变得极其复杂。看起来很不错,直到您必须进行12次联接才能获得客户的姓名和地址。就最重要的性能而言,这些设计并非自动出色:查询。

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

    这是杰夫关于这个话题的帖子。


    具有较少列的表有很多优点,但是您还需要查看上面的情况并回答以下问题:

    允许客户使用多个地址吗?如果不是,则不需要单独的地址表。如果是这样,那么一个单独的表将很有用,因为您可以轻松地根据需要添加更多地址,而在该表中添加更多列将变得更加困难。


    我认为这很重要,取决于您的特定设计模型。一定要在其自己的表中排除具有多个字段的实体,或者其组成可能会随您的应用程序需求的变化而变化的实体(例如,我会考虑地址,因为它有很多字段,但是我仍然会考虑解决)如果您认为有任何可能需要处理国外地址(可以采用不同的形式(电话号码相同)),则最好这样做。

    就是说,当您开始工作时,请密切注意性能。如果您拆分出一个需要进行大型,昂贵连接的实体,那么将表旋转回原始表可能是一个更好的设计决策。


    这有很多方面,但是从应用程序效率的角度来看,表有时会更高效。如果每次db进行操作时,如果有几个表具有一堆列,则有机会进行锁定,则在锁定期间将使更多数据不可用。如果锁升级到页和表(希望不是表:)),您将看到它如何降低系统速度。


    我认为在这种情况下要保持平衡。如果在表中放置一列是有意义的,则将其放在表中,如果没有,则不要。您的同事方法肯定会帮助标准化数据库,但是如果您必须将50个表连接在一起以获取所需的信息,那可能就没有太大用处。

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


    我认为标准化是第一步,因此将城市,县,州,国家/地区作为单独的列会更好... SQL语言的强大功能以及今天的DBMS-es允许您在以后需要查看数据时对数据进行分组它以其他一些非标准化的观点来看。

    在开发系统时,如果您认为这是一项改进,则可以考虑"标准化"某些部分。


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

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

    两种情况:
    *如果您创建了一个将要使用多年的数据模型,因此可能不得不适应许多将来的更改:请使用更多的表,更少的行以及相当严格的规范化。
    *在其他情况下,您可以在更多表少行或更少表多行之间进行选择。特别是对于刚接触该主题的人们,后一种方法可以更直观,更容易理解。

    对于面向对象方法和其他选项之间的选择,这同样有效。


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

    一个好的数据库设计应保持20年不变。

    一个客户可能有多个地址,这就是事实。如果您确定您的应用程序在第一个发行版中仅限于一个地址,则与应用程序的设计有关,而不是数据!

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

    大多数情况下,数据库会出现性能问题,这与网络性能(具有单行结果的链式查询,不需要的获取列等)有关,而与查询的复杂性无关。


    使用尽可能少的列进行查询有很大的好处。但是表本身可以有很多。杰夫对此也说了些话。

    基本上,请确保您查询的内容不超过所需数量,查询的性能与所需的列数直接相关。


    首先,规范化表。这样可以确保避免冗余数据,减少要扫描的数据行,从而改善查询。然后,如果遇到要联接的规范化表导致查询花费较长时间处理的情况(昂贵的联接子句),请在更合适的地方进行规范化。


    我认为您必须先确定要存储的数据类型,然后再做出决定。有一个地址表是很棒的,但前提是多个人共享同一地址的可能性很高。如果每个人都有不同的地址,那么将该数据保存在不同的表中只会引入不必要的联接。

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

    最重要的是,这样的决定必须在开始提高效率之前考虑应用程序本身。海事组织。


    推荐阅读

      linux获取地址命令?

      linux获取地址命令?,地址,网络,信息,系统,设备,终端,命令,中心,管理,数字,lin

      linux命令行ip地址?

      linux命令行ip地址?,地址,系统,网络,信息,设备,电脑,密码,命令,服务,状态,lin

      linux获取地址命令?

      linux获取地址命令?,地址,网络,信息,系统,设备,终端,命令,中心,管理,数字,lin

      linux命令大全数据库?

      linux命令大全数据库?,服务,系统,平台,状态,软件,通用,环境,数据,神州,地址,

      linux上数据库的命令?

      linux上数据库的命令?,服务,系统,信息,地址,命令,密码,工具,管理,数据,单位,

      linux命令dm数据库?

      linux命令dm数据库?,地址,软件,时间,设备,名字,服务,位置,名称,公司,命令,lin

      linux命令物理地址?

      linux命令物理地址?,地址,信息,电脑,系统,网络,服务,网卡,数据,软件,手机,lin

      linux地址转换命令是?

      linux地址转换命令是?,地址,系统,代码,密码,网络,信息,服务,电脑,设备,报告,

      linux的ip地址命令?

      linux的ip地址命令?,地址,系统,网络,信息,数字,电脑,终端,命令,服务,名称,Lin

      linux数据库查找命令?

      linux数据库查找命令?,位置,名称,状态,服务,软件,信息,系统,命令,名字,密码,

      linux数据库同步命令?

      linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

      linux建立数据库命令?

      linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

      linux命令进数据库?

      linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

      linux修改地址命令?

      linux修改地址命令?,地址,系统,代码,网络,服务,信息,密码,命令,管理,基础,lin

      linux查看命令的地址?

      linux查看命令的地址?,地址,系统,网络,信息,设备,电脑,手机,终端,技术,环境,l

      linux地址查询命令?

      linux地址查询命令?,地址,网络,系统,工作,信息,设备,名称,标准,手机,管理,lin

      linux数据库检查命令?

      linux数据库检查命令?,服务,状态,地址,位置,系统,信息,命令,工作,情况,密码,

      linux命令进去数据库?

      linux命令进去数据库?,地址,服务,名字,系统,数据库,工具,基础,工作,管理,网

      linux数据库基础命令?

      linux数据库基础命令?,地址,工作,基础,系统,命令,信息,情况,工具,设备,目录,l

      linux带源地址命令?

      linux带源地址命令?,时间,地址,数据,网络,系统,信息,档案,命令,名称,名字,Lin