错误代码1117列太多。表的MySQL列限制


37

我有一张包含1699列的表格,当我尝试插入更多列时,

错误代码:1117。列太多

在此表中,我只有1000行。对我来说,最重要的是列数。桌子上有什么限制吗?我想创建2000列。那可能吗?


21
好主啊,干什么。这闻起来就像数据库设计异常疯狂。也许您使用的工具不正确。也许您应该看一下数据库的规范化
Zoredache

12
将显示器旋转90度。更严重的是,MySQL(或几乎所有其他RDBMS)并不是为那么多列而设计的。

11
为什么将2000个传感器引导到2000列?重新设计您的数据库。创建一个单独的传感器表或其他内容,但不要将每个传感器添加为新列。那真是令人难以置信的错误。

6
最大桌子数...哇!您可能只需要几个表。甚至不考虑创建2000个表而不是2000个列!

2
请,请,请阅读有关数据库规范化的信息

Answers:


35

为什么您需要创建一个甚至有20列的表,更不用说2000了?

授予的,非规范化的数据可以避免必须执行JOIN来检索数据的许多列。但是,如果列数超过10,则应该停下来思考在数据检索过程中可能发生的情况。

如果2000列表经过SELECT * FROM ... WHERE,您将在处理期间生成大型临时表,获取不需要的列,并创建许多情况,在这些情况下,通信包(max_allowed_pa​​cket)将在每次查询时都处于边缘。

在开发初期,我在1995年曾在一家公司工作,当时DB2是主要的RDBMS。该公司有一个包含270列,数十个索引的表,并且在检索数据时遇到性能问题。他们联系了IBM,并请顾问检查了他们系统的体系结构,包括一张整体表。该公司被告知:“如果您在未来两年内不对该表进行规范化,那么DB2将在执行Stage2处理的查询(任何需要对未索引列进行排序的查询)上失败。” 有人告诉一家价值数万亿美元的公司,以规范化270列表。2000列表还有多少呢?

在mysql方面,您必须通过设置与DB2 Stage2处理相当的选项来补偿这种不良设计。在这种情况下,这些选项是

如果您具有TB的RAM,则对这些设置进行Tweeking来弥补数十列(更不用说数百列)的存在了。

如果您使用InnoDB,此问题会成倍增加,因为您将不得不处理MVCC(多版本并发控制),试图通过事务隔离来保护每个SELECT,UPDATE和DELETE的大量列。

结论

没有替代品或创可贴可以弥补糟糕的设计。请为了您将来的理智,今天将这张桌子归一化!!!


1
我可以想像一下,这件事该公司将如何做。他们添加svn挂钩或创建“数据库最佳实践准则”,要求开发人员不要对SQL中未索引的列进行排序。相反,它们通过实现自己的大数据排序算法在应用程序内进行排序。
Gqqnbig

25

我很难想象任何数据模型可以在正确规范化的表中合法包含2000列的地方。

我的猜测是,您可能正在执行某种“填补空白”的非规范化模式,实际上您是在一张表中存储所有不同种类的数据,而不是将数据分解为单独的表并建立关系,您有多个字段来记录给定行中存储的数据的“类型”,而您90%的字段为NULL。即使如此,还是要达到2000列... yikes。

解决您的问题的方法是重新考虑您的数据模型。如果要存储大量与给定记录关联的键/值数据,为什么不这样建模呢?就像是:

CREATE TABLE master (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields that really do relate to the
    master records on a 1-to-1 basis>
);

CREATE TABLE sensor_readings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    master_id INT NOT NULL,   -- The id of the record in the
                              -- master table this field belongs to
    sensor_id INT NOT NULL,
    value VARCHAR(255)
);

CREATE TABLE sensors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields relating to sensors>
);

然后,要获取与给定的“主”记录关联的所有传感器条目,只需输入即可SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>。如果需要获取master表中记录的数据以及该记录的所有传感器数据,则可以使用联接:

SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>

如果需要每个传感器的详细信息,则可以进一步加入。


18

这是一个具有2000个传感器的测量系统

忽略所有关于标准化的喊话-您所要求的可能是明智的数据库设计(在理想的世界中)并且标准化得很好,这是非常不寻常的,而且正如其他地方指出的那样,RDBMS通常不是为这么多列而设计的。

尽管您没有达到MySQL的硬性限制,但链接中提到的其他因素之一可能是阻止您进一步发展的原因。

就像其他人建议的那样,您可以通过使用带有的子表来解决此限制id, sensor_id, sensor_value,或更简单地说,您可以创建第二个表以仅包含不适合第一个表的列(并使用相同的PK)


1
这是真的。认真处理数据和相应的SQL时,您的答案会更加突出!!!
RolandoMySQLDBA 2011年

