2010-07-06 97 views
32

我注意到很多人在这里引用了一张表中有20+(我见过多达55)列的表格。现在我不假装成为数据库设计专家,但我一直听说这是一种可怕的做法。当我看到这一点时,我通常建议将它们分成两个表,一对一的关系:一个包含最常用的数据,另一个包含最少使用的数据。虽然在同一时间,可能存在性能问题(少JOINs等)。所以我的问题是这样的:有多少列是太多列?

当涉及到真正大规模的数据库时,实际上有大量列的优点,尽管这通常会导致很多NULL值?

哪种性能更好:大量的NULL列很多,或者列数较少的JOIN?

+0

看起来很明显,它完全取决于数据库的要求以及每个操作在其上执行的重要程度。感谢您的答案。 – 2010-07-06 08:34:12

回答

39

表的设计取决于它需要存储的实体。如果所有的数据都归属于一起,则50列(甚至100列)可能是正确的。

只要表格是normalized,除了数据库功能和需要优化之外,关于大小没有经验法则。

3

我同意Oded。我看过有500列的桌子,其中的所有列都在正确的位置。只要考虑一下人们可能希望存储的关于日常物体的事实数量,你很快就会明白为什么。

如果证明不方便选择所有这些列,或者指定当您只对其中的一小部分感兴趣时选择哪些列,则可能会发现值得定义一个视图。

0

哪个更性能命中: 大量列有很多空值的,或者有很多的JOIN的 较少的列?

它完全取决于您存储的数据,您创建的索引等。没有人能确保你在不知道你在储存什么的情况下比另一个更好。一般来说,规范化规则将“强制”你将数据分离到不同的表和用户FKeys,如果你有大表,但我不同意它总是比一个大表表现更好。您可以在数十个查询中以6-7级别连接结束,这些查询有时会导致错误,因为在大型查询中创建错误的机会大大增加。

如果您发布了一些您正在做的事情,也许我们可以帮助您正确设计数据库。

1

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

我在一张有138列的表格上工作过,它写得很糟糕,可能已经正常化了。虽然这个数据库似乎是某人想知道为什么数据库设计中有约定,并决定一次测试它们。

当您进入数据仓库和报表服务器时,具有非常宽的平整表格是相当常见的。它们速度更快,意味着您不必将数据库存储在内存中以获得性能。

4

有多少列是太多列?

当你觉得它不再有意义或者是正确的添加另一列。

一般取决于应用。

1

根据我的经验,最好减少连接数,因为这些连接往往发生得太频繁,特别是在大型数据库中。只要你的数据库表被设计为存储单个实体(学生,老师等),这应该是没问题的。因此,这将在稍后的代码中作为对象表示。所以,如果你将实体分成几个表,你将不得不使用几个连接来填充你的对象。此外,如果您使用ORM生成数据访问层(如.Net中的Linq),将为每个表生成单独的类(当然,它们之间存在关系但仍然存在),并且这将很难使用。

另一件事是,您可以指定要在您的查询中返回哪些列,这将减少传递给您的应用程序的数据,但是如果您需要从另一个表中获得单个列,则必须执行连接。而且在大多数情况下,因为您有很多列,那么在数据库中存储大量数据的概率很高。所以这个连接会比NULL更有害。

我所从事的每个项目都不同,因此您应该为每个故事找到平衡点。

+0

非常真实。显然,联接和多选查询很慢,因此应尽可能考虑非规范化,而不会像您所建议的那样破坏一致性。 – JCasso 2017-09-27 15:49:51

0

它也高度依赖于您的表的用例。如果你想优化它的阅读,那么把它放在一张表中可能是一个好主意。

在NO-SQL世界(例如cassandra/hbase)中,对列的数量没有限制,实际上有很多列是一个很好的做法。这也来自它存储的方式(没有差距)。值得一边调查。

-4

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

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

+3

-1:_why_是更好吗? _哪种方式更好? – 2014-05-30 07:21:15

0

如果列太多,会导致很多空值(邪恶)以及该表映射到的难以操作的对象。这会影响IDE的可读性并妨碍维护(增加开发成本)。如果在某些情况下需要快速读取,请使用非规格化表格仅用于报告或查询(搜索“CQRS”模式)。是“人”有一百万个属性,但是您可以分解这些单一表(设计优先于标准化)以匹配较小的实体(“地址”,“电话”,“业余爱好”),而不是为每个新用例添加新列。具有较小尺寸的物体(和桌子)带来如此多的优点;他们可以实现单元测试,OOP和SOLID实践等功能。另外,因为它涉及聚集许多列以避免连接,所以我认为,通过索引维护,假设典型的读写工作负载,避免连接带来的性能收益会丢失。为了读取性能而在字段上添加索引可能表示需要将这些字段移动到它们自己的表中。