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: 特殊字段太长报错

Laravel 5.4 migrate时报错: Specified key was too long error

Laravel 5.4数据库迁移不起作用[重复]

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