有太多列会造成什么问题?

75
我注意到这里很多人引用了拥有20+甚至55列的表格。虽然我不是数据库设计专家,但我一直听说这是一个可怕的做法。当我看到这种情况时,我通常会建议将其拆分为两个具有一对一关系的表:一个包含最常用的数据,另一个包含最不常用的数据。同时,这可能会导致性能问题(少JOIN等)。所以我的问题是:
在真正的大规模数据库中,拥有大量列是否确实有优势,尽管这通常会导致许多NULL值?
哪种情况更容易影响性能:许多带有许多NULL的列,还是少量带有许多JOIN的列?

1
似乎很明显,这完全取决于数据库的要求以及每个相应操作在其上执行的负荷。谢谢答案。 - Stephen Collins
我认为这个过程是设计数据库和表到第三或第四范式,然后为了性能而去规范化。这个过程不是由开发人员的感觉来决定列数的吗? - jww
50列并不算多,但在我看来,当表格的列数超过300、400时,你必须审视整个应用程序以及设计它的人,并查看是否存在重复模式。你可能会发现一些。在生产应用程序中拆分大型表格可能很困难,因此最好从良好的基础开始。 - Alex M
9个回答

84
的设计取决于需要存储的实体。如果所有数据都属于同一个实体,那么可能需要使用50个(甚至100个)列。

只要表格是规范化的,除了数据库能力和优化需求外,没有关于大小的经验法则。


我知道这是老问题,请见谅。我有一个包含50个列的表格,例如。我在C#中有一个模型类,其中所有列都作为属性。我需要一个不可变对象,这意味着,除其他事项外,我必须通过ctor传递所有50个列。对于如何最好处理此场景,您有什么想法吗? - Benson O.

15

我同意Oded的观点。我曾经见过有500列的表,并且其中所有列都在正确的位置上。考虑一下人们可能想要存储关于日常物品的事实数量,你很快就会明白为什么这些表格需要如此多的列。

如果选择所有这些列或者只对其中一小部分感兴趣时需要指定哪些列,这可能会变得不方便,这时你可以考虑定义一个视图。


9

多少列才算太多?

当你感觉再添加一列不再合理或正确时。

通常取决于应用程序。


8
拥有太多列会导致许多空值(不好)和映射到表的难以操作的对象。这会降低IDE的可读性并阻碍维护(增加开发成本)。如果您需要在某些情况下快速读取,请使用非规范化表格,例如仅用于报告或查询的表格(搜索“CQRS”模式)。是的,“人”有一百万个属性,但您可以将这些单体表格(设计优先于规范化)分解为匹配较小实体(“地址”,“电话”,“爱好”),而不是为每个新用例添加新列。拥有较小的对象(和表格)带来了许多优点;它们使单元测试、面向对象编程和SOLID实践等变得可能。
此外,关于为了避免连接而将众多列分组,我认为通过索引维护,避免连接所获得的性能收益将会丧失,假设读写工作负载都很典型。为了提高读取性能而在字段上添加索引可能表明需要将这些字段移动到自己的表中。

4

odbc的字符限制为8000个,这是一个物理限制,超过这个限制会让事情变得非常令人沮丧。

我曾经处理过一个有138列的表格...它写得很糟糕,本可以规范化。尽管这个数据库似乎是某个人创建的,他想知道为什么有数据库设计约定,并决定一次性测试所有这些约定。

当你进入数据仓库和报告服务器时,拥有非常宽的扁平表格是相当普遍的。它们只是更快,意味着你不必为了性能而完全将数据库存储在RAM中。


3

这也高度取决于您表格的使用情况。如果您想将其优化为读取,则将其全部保留在一个表中可能是一个好主意。

在NO-SQL世界(例如cassandra / hbase),没有列数限制,实际上拥有许多列被认为是一种良好的做法。这也来自存储方式(无间隙)。值得探究。


2
根据我的经验,在大型数据库中,连接次数太多往往会导致问题,因此最好尽量减少连接次数。只要您的数据库表被设计为存储单个实体(例如学生、教师等),这应该是可以接受的。这样,在您的代码中,它将表示为一个对象。因此,如果您将实体拆分到多个表中,则稍后需要使用多个连接来填充对象。此外,如果您使用ORM生成数据访问层(例如.Net中的Linq),它将为每个表生成单独的类(当然它们之间有关系但仍然)并且这将更难使用。
另一件事是,您可以指定要在查询中返回哪些列,这将减少传递到应用程序的数据量,但是如果您需要从另一个表中获取单个列,则必须进行连接。在大多数情况下,由于有这么多列,因此在数据库中存储大量数据的可能性很高。因此,这种连接会比NULL更有害。
我曾经参与的每个项目都是不同的,因此您应该为每个场景找到平衡点。

非常正确。显然,连接和多个选择查询很慢,因此应该考虑去规范化,只要不破坏一致性,就像你所建议的那样。 - JCasso

1
哪个会更影响性能: 有许多包含大量NULL的列,还是较少的列具有大量JOIN?
这完全取决于您存储的数据、建立的索引等。没有人可以保证哪种方式比另一种效果更好,除非知道您正在存储什么。通常,规范化规则将“强制”您将数据分别存储到不同的表中,并使用FKeys(外键)如果您有大型表,但我不同意它总是比一个大表性能更好。在许多查询中,您可能会遇到6-7级联接,有时会导致错误,因为在大型查询中创建错误的机会比简单查询要多得多。
如果您发布有关您所做的工作的某些要求,也许我们可以帮助您正确设计数据库。

-3

最好使用单个表,以避免在查询时使用连接,这取决于列是属于同一实体还是不同实体。

例如,假设您正在为工作流进行数据库设计,其中某些字段将由初级工人编辑,而某些字段将由高级工人编辑。在这种情况下,最好将所有列放在一个表中。


8
为什么它更好?以何种方式它更好? - John Saunders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接