mysql-多少列太多?


111

我正在设置一个可能有70列以上的表格。我现在正在考虑将其拆分,因为每次访问表时都不需要列中的某些数据。再说一次,如果我这样做,我就不得不使用联接。

在什么时候(如果有的话)是否认为列太多?


6
我们不必一直使用SELECT *。我们始终可以选择仅针对给定情况选择所需的列。
APC

3
70列?其中有多少不能为空?
OMG小马

1
最大的问题是...您要标准化表格吗?除非您故意降低性能规格化(很少有东西具有70个独特的属性),否则70是不寻常的。如果您为了性能而进行非规范化,那么我会同意ChssPly76,您可以使用数据库允许的任何东西。
Godeke

2
@KM。那应该是个玩笑吗?我是MySQL的新手,无法理解,您是说JOIN是一件好事还是可以尝试避免的事情?
埃里亚·伊利亚申科

2
尽管联接是SQL的核心部分,但由于联接的缘故,联接可能会降低您所拥有的任何应用程序的性能和可维护性。
jeteon

Answers:


142

一旦超过数据库支持最大限制,就认为它太多了。

不需要每个查询都返回所有列的事实是完全正常的;这就是为什么SELECT语句可让您显式命名所需列的原因。

通常,您的表结构应反映您的域模型。如果您确实拥有属于同一实体的70个属性(100个,您拥有什么),则没有理由将它们分成多个表。


29
@KM-这就是为什么我说“域模型上属于同一实体的属性”的原因。表中的高列数不会使其标准化。这就是所说的列所代表的意义。此外,尽管规范化绝对是一件好事,但这并不是解决生活中所有问题的解决方案。技巧问题-您认为SO问题/答案旁边的票数是select count(*) from votes每次计算的,还是您认为它是非规范化的?这是否会使SO数据库变坏并使Jeff Atwood疯狂?
ChssPly76

@ ChssPly76,它是一个关系数据库,而不是对象模型。有表,行和列,如果要获得最大性能,则应在该约束内工作,为方便起见,为了方便起见,应模仿对象。那么,关于一个人的每条信息都应该存储在同一行中吗?不,将它们分开并分组到不同的表中(使用我以前的注释中的示例):“人”,“活动”,“健康记录”。出于性能原因而存储SUM与将所有数据保留在70列以避免连接的问题完全不同。
KM。

20
“ numberOfTeethPulled”是否应该成为Person记录的一部分?不,它可能根本不应该存储-如果您的域模型需要这样的详细程度,则可以从“ ToothExtractionRecord”中获取该信息。但这只是您的示例(我敢说,是人为的),与我的观点无关:表中的大量列并不意味着表会被非规范化。想一下房地产合同/采购订单/其他财务文件,仅举几个例子。可以将它们进一步拆分成多个表吗?是。有什么理由吗?并不是的。
ChssPly76

1
+1,好笑。如果要创建另一个表,并且该表将是1:1关系,则可能应将其包括在主表中。它不会节省空间,如果您不请求数据而不是根本不在表中,它的性能将不会更好。我现在想到的唯一合法的原因是,其中是否包含敏感信息,例如SSN,信用卡信息等…
Vandel212 '18

1
如果我有一个表有15个列,而另一个表有300个列,则两个表的主键是相同的。在两个表中选择一列,性能会明显不同吗?
报价不能拒绝

28

将表拆分为几列,减少列数,这也有一些好处,这也称为“ 垂直分区”。这里有一些:

  1. 如果您的表具有许多行,则修改索引可能会花费很长时间,因为MySQL需要重建表中的所有索引。将索引分成几个表可以使速度更快。

  2. 根据您的查询和列类型,MySQL可能正在将临时表(用于更复杂的选择查询)写入磁盘。这很不好,因为磁盘I / O可能是一个很大的瓶颈。如果查询中有二进制数据(文本或Blob),则会发生这种情况。

  3. 表变宽会导致查询性能降低。

不要过早地进行优化,但是在某些情况下,您可以从较小的表中获得改进。


5
如果仅修改一个索引,为什么MySQL需要重建表中的所有索引?
Petr Peller

我在想同样的事情。为什么MySQL重建表中的所有索引?上述说法正确吗?
少校

13

当它违反规范化规则时,它太多了。如果要规范化数据库,那么很难获得那么多列。设计数据库以对问题进行建模,而不是围绕任何针对特定数据库平台进行优化的人为规则或想法。

将以下规则应用于宽表,则单个表中的列可能会少得多。

  1. 没有重复的元素或元素组
  2. 对级联键没有部分依赖
  3. 不依赖于非关键属性

这是一个可以帮助您的链接


17
It is pretty hard to get that many columns if you are normalizing your database.不像看起来那么难。
Petr Peller

5
绝对不是那么难。人们似乎不太了解此处这些部分的正常形式。您可以有10000列,并且仍可以规范化(即使是最高规范形式)。
Hejazzman 2013年

2
@foljs正是这种公认的非规范化实践出现的地方。如果您在十字路口,并且有汽车要驶入您的车厢,那么等待指示灯变绿会很愚蠢。您必须摆脱困境。尽管通过红灯从技术上可能不合法,但您正在做显然应该采取的操作,因为情况是=非规范化
user3308043 2014年

3
当您开始谈论汽车时,您迷失了我。不知道相关性是什么。
JohnFx

2
但是,在这种情况下,如何使用单个数据表执行复杂的查询,您不能,您必须高度依赖于编程语言和各种其他内容才能实现此目的!因此,我不妨回到具有170列的表,因为在我看来,拥有“ JOIN”查询和使单独的表正常工作所需的额外复杂编程似乎是浪费时间。我想我是KISS原则的忠实拥护者。
弗拉德·弗拉基米尔·大力神

0

除非所有属性都属于同一实体并且彼此不依赖,否则这不是问题。为了让生活更轻松,您可以将一个带有JSON数组的文本列存储在其中。显然,如果您每次都获取所有属性都没有问题。尽管这将完全破坏将其存储在RDBMS中的目的,并使每个数据库事务都大大复杂化。因此,不建议在整个数据库中都遵循这种方法。


0

同一张表中的列过多也会导致复制中的巨大问题。您应该知道主服务器中发生的更改将复制到从服务器中。例如,如果您更新表中的一个字段,则整行将为w

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.