Laravel5.4 数据库迁移错误 SQLSTATE [42000] Syntax error or access violation 1071

laralve5.4版本中我写好了数据库迁移文件, 在本机的mysql5.7.23中执行没有问题.
但是提交git后同事(mysql5.6.*)执行该迁移就报错了很是奇怪.
从网上查找解决方案后,又尝试着深入写分析了下问题
以下记录了查找错误的过程.

In Connection.php line 647:                       
  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `password_reset  
  s` add index `password_resets_email_index`(`email`))                              

从报错信息可以看出:索引长度的最大限制是767bytes, 而欲在email字段创建的索引长度超过了这个范围

计算email字段索引长度

首先查看创建email字段并加索引的文件

 table->string('email')->index();

这样创建的email字段默认类型varchar默认长度为255, 编码(Collation)类型会读取laravelProject/config/database.php 中的配置

<?php

return [
    'connections' => [
        //...
        'mysql' => [
        //...
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
        ],
        //...
    ],
];

可以看出varchar会使用utf8mb4编码, utf8mb4编码(4bytes)属于utf8编码(3bytes)的扩展类型,
由此可以计算索引长度255*4+2=1022 >767

分析错误原因

对比laravel5.3和laravel5.4的laravelProject/config/database.php文件 可以看出
laravel5.4中改变了默认的编码类型(utf8 => utf8mb4), 从而使email字段索引长度超过了的默认限制长度.
而新版本mysql>= 5.7.7
(mysql5.7.7更新日志):默认打开了innodb_large_prefix ,使索引长度限制由767bytes增加到了3072bytes. 所以不会导致迁移报错.

mysql5.7.7更新日志

四种解决方案

知道原因后解决方案就很明显了

  1. 编辑AppServiceProvider.php

    use Illuminate\Support\Facades\Schema;
    public function boot()
    {
    Schema::defaultStringLength(191);
    }

    原理:改变了默认的string()方法生成的varchar长度,而191*4+2 = 766 < 767合法;

  2. 修改laravelProject/config/database.php 配置文件

    <?php
    return [
    'connections' => [
       //...
       'mysql' => [
       //...
           'charset' => 'utf8',
           'collation' => 'utf8_unicode_ci',
       ],
       //...
    ],
    ];

    原理: 将默认编码仍然修改为utf8编码.

  3. 升级mysql>=5.7.7

  4. 修改mysql配置

    如果由于某些原因你不能升级你的数据库版本,则可以单独修改数据库的配置,解除innodb_large_prefix的限制.(需FQ)

以上解决方案任选其一即可!!!

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!