当我执行以下命令时:
ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);
我收到了这个错误信息:
# 1071 - Specified key was too long; max key length is 767 bytes
关于第1列和第2列的信息:
column1 varchar(20) utf8_general_ci
column2 varchar(500) utf8_general_ci
我想 varchar(20)
只需要21字节 varchar(500)
只需要501字节。所以总字节数是522,小于767。为什么我会收到错误信息?
# 1071 - Specified key was too long; max key length is 767 bytes
18条答案
按热度按时间jjhzyzn01#
在查询之前运行此查询:
这将使限制增加到
3072 bytes
.3pmvbmvn2#
关于为什么会收到错误消息的答案已经被这里的许多用户回答了。我的答案是如何修复和使用它。
请参阅此链接。
打开mysql客户端(或mariadb客户端)。它是一个命令行工具。
它会询问你的密码,输入正确的密码。
使用此命令选择数据库
use my_database_name;
数据库已更改set global innodb_large_prefix=on;
查询正常,0行受影响(0.00秒)set global innodb_file_format=Barracuda;
查询正常,0行受影响(0.02秒)访问phpmyadmin或类似的数据库以便于管理。>选择“数据库”>“查看表结构”>“转到操作选项卡”。>将行格式更改为动态并保存更改。
转到表的结构选项卡>单击唯一按钮。
完成。现在它应该没有错误了。
此修复程序的问题是,如果将db导出到另一台服务器(例如从localhost到real host),并且不能在该服务器中使用mysql命令行。你不能在那里工作。
xcitsw883#
767字节是MySQL5.6版(及以前版本)中innodb表的前缀限制。myisam表有1000字节长。在MySQL5.7及更高版本中,此限制已增加到3072字节。
您还必须注意,如果在utf8mb4编码的大char或varchar字段上设置索引,则必须将767字节(或3072字节)的最大索引前缀长度除以4,得到191。这是因为utf8mb4字符的最大长度是四个字节。对于utf8字符,它将是三个字节,导致最大索引前缀长度为254。
一种选择是只对varchar字段设置下限。
另一种选择(根据对此问题的答复)是获取列的子集,而不是整个金额,即:
根据需要进行调整,以获得要应用的密钥,但我想知道是否值得检查有关此实体的数据模型,以查看是否有改进可以让您在不触及mysql限制的情况下实现预期的业务规则。
ecfdbz9o4#
当你到达极限时。设置以下选项。
innodb公司
utf8
VARCHAR(255)
innodb公司utf8mb4
VARCHAR(191)
brvekthn5#
5种解决方法:
5.7.7(10.2.2?)中提高了限制。并且可以通过5.6(10.1)中的一些工作来增加。
如果因为尝试使用字符集utf8mb4而达到限制。然后执行以下操作之一(每个操作都有缺点)以避免错误:
-- http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes
t1qtbnec6#
对于laravel 5.7至6.0
遵循的步骤
去
App\Providers\AppServiceProvider.php
.将此添加到提供程序
use Illuminate\Support\Facades\Schema;
在上面。在引导函数中添加
Schema::defaultStringLength(191);
就这些,享受吧。monwx1rj7#
我通过以下方法解决了此问题:
替换为
所有具有200个以上的唯一或主要varchar键都将它们替换为191或将它们设置为文本。
oxcyiej78#
你用什么字符编码?有些字符集(如utf-16等)每个字符使用超过一个字节。
qnakjoqk9#
mysql假设字符串中每个字符的字节数为最坏情况。对于mysql'utf8'编码,即每个字符3字节,因为该编码不允许超过3个字符
U+FFFF
. 对于mysql'utf8mb4'编码,它是每个字符4个字节,因为mysql称之为实际的utf-8。因此,假设您使用的是“utf8”,第一列将占用索引的60字节,第二列将占用另外1500字节。
relj7zay10#
我们在尝试使用utf8mb4向varchar(255)字段添加唯一索引时遇到了这个问题。虽然这个问题在这里已经被很好地概括了,但我想补充一些实用的建议,说明我们是如何解决这个问题的。
使用utf8mb4时,字符数为4字节,而在utf8下,字符数可以为3字节。innodb数据库有一个限制,索引只能包含767字节。因此,使用utf8时,可以存储255个字符(767/3=255),但使用utf8mb4时,只能存储191个字符(767/4=191)。
您完全可以为添加常规索引
VARCHAR(255)
字段使用utf8mb4,但实际情况是索引大小被自动截断为191个字符,就像unique_key
在这里:这很好,因为常规索引只是用来帮助mysql更快地搜索数据。整个字段不需要索引。
那么,为什么mysql会自动截断常规索引的索引,而在尝试对唯一索引执行此操作时却抛出显式错误呢?好吧,为了让mysql能够判断被插入或更新的值是否已经存在,它实际上需要索引整个值,而不仅仅是其中的一部分。
在一天结束时,如果您想在一个字段上有一个唯一的索引,那么该字段的全部内容必须适合该索引。对于utf8mb4,这意味着将varchar字段长度减少到191个字符或更少。如果该表或字段不需要utf8mb4,可以将其放回utf8,并能够保留255个长度字段。
yc0p9oo011#
以下是我最初的答案:
我只是删除数据库,然后像这样重新创建,错误就消失了:
drop database if exists rhodes; create database rhodes default CHARACTER set utf8 default COLLATE utf8_general_ci;
然而,它并不适用于所有的情况。这实际上是一个在varchar列和字符集上使用索引的问题
utf8
(或utf8mb4
),其中varchar列的字符长度超过一定长度。如果是utf8mb4
,一定长度是191。有关如何在mysql数据库中使用长索引的详细信息,请参阅本文中的长索引部分:http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
ct2axkht12#
你得到这个消息是因为只有当你使用
latin-1
字符集。如果你使用utf8
,在定义键列时,每个字符将被视为3个字节。如果你使用utf8mb4
,在定义键列时,每个字符将被视为4个字节。因此,您需要将键字段的字符限制乘以1、3或4(在我的示例中)来确定键字段尝试允许的字节数。如果您使用的是uft8mb4,则只能为本机innodb主键字段定义191个字符。只是不要突破767字节。7uzetpgm13#
如果有人对innodb/utf-8有意见
UNIQUE
a上的索引VARCHAR(256)
field,切换到VARCHAR(255)
. 似乎255是限制。h7wcgrx314#
替换
utf8mb4
与utf8
在导入文件中。hxzsmxv215#
您可以添加一列md5的长列