3
使用子表不是“解决方法”。每个传感器只有一根色谱柱是不好的(错误的)设计。就像在HR系统中为每个员工提供一列,或者为每个管理汽车模型的数据库为每个汽车制造商提供一列。
a_horse_with_no_name

11
@a_horse-您正在做出我怀疑有效的假设。传感器的数量很可能基本固定,可以同时读取所有传感器,并且每次都返回数据。在这种情况下,每个传感器的一列不是“错误的”,考虑到数据库的限制,这仅仅是不切实际的。我想假设提问者不是白痴,除非得到其他证明,而且iUngi面对来自SF人群的非常无助的回应,做出了庄重的回应。
杰克·道格拉斯

2
@杰克·道格拉斯(Jack Douglas):即使您的所有假设都是正确的(我非常怀疑),将每个传感器值存储在其自己的列中,从长远来看也会造成麻烦。诸如“昨天到今天之间传感器10到50和25到100的平均值是多少”之类的查询呢?或“上周一哪个传感器的读数最高?”。尝试使用2000列为此编写查询。从长远来看,使用标准化表将比现在解决2000列解决方案解决更多的问题。
a_horse_with_no_name 2011年

2
当然,如果传感器正在存储相关值-我假设它们是不相关的(例如,它们都在测量不同种类的东西,而不是在不同位置测量的基本上是同一件事)。您可能会怀疑,但只有OP可以肯定知道-在医学或科学领域这并非不可能。
杰克·道格拉斯

15

MySQL 5.0列数限制(添加了重点):

每个表有4096列的硬限制,但是对于给定的表,有效最大值可能会更少。确切的限制取决于几个相互作用的因素。

  • 每个表(与存储引擎无关)的最大行大小为65,535字节。存储引擎可能会对此限制施加其他限制,从而减小有效的最大行大小。

    最大行大小限制了列数(可能还有大小),因为所有列的总长度不能超过该大小。

...

各个存储引擎可能会施加其他限制表数的限制。例子:

  • InnoDB最多允许1000列。

7

首先是更多的燃烧,然后是一个真正的解决方案...

我大体上同意已经向您扑来的火焰。

我不同意键值标准化。查询最终变得可怕。性能更差。

避免当前问题(列数限制)的一种“简单”方法是“垂直分区”数据。假设有5个表,每个表有400列。它们都将具有相同的主键,除了一个可能是AUTO_INCREMENT。

也许最好决定最重要的十二个字段,然后将它们放入“主”表中。然后以某种逻辑方式将传感器分组,然后将它们放入几个并行表中。使用正确的分组,您可能不必一直都联接所有表。

您是否在索引任何值?您需要搜索它们吗?您可能在日期时间搜索?

如果您需要索引很多列-平底锅。

如果您需要索引一些-将它们放入“主表”中。

这是真正的解决方案(如果适用)...

如果您不需要索引大量的传感器,则不要创建列!是的,你听到了我的声音。取而代之的是,将它们收集到JSON中,压缩JSON,并将其存储到BLOB字段中。您将节省大量空间;您将只有一个表,没有列限制问题;等等。您的应用程序将解压缩,然后使用JSON作为结构。你猜怎么了?您可以拥有结构-您可以将传感器分组为数组,多级内容等,就像您的应用程序希望的那样。另一个“功能”-它是开放式的。如果添加更多传感器,则无需更改表。JSON(如果灵活)的话。

(压缩是可选的;如果您的数据集很大,它将有助于磁盘空间,从而提高整体性能。)


这是实际的最佳答案。可以发表评论,也许他应该研究没有那么多专栏,但是对于公认的答案是“不做那”并不能回答问题。即使这个人并不需要那么多的列,也许其他人找到这个Q确实也需要那么多,并且需要一个真实的答案。
BoB3K

@ BoB3K- 考虑到问题的可用信息,我的大段文字说了怎么JSON避免“列太多”;索引选定的列有助于提高性能。
瑞克·詹姆斯

3

我认为这是大数据世界中的一种可能方案,在这种情况下,您可能不会执行传统的select *类型的查询。我们在客户级别的预测建模世界中处理此问题,我们在数千个维度上对客户进行建模(所有维度的值为0或1)。当您在同一行中同时具有风险因素和同一行中的结果标记时,这种存储方式使下游模型构建活动等更加容易。这可以从具有父子结构的存储立场上标准化,但是下游的预测模型将需要将其转换回平面模式。我们使用redshift进行列存储,因此在加载数据时,您的1000+列实际上以列格式存储...

此设计存在时间和地点。绝对。规范化不是解决每个问题的方法。


感谢您的评论。如果要对图像进行分析,即使是一张16x16像素的彩色图像也需要在0到255之间的16 * 16 * 3整数(使用RGB颜色在16x16像素中使用3个数字来描述颜色)。768列仅用于数据,需要向其中添加一个键。
VictorZurkowski
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.