Laravel 数据i迁移报错1071 Specified key was too long; ma...

每次新安装的Laravel,在执行数据库迁移操作时都会报错提示一个有关于字符串长度的报错,原因:字段太长导致无法加索引。

网上有许多同类的人和我遇到了,有的人说是MySQL的版本问题,但我尝试发现就算是用MySQL8.0版本都无济于事,那么我就整理一下所有我遇到的解决方法一一列出,希望能帮到你。

一、MySQL版本,指定默认字符串长度

Laravel 默认使用 utf8mb4 字符,它支持在数据库中存储 "emojis" 。 如果你是在版本低于 5.7.7 的 MySQL release 或者版本低于 10.2.2 的 MariaDB release 上创建索引,那就需要你手动配置迁移生成的默认字符串长度。

打开app/Providers/AppServiceProvider.php文件,从中调用Schema::defaultStringLength方法来配置它,注意头部的use

use Illuminate\Support\Facades\Schema;
 
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}
二、开启数据库的innodb_large_prefix选项

使用管理员身份登录到MySQL,并执行如下命令,限制值则会上升到3072

mysql> set global innodb_file_format = BARRACUDA;
Query OK, 0 rows affected (0.00 sec)
 
mysql> set global innodb_large_prefix = ON;
Query OK, 0 rows affected (0.00 sec)
三、修改vendor目录文件,将默认字符串写死

打开vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php文件,找到第39行

public static $defaultStringLength = 255;//改为
public static $defaultStringLength = 191;
四、修改字段长度

打开database/migrations/2014_10_12_000000_create_users_table.php文件,修改user表email字段长度

$table->string(''email'')->unique();//改为
$table->string(''email'', 191)->unique()->change();

{注} 只有下面的字段类型能被 "修改": bigInteger、 binary、 boolean、date、dateTime、dateTimeTz、decimal、integer、json、 longText、mediumText、smallInteger、string、text、time、 unsignedBigInteger、unsignedInteger and unsignedSmallInteger

上面的几种方法其实也不一定只适用于Laravel,道理都是一样的,如果禁用innodb_large_prefix,不管是什么表,索引键前缀限制为767字节。

例如改变varchar的字符数,改成低于上限的值就可以了。如varchar(64)。

我们需要修改字段长度,注意编码格式,utf8 下 3 字节表示一个字符,utf8mb4 是 4 字节表示一个字符,以 innodb 存储引擎来换算:utf8 下长度 255 的字符索引占 255X3=765 字节,但 Laravel 默认使用 utf8mb4 ,这样 255X4=1020,超过了 767 字节,改成 191 后,191X4=764 字节。这也是为什么要指定默认字符串长度191,其实如果你用不么这么长,指定小于191的也可以。所以修改字段长度时要根据报错提示的长度以及你字段的长度和编码来修改;


版权声明:若无特殊注明,本文为《周小雨》原创,转载请保留文章出处。
本文链接:https://zxyy.me/post-185.html
正文到此结束

热门推荐

管理员已关闭本篇文章评论!