laravel 5.4指定键太长,为什么数字191

ron*_*run 9 laravel

我知道这个问题已经讨论,解决或关闭了.
但我想问的是,为什么数字191?

Schema::defaultStringLength(191);
Run Code Online (Sandbox Code Playgroud)

我试过:如果192,错了.191,好的.在此之后,我还编辑了database\migrations\xxx_user_table.php
更改此设置

$table->string('name');
Run Code Online (Sandbox Code Playgroud)

成为

$table->string('name', 255);
Run Code Online (Sandbox Code Playgroud)

然后运行php artisan migrate,没关系.使用一些mysql工具查看用户表的模式,varchar的名称长度实际为255,其他列为191.

我看到这些文章
@ https://laravel-news.com/laravel-5-4-key-too-long-error
@ Laravel迁移:唯一密钥太长,即使指定
@ 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

对于使用REDUNDANT或COMPACT行格式的InnoDB表,索引键前缀长度限制为767字节.例如,您可能会在TEXT或VARCHAR列上使用超过255个字符的列前缀索引达到此限制,假设为utf8mb3字符集,并且每个字符最多包含3个字节.

但为什么长度255的名字还可以?
并且192*3 = 576,小于767,为什么192不行?

Luk*_*ite 28

为什么限制在191个字符?

关键是Laravel 5.4 默认为utf8mb4这样,数据库假定每个字符最多4个字节.

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
Run Code Online (Sandbox Code Playgroud)

如果针对utf8mb4更新,您引用的示例将完美排列.重点添加在编辑的地方.

对于使用REDUNDANT或COMPACT行格式的InnoDB表,索引键前缀长度限制为767字节.例如,您可能会在TEXT或VARCHAR列上使用超过191个字符的列前缀索引达到此限制,假设为utf8mb4字符集,并且每个字符最多包含4个字节.

  • 191 * 4 = 764 (作品)
  • 192 * 4 = 768 (太大了)

utf8mb4引入的支持Supplementary Charactersutf8包括其中包括表情符号.有关是否需要的进一步阅读utf8mb4,您可以从问题的StackOverflow答案开始.

我该如何解决?

如果您需要维持较大的字段大小,最快的修复方法是将默认值更改为utf8.Laravel 5.3及以下版本默认utf8,在大多数情况下使用是安全的.

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
Run Code Online (Sandbox Code Playgroud)

或者,您可以在创建该表时在数据库迁移中设置charsetcollation使用特定表.这看起来像这样:

Schema::create('monitors', function (Blueprint $table) {
    $table->charset = 'utf8';
    $table->collation = 'utf8_unicode_ci';

    $table->increments('id');
    $table->string('myString')->unique();
});
Run Code Online (Sandbox Code Playgroud)

如果我需要utf8mb4和长索引键怎么办?

这个StackOverflow答案应该是一个很好的起点.它讨论innodb_large_prefix了允许更长密钥长度的设置.