繁体   English   中英

MySQL:列大小限制

[英]MySQL: column size limit

我目前正在开发Windows操作系统,我已经安装了MySQL社区服务器5.6.30,一切都很好。 我有一个初始化数据库的脚本,并且一切正常。

现在我正在尝试在Linux环境中运行此脚本 - 相同的MySQL版本 - 我收到以下错误:

第3行的错误1074(42000):列'txt'的列长太大(max = 21845); 请改用BLOB或TEXT

脚本 -

DROP TABLE IF EXISTS text;
CREATE TABLE `texts` (
  `id` BINARY(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `txt` VARCHAR(50000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

显然我的Windows操作系统上有一些我需要在Linux上复制的MySQL服务器配置; 任何人都可以分享想法吗?

更新1

在AWS的RDS上,它也可以工作,我非常确定它只是一个基于Linux的服务,所以显然它只是一个配置问题。

有没有人知道如何用UTF8达到varchar 50k? 我不想使用TEXT或MEDIUMTEXT或其他任何东西,只是普通的旧varchar(大小)

更新2

我很欣赏所提出的不同的解决方案,但我不寻找新的解决方案我只是寻找答案,为什么varchar(50k)在Windows下工作,在linux下它没有。 顺便说一句,我使用字符集UTF8和collat​​ion utf8_general_ci。

回答

回答我自己的问题,它是SQL_MODE的问题,它被设置为STRICT_TRANS_TABLES并且应该被删除。

根据文件:

尽管InnoDB在内部支持大于65,535字节的行大小,但MySQL本身对所有列的组合大小施加了行大小限制65,535:

 mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000), -> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000), -> f VARCHAR(10000), g VARCHAR(10000)) ENGINE=InnoDB; 

ERROR 1118(42000):行大小太大。 使用的表类型的最大行大小(不计算BLOB)是65535.您必须将某些列更改为TEXT或BLOB

(不幸的是,这个例子没有提供字符集,所以我们真的不知道列有多大。)

utf8编码每个字符使用1,2或3个字节。 因此,可以安全地适合65,535字节(MySQL最大值)页面的最大字符数是21,845个字符(21,845 * 3 = 65,535)。

尽管版本相似,但似乎Windows的空间分配保守,并保证您可以在该字段中存储任何字符。 Linux似乎有更自由放任的态度。 您可以存储一些超过21,845个字符的字符串,具体取决于字符。

我不知道为什么在同一版本中存在这种差异。 在某种意义上,这两种方法都是“正确的”。 有足够简单的解决方法:

  • 使用TEXT
  • 切换到具有较短字符的排序规则(可能是您要存储的字符)。
  • 减小场地的大小。

请简单地使用TEXT声明txt列

DROP TABLE IF EXISTS text;
CREATE TABLE `texts` (
  `id` BINARY(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `txt` TEXT DEFAULT NULL,
   PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

utf8每个字符最多需要3个字节。 utf8mb4:4; 拉丁1:1; ascii:1; VARCHAR(N)在文本的字节前面实现为1或2字节长度。 允许保存N个字符 (不是字节)。 所以,如果你说你想要utf8,那么3 * N必须小于65535,这是2字节长度的最大值。

很高兴你没有在旧版本中运行,其中VARCHAR的限制为255。

如果你的txt不需要ascii或英文以外的字符,那么使用CHARACTER SET latin1

在InnoDB中,当存在“长”字段(大字符,文本,blob等)时,部分或全部列存储在单独的块中。 对于记录中存储的内容,存在大约8000字节的限制。

如果你真的需要50K的utf8,那么MEDIUMTEXT就是你所需要的。 它使用3字节长度,最多可容纳16M字节(5M字符,可能更多,因为utf8是可变长度编码)。

大多数应用程序可以(应该?)使用ascii (每个字符1个字节)或utf8mb4 (每个字符1-4个字节)。 后者允许使用所有语言,包括表情符号和utf8无法处理的4字节中文字符。

至于为什么Windows和Linux在这里的工作方式不同,我不知道。 你使用的是同一个版本吗? 建议您使用http://bugs.mysql.com提交错误报告。 (并提供此问题的链接。)

如果你绝对必须使用varchar - 这是解决这个问题的一个不好的方法! - 那么这是你可以尝试的东西:

CREATE TABLE `texts` (
  `id` BINARY(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `txt` VARCHAR(20000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `texts2` (
  `id` BINARY(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `txt` VARCHAR(20000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `texts3` (
  `id` BINARY(16) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
  `txt` VARCHAR(10000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

有50000个字符。 现在,您的客户端应用程序必须管理将文本分解为单独的块,并在每个表中创建记录。 同样,重新阅读文本将要求您执行3个选择语句,但您将拥有50000个字符。

对于任何数据库实现,都不建议这样做。

我曾经在一些环境中工作,在这些环境中,大型文本存储在数据库的列中,并且它总是会导致比解决的问题更多的问题。

这些应该真正假脱机到磁盘上的文件,以及对存储在数据库中的文件的完整路径的引用。

然后在这个文档集上运行一些索引引擎。

您将从此获得更大的可扩展性,并且更容易管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM