laravel 5.4 指定的key太长,为啥数字191
Posted
技术标签:
【中文标题】laravel 5.4 指定的key太长,为啥数字191【英文标题】:laravel 5.4 specified key was too long, why the number 191laravel 5.4 指定的key太长,为什么数字191 【发布时间】:2017-10-05 13:00:54 【问题描述】:我知道这个问题已经讨论过、解决或关闭了。 但我想问的是,为什么是191?
Schema::defaultStringLength(191);
我试过了:如果是 192,那就错了。 191,好的。 在此之后,我还编辑了 database\migrations\xxx_user_table.php 改变这个
$table->string('name');
成为
$table->string('name', 255);
然后运行php artisan migrate,就ok了。 使用一些mysql工具查看用户表的架构, varchar 的名称长度实际上是 255,其他列是 191。
我看过这些文章 @https://laravel-news.com/laravel-5-4-key-too-long-error @Laravel migration: unique key is too long, even if specified @https://github.com/laravel/framework/issues/17508 @https://laravel.com/docs/master/migrations#creating-indexes
还有这个: @https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html
对于 InnoDB 表,索引键前缀长度限制为 767 字节 使用 REDUNDANT 或 COMPACT 行格式。例如,您可能会打 列前缀索引超过 255 个字符的此限制 TEXT 或 VARCHAR 列,假设是 utf8mb3 字符集和 每个字符最多 3 个字节。
但是为什么名称的长度为 255 是可以的? 而192*3 = 576,小于767,为什么192不行?
【问题讨论】:
5 个解决方法,从 MySQL 的角度来看:mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes 【参考方案1】:为什么限制为 191 个字符?
关键是 Laravel 5.4 defaults to utf8mb4
所以数据库假定每个字符最多 4 个字节。
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
如果更新为 utf8mb4,您引用的示例将完美排列。 强调在编辑处添加。
对于使用 REDUNDANT 或 COMPACT 行格式的 InnoDB 表,索引键前缀长度限制为 767 字节。例如,假设 utf8mb4 字符集且最大值为 4 个字节。
191 * 4 = 764
(工作)
192 * 4 = 768
(太大)
utf8mb4
引入了对 Supplementary Characters
的支持,这些支持不是 utf8
的一部分,其中包括表情符号。如需进一步了解您是否需要utf8mb4
,您可以从this *** answer on the question 开始。
我该如何解决这个问题?
如果您需要保持较大的字段大小,最快的解决方法是将默认值更改为 utf8
。 Laravel 5.3 and below defaulted utf8
, and that would be safe to use in most cases.
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
或者,您也可以set the charset
and collation
on specific tables in the DB Migration when creating that table。看起来像这样:
Schema::create('monitors', function (Blueprint $table)
$table->charset = 'utf8';
$table->collation = 'utf8_unicode_ci';
$table->increments('id');
$table->string('myString')->unique();
);
如果我需要utf8mb4
和长索引键怎么办?
This *** answer 应该是一个很好的起点。它讨论了设置innodb_large_prefix
以允许更长的密钥长度。
【讨论】:
只是一个澄清 - utf8 可以很好地使用 1 - 4 个字节来表示 Unicode 世界中的任何字符。问题是 mysql 的 utf8 实现使用 1-3 个字节,这意味着无法表示非常大的块(在基本的前 65K 代码点之外)。以上是关于laravel 5.4 指定的key太长,为啥数字191的主要内容,如果未能解决你的问题,请参考以下文章
laravel migration 指定的key太长;最大密钥长度为 767 字节 [重复]
Laravel 5.4 migrate时报错: Specified key was too long error
Laravel 5.4 migrate时报错: Specified key was too long error
Laravel 5.4 migrate报错:Syntax error or access violation: 1071 Specified key was too long; max key len