回答(28)
2 years ago
767字节是MySQL版本5.6(及之前版本)中InnoDB表的stated prefix limitation . MyISAM表的长度为1,000字节 . 在MySQL 5.7及更高版本中,此限制已增加到3072字节 .
您还必须注意,如果您在一个大字符或varchar字段上设置了一个索引,该字段为utf8mb4编码,则必须将最大索引前缀长度767字节(或3072字节)除以4,得到191.这是因为utf8mb4字符的最大长度为4个字节 . 对于utf8字符,它将是三个字节,导致最大索引前缀长度为254 .
您可以选择的一个选项是在VARCHAR字段上设置下限 .
另一种选择(根据response to this issue)是获得列的子集而不是整个数量,即:
ALTER TABLE `mytable` ADD UNIQUE ( column1(15), column2(200) );
调整需要获取密钥以进行调整,但我想知道是否值得查看有关此实体的数据模型,看看是否有改进可以让您实现预期的业务规则而不会遇到MySQL限制 .
2 years ago
如果任何人遇到INNODB / Utf-8尝试在 VARCHAR(256) 字段上放置 UNIQUE 索引的问题,请将其切换为 VARCHAR(255) . 似乎255是限制 .
2 years ago
当你达到极限 . 设置以下内容 .
INNODB utf8 VARCHAR(255)
INNODB utf8mb4 VARCHAR(191)
2 years ago
MySQL假设字符串中每个字符的字节数最差 . 对于MySQL 'utf8'编码,'s 3 bytes per character since that encoding doesn' t允许超出 U+FFFF 的字符 . 对于MySQL 'utf8mb4'编码,它___19629_是MySQL所谓的实际UTF-8 .
因此,假设您使用'utf8',您的第一列将占用索引的60个字节,而您的第二列将占用1500个字节 .
2 years ago
在查询之前运行此查询:
SET @@global.innodb_large_prefix = 1;
这将增加限制为 3072 bytes .
2 years ago
你使用什么字符编码?某些字符集(如UTF-16等)每个字符使用多个字节 .
2 years ago
Solution For Laravel Framework
按照Laravel 5.4.* documentation;您必须在 app/Providers/AppServiceProvider.php 文件的 boot 方法中设置默认字符串长度,如下所示:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
Explanation of this fix, given by Laravel 5.4. documentation:*
Laravel默认使用utf8mb4字符集,其中包括支持在数据库中存储“emojis” . 如果您运行的是早于5.7.7版本的MySQL版本或早于10.2.2版本的MariaDB,您可能需要手动配置迁移生成的默认字符串长度,以便MySQL为它们创建索引 . 您可以通过在AppServiceProvider中调用Schema :: defaultStringLength方法来配置它 . 或者,您可以为数据库启用innodb_large_prefix选项 . 有关如何正确启用此选项的说明,请参阅数据库的文档 .
2 years ago
我认为varchar(20)只需要21个字节,而varchar(500)只需要501个字节 . 所以总字节数是522,小于767.那么为什么我收到错误信息呢?
UTF8 requires 3 bytes per character 存储字符串,所以在你的情况下20 500个字符= 20 * 3 500 * 3 = 1560 个字节,这是 more than 允许 767 个字节 .
UTF8的限制是767/3 = 255 characters ,对于UTF8mb4,每个字符使用4个字节,它是767/4 = 191 characters.
如果您需要使用比限制更长的列,则有两种解决方案:
Use "cheaper" encoding (the one that requires less bytes per character)
在我的情况下,我需要在包含SEO字符串文章的列上添加唯一索引,因为我只使用 [A-z0-9\-] 字符用于SEO,我使用 latin1_general_ci ,每个字符只使用一个字节,因此列可以有767字节长度 .
Create hash from your column and use unique index only on that
对我来说另一个选择是创建另一个列,它将存储SEO的哈希值,此列将具有 UNIQUE 键以确保SEO值是唯一的 . 我还会将 KEY 索引添加到原始SEO列以加快查找速度 .
2 years ago
Specified key was too long; max key length is 767 bytes
您收到该消息,因为只有使用 latin-1 字符集时,1个字节才等于1个字符 . 如果使用 utf8 ,则在定义键列时,每个字符将被视为3个字节 . 如果使用 utf8mb4 ,则在定义键列时,每个字符将被视为4个字节 . 因此,您需要将您的关键字段's character limit by, 1, 3, or 4 (in my example) to determine the number of bytes the key field is trying to allow. If you are using uft8mb4, you can only define 191 characters for a native, InnoDB, primary key field. Just don't违反767字节 .
2 years ago
你可以添加md5长列的列
2 years ago
许多用户已经回答了有关您收到错误消息的原因的答案 . 我的答案是关于如何修复和使用它 .
打开MySQL客户端(或MariaDB客户端) . 它是一个命令行工具 .
它会询问您的密码,输入正确的密码 .
使用此选择您的数据库命令 use my_database_name;
数据库已更改
set global innodb_large_prefix=on;
查询OK,0行受影响(0.00秒)
set global innodb_file_format=Barracuda;
查询OK,0行受影响(0.02秒)
在phpMyAdmin或类似的东西上转到您的数据库以便于管理 . >选择数据库>查看表 structure >转到 Operations 选项卡 . >将 ROW_FORMAT 更改为 DYNAMIC 并保存更改 .
转到表的 structure 选项卡>单击 Unique 按钮 .
完成 . 现在它应该没有错误 .
此修复的问题是如果将db导出到另一台服务器(例如从localhost导出到真实主机),并且您无法在该服务器中使用MySQL命令行 . 你无法在那里工作 .
2 years ago
尝试使用utf8mb4将UNIQUE索引添加到VARCHAR(255)字段时遇到此问题 . 虽然这里已经很好地概述了这个问题,但我想为我们如何解决这个问题添加一些实用的建议并解决它 .
当使用utf8mb4时,字符计为4个字节,而在utf8下,它们可以为3个字节 . InnoDB数据库有一个限制,索引只能包含767个字节 . 所以当使用utf8时,你可以存储255个字符(767/3 = 255),但是使用utf8mb4,你只能存储191个字符(767/4 = 191) .
您完全可以使用utf8mb4为 VARCHAR(255) 字段添加常规索引,但会发生的情况是索引大小会自动截断为191个字符 - 如 unique_key 此处:
这很好,因为常规索引仅用于帮助MySQL更快地搜索数据 . 整个字段不需要编入索引 .
那么,为什么MySQL会自动为常规索引截断索引,但在尝试为唯一索引执行时会抛出显式错误?好吧,为了让MySQL能够确定插入或更新的值是否已经存在,它需要实际索引整个值而不仅仅是其中的一部分 .
在一天结束时,如果要在字段上具有唯一索引,则该字段的全部内容必须适合索引 . 对于utf8mb4,这意味着将VARCHAR字段长度减少到191个字符或更少 . 如果您不需要utf8mb4用于该表或字段,则可以将其放回utf8并保留255个长度字段 .
2 years ago
这是我原来的答案:
我只是丢弃数据库并重新创建这样的,并且错误消失了:如果存在rhodes则删除数据库; create database rhodes default CHARACTER set utf8 default COLLATE utf8_general_ci;
但是,它并不适用于所有情况 .
实际上,在VARCHAR列上使用索引的问题是字符集 utf8 (或 utf8mb4 ),VARCHAR列的字符长度超过一定长度 . 在 utf8mb4 的情况下,该特定长度为191 .
2 years ago
I did some search on this topic finally got some custom change
For MySQL workbench 6.3.7 Version Graphical inter phase is available
启动Workbench并选择连接 .
转到管理或实例,然后选择选项文件 .
如果Workbench要求您同意读取配置文件,然后按两次OK键允许它 .
在中心位置管理员选项文件窗口到来 .
转至InnoDB选项卡,如果未在“常规”部分中选中,则检查innodb_large_prefix .
将innodb_default_row_format选项值设置为DYNAMIC .
For Versions below 6.3.7 direct options are not available so need to go with command prompt
以管理员身份启动CMD .
转到安装mysql服务器的导演大多数情况下,它在"C:\Program Files\MySQL\MySQL Server 5.7\bin" so命令是"cd " "cd Program Files\MySQL\MySQL Server 5.7\bin" .
现在运行命令mysql -u userName -p databasescheema现在它要求各个用户的密码 . 提供密码并进入mysql提示符 .
我们必须设置一些全局设置,逐个输入以下命令设置全局innodb_large_prefix = on; set global innodb_file_format = barracuda; set global innodb_file_per_table = true;
现在最后我们必须默认改变所需表的ROW_FORMAT它的COMPACT我们必须将它设置为DYNAMIC .
使用以下命令alter table table_name ROW_FORMAT = DYNAMIC;
完成
2 years ago
改变你的整理 . 你可以使用几乎支持所有的 utf8_general_ci
2 years ago
我修复了这个问题:
varchar(200)
换成了
varchar(191)
所有超过200的varchar用191替换它们或设置它们的文本 .
2 years ago
根据下面给出的列,这2个变量字符串列使用 utf8_general_ci collation(隐含了 utf8 charset) .
在MySQL中, utf8 charset对每个字符使用最大值 3 bytes . 因此,它需要分配500 * 3 = 1500字节,这比MySQL允许的767字节大得多 . 这就是为什么你得到这个1071错误 .
换句话说,您需要根据字符集的字节表示来计算字符数,因为并非每个字符集都是单字节表示(如您所设想的那样) . MySQL中的 utf8 最多使用每个字符3个字节,767 /3≈255个字符,而对于 utf8mb4 ,最多使用4个字节的表示,767 /4≈191个字符 .
这也是知道MySQL
column1 varchar(20) utf8_general_ci
column2 varchar(500) utf8_general_ci
2 years ago
我发现此查询可用于检测哪些列的索引违反了最大长度:
SELECT
c.TABLE_NAME As TableName,
c.COLUMN_NAME AS ColumnName,
c.DATA_TYPE AS DataType,
c.CHARACTER_MAXIMUM_LENGTH AS ColumnLength,
s.INDEX_NAME AS IndexName
FROM information_schema.COLUMNS AS c
INNER JOIN information_schema.statistics AS s
ON s.table_name = c.TABLE_NAME
AND s.COLUMN_NAME = c.COLUMN_NAME
WHERE c.TABLE_SCHEMA = DATABASE()
AND c.CHARACTER_MAXIMUM_LENGTH > 191
AND c.DATA_TYPE IN ('char', 'varchar', 'text')
2 years ago
请检查是否 sql_mode
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
如果是的话,改为
sql_mode=NO_ENGINE_SUBSTITUTION
要么
重新启动服务器更改f文件(放下)
innodb_large_prefix=on
2 years ago
在创建表时将 utf8mb4 更改为 utf8 解决了我的问题 . 例如: CREATE TABLE ... DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 到 CREATE TABLE ... DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; .
2 years ago
对于laravel 5.6
要遵循的步骤
转到 App\Providers\AppServiceProvider.php .
将此添加到顶部的提供商 use Illuminate\Support\Facades\Schema; .
在Boot功能内添加 Schema::defaultStringLength(191);
所有,享受 .
2 years ago
将抱怨索引字段的CHARSET更改为"latin1"
即ALTER TABLE tbl CHANGE myfield myfield varchar(600)CHARACTER SET latin1 DEFAULT NULL;
latin1为一个字符而不是四个字符占用一个字节
2 years ago
如果您正在创建以下内容:
CREATE TABLE IF NOT EXISTS your_table (
id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
name varchar(256) COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;
它应该是这样的
CREATE TABLE IF NOT EXISTS your_table (
id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
name varchar(256) COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;
但是您需要从代码中检查该列的唯一性,或者将新列添加为varchar列的MD5或SHA1
2 years ago
就我而言,当我使用linux重定向输出/输入字符备份数据库时,我遇到了这个问题 . 因此,我按如下所述更改语法 . PS:使用linux或mac终端 .
备份(没有>重定向)
# mysqldump -u root -p databasename -r bkp.sql
恢复(没有
# mysql -u root -p --default-character-set=utf8 databasename
mysql> SET names 'utf8'
mysql> SOURCE bkp.sql
错误“指定密钥太长;最大密钥长度为767字节”简单消失 .
2 years ago
5解决方法:
限制是在5.7.7(MariaDB 10.2.2?)中提高的 . 并且可以通过5.6(10.1)中的一些工作来增加它 .
如果因为尝试使用CHARACTER SET utf8mb4而达到极限 . 然后执行以下操作之一(每个都有一个缺点)以避免错误:
⚈ Upgrade to 5.7.7 for 3072 byte limit -- your cloud may not provide this;
⚈ Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?);
⚈ ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese;
⚈ Use a "prefix" index -- you lose some of the performance benefits.
⚈ Or... Stay with older version but perform 4 steps to raise the limit to 3072 bytes:
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_large_prefix=1;
logout & login (to get the global values);
ALTER TABLE tbl ROW_FORMAT=DYNAMIC; -- (or COMPRESSED)
2 years ago
如果您最近更改了 innodb_log_file_size ,请尝试恢复之前有效的值 .
2 years ago
对我来说,通过将列大小限制为200来更改primarykey / uniquekey组合后,“#1071 - 指定密钥太长;最大密钥长度为767字节”的问题得到了解决 .
ALTER TABLE `mytable` ADD UNIQUE (
`column1` (200) ,
`column2` (200)
);
2 years ago
如果您运行Laravel(laravel现在默认为4字节Unicode导致这一点),您可以通过更改config / database.php中的下一行来解决此问题 .
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
到
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
如果觉得《java获取密钥长度_#1071 - 指定密钥太长;最大密钥长度为767字节》对你有帮助,请点赞、收藏,并留下你的观点哦!