我目前正在开发Windows操作系统,我已经安装了MySQL社区服务器5.6.30,一切都很好。我有一个初始化数据库的脚本,而且一切正常。
现在我正在尝试在Linux环境中运行此脚本 - 相同的MySQL版本 - 我收到以下错误:
第3行的错误1074(42000):色谱柱长度过大 'txt'(最大= 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操作系统上有一些MySQL服务器配置需要在Linux上复制;任何人都可以分享想法吗?
更新1
在AWS的RDS上它也可以工作,我非常确定它只是一个基于Linux的服务,所以显然它只是一个配置问题。是否有人知道如何使用UTF8达到varchar 50k?我不想使用TEXT或MEDIUMTEXT或其他任何东西,只是普通的旧varchar(大小)
更新2
我很欣赏所提出的不同解决方案,但我不寻找新的解决方案,我只是在寻找答案,为什么varchar(50k)在windows下工作,在linux下也没有。 顺便说一句,我使用字符集UTF8和整理utf8_general_ci。
答案
回答我自己的问题,这是它设置的SQL_MODE的一个问题 STRICT_TRANS_TABLES,应该已被删除。
答案 0 :(得分:3)
根据文件:
尽管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
。答案 1 :(得分:1)
请简单地使用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;
答案 2 :(得分:1)
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提交错误报告。 (并提供本课题的链接。)
答案 3 :(得分:0)
如果你绝对必须使用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个字符。
根本不建议在任何数据库实施中执行此操作。
我曾在一些环境中工作,在这些环境中,大型文本存储在数据库的列中,并且它总是会导致比解决的问题更多的问题。
这些应该真正假脱机到磁盘上的文件,以及对存储在数据库中的文件的完整路径的引用。
然后在这个文档集上运行一些索引引擎。
您将从此获得更大的可扩展性,并且更容易管理。