Laravel Migration Error:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

时间:2017-02-15 08:49:30

标签: mysql laravel pdo laravel-5 laravel-5.4

使用php artisan make:auth

的Laravel 5.4上的迁移错误
  

[Illuminate \ Database \ QueryException] SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节(SQL:alter tabl e users添加唯一users_email_uniqueemail))

     

[PDOException] SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长;最大密钥长度为767字节

41 个答案:

答案 0 :(得分:162)

根据official documentation,你可以很容易地解决这个问题。

将以下代码添加到 AppServiceProvider.php (/app/Providers/AppServiceProvider.php)

use Illuminate\Support\Facades\Schema; //NEW: Import Schema

function boot()
{
    Schema::defaultStringLength(191); //NEW: Increase StringLength
}
  

MySQL保留UTF8字段的最大数量,即4字节,因此255 + 255与您的默认字符集utf8mb4 COLLATE utf8mb4_unicode_ci;你超过767最大密钥长度限制。由@scaisedge

答案 1 :(得分:69)

我不知道为什么上面的解决方案和正在添加的官方解决方案

Schema::defaultStringLength(191);
AppServiceProvider中的

对我不起作用。 有用的是编辑database.php文件夹中的config文件。 只需编辑

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

它应该有效。 希望它有所帮助。

答案 2 :(得分:45)

我只是在这里添加此答案,因为它是 quickest 解决方案。只需将默认数据库引擎设置为 'InnoDB'

<强> /config/database.php

'mysql' => [
    ...,
    ...,
    'engine' => 'InnoDB',
 ]

然后运行 php artisan config:cache 以清除并刷新配置缓存

答案 3 :(得分:23)

AppServiceProvider.php中,您将此代码包含在文件顶部。

use Illuminate\Support\Facades\Schema;

然后在boot方法中添加此代码。

 Schema::defaultStringLength(191);

答案 4 :(得分:18)

此问题是由数据库版本在Laravel 5.4中引起的。

根据docsIndex Lengths & MySQL / MariaDB部分):

  

Laravel默认使用utf8mb4字符集,其中包括   支持在数据库中存储“emojis”。如果你正在运行   早于5.7.7版本或早于MariaDB的MySQL版本   在10.2.2版本中,您可能需要手动配置默认值   迁移生成的字符串长度,以便MySQL创建   他们的索引。您可以通过调用来配置它   Schema::defaultStringLength中的AppServiceProvider方法。

换句话说,在<ROOT>/app/Providers/AppServiceProvider.php

// Import Schema
use Illuminate\Support\Facades\Schema;
// ...

class AppServiceProvider extends ServiceProvider
{

public function boot()
{
    // Add the following line
    Schema::defaultStringLength(191);
}

// ...

}

但正如对其他答案的评论所说:

  

小心这个解决方案。例如,如果索引电子邮件字段,   存储的电子邮件最多只能有191个字符。这个更少   比官方的RFC声明。

因此,文档还提出了另一种解决方案:

  

或者,您可以为您启用innodb_large_prefix选项   数据库。有关的说明,请参阅数据库的文档   如何正确启用此选项。

答案 5 :(得分:14)

Laravel 7.X(也适用于 8X):简单解决方案

选项 1:

php artisan db:wipe 

更新/config/database.php

mysql数组的这些值(如下) <块引用>

'charset' => 'utf8', 'collation' => 'utf8_general_ci',

然后

php artisan migrate

大功告成!迁移表将成功创建。


选项 2:

使用 php artisan db:wipe 手动删除/删除数据库中的所有表。

更新您的AppServiceProvider.php [位于app/Providers/AppServiceProvider.php ]

use Illuminate\Support\Facades\Schema;
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191); 
}

然后

php artisan migrate

大功告成!

陷阱:我想提一下@shock_gone_wild 的评论

<块引用>

请注意此解决方案(选项 2)。例如,如果您索引电子邮件字段, 存储的电子邮件最多只能有 191 个字符。这个少 比官方 RFC 状态。


可选我尝试了这些可能的方法(如下所示)但不起作用

php artisan config:cache php artisan migrate:fresh

php artisan migrate:reset

答案 6 :(得分:13)

对于不想改变AppServiceProvider.php的人。 (在我看来,仅仅因为迁移而改变AppServiceProvider.php是个坏主意)

您可以将数据长度添加回 database/migrations/ 下的迁移文件,如下所示:

<强> create_users_table.php

$table->string('name',64);
$table->string('email',128)->unique();

<强> create_password_resets_table.php

$table->string('email',128)->index();

答案 7 :(得分:9)

如果使用命令php artisan migrate在laravel上工作时遇到此错误 那么您只需在文件中添加2行: app-> Providers-> AppServiceProvider.php

  1. use Schema;
  2. Schema::defaultStringLength(191);

请检查this image。 然后再次运行php artisan migrate命令。

答案 8 :(得分:6)

app/Providers/AppServiceProvider.php方法中添加以下代码:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

首先你必须删除(如果有的话)用户表, 来自数据库的 password_resets 表,并从迁移表中删除用户和password_resets条目,然后在删除旧表后运行php artisan migrate命令

答案 9 :(得分:6)

我已经解决了这个问题并编辑了我的config-&gt; database.php文件,就像我的数据库('charset'=&gt;'utf8')('整理'一样=&gt;'utf8_general_ci'),所以我的问题解决了以下代码:

'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_general_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],

答案 10 :(得分:6)

我要添加两个对我有用的sollution

1st sollution is

  1. 打开 database.php 文件,插入 config 目录/文件夹。
  2. 'engine' => null,编辑为'engine' => 'InnoDB',

    这对我有用。

第二种解决方法是:

  1. 打开 database.php 文件,并插入 config 目录/文件夹。
    2. 编辑
    'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',

    'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',


祝你好运

答案 11 :(得分:5)

不是设定长度限制,而是提出以下内容,这对我有用。

内部

  

配置/ database.php中

将此行替换为mysql

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

<强>

'engine' => null,

答案 12 :(得分:4)

如前所述,我们将添加到App / Providers中的AppServiceProvider.php

use Illuminate\Support\Facades\Schema;  // add this

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191); // also this line
}

您可以在下面的链接中查看更多详细信息(搜索&#34;索引长度&amp; MySQL / MariaDB&#34;) https://laravel.com/docs/5.5/migrations

但是,这不是我发布的所有内容!即使在执行上述操作时您可能会收到其他错误(&#39) ;当你运行php artisan migrate命令时,由于长度问题,操作可能会停留在中间。解决方案在之下,并且用户表可能是在没有其余的情况下创建的或者不完全正确) 我们需要回滚。默认回滚将不起作用。因为迁移的运作并不像完成。您需要手动删除数据库中新创建的表。

我们可以使用修补程序来执行此操作,如下所示:

L:\todos> php artisan tinker

Psy Shell v0.8.15 (PHP 7.1.10 — cli) by Justin Hileman

>>> Schema::drop('users')

=> null

我自己的用户表有问题。

之后,你很高兴

php artisan migrate:rollback

php artisan migrate

答案 13 :(得分:4)

1-转到 /config/database.php 并找到以下行

'mysql' => [
    ...,
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    ...,
    'engine' => null,
 ]

并将其更改为:

'mysql' => [
    ...,
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    ...,
    'engine' => 'InnoDB',
 ]

2-运行 php artisan config:cache 来重新配置laravel

3-删除数据库中的现有表,然后再次运行 php artisan migrate

答案 14 :(得分:3)

更新并将这些行插入app / Providers / AppServiceProvider.php

use Illuminate\Support\Facades\Schema;  //insert this line
public function boot()
{
    Schema::defaultStringLength(191); //insert this line also
}

App / Serviceprovider.php中的这些更改将为您提供帮助

答案 15 :(得分:3)

AppServiceProvider.php 文件中:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

答案 16 :(得分:3)

如迁移guide中所述,要解决此问题,您只需编辑app/Providers/AppServiceProvider.php文件并在引导方法内设置默认字符串长度:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

注意:首先,您必须从数据库中删除(如果有)用户表, password_resets 表,并从中删除用户和password_resets条目迁移表。

要运行所有未完成的迁移,请执行migrate Artisan命令:

php artisan migrate

之后一切都应该正常工作。

答案 17 :(得分:3)

如果要更改AppServiceProvider,则需要在迁移中定义电子邮件字段的长度。只需将第一行代码替换为第二行。

create_users_table

$table->string('email')->unique();
$table->string('email', 50)->unique();

create_password_resets_table

$table->string('email')->index();
$table->string('email', 50)->index();

成功更改后,您可以运行迁移 注意:首先,您必须从数据库中删除(如果有)用户表 password_resets表,并从迁移表中删除users和password_resets条目。

答案 18 :(得分:3)

默认情况下,

Schema::defaultStringLength(191);将定义所有字符串191的长度,这可能会破坏您的数据库。你不能这样走。

只需定义数据库迁移类中任何特定列的长度即可。例如,我定义了&#34; name&#34;,&#34; username&#34;和&#34;电子邮件&#34;在CreateUsersTable课程中,如下所示:

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 191);
            $table->string('username', 30)->unique();
            $table->string('email', 191)->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

答案 19 :(得分:2)

没有人知道的解决方案是,在 Mysql v5.5 和更高版本的 InnoDB 中,它没有默认问题,但是在很多情况下,例如我的是一些使用旧 MYISAM

的旧mysql ini配置文件
default-storage-engine=MYISAM

这将导致所有这些问题,而解决方案是一次将Mysql的 ini 配置文件中的default-storage-engine更改为 InnoDB ,而不是进行临时修改

default-storage-engine=InnoDB

如果您使用的是 MySql v5.5 或更高版本,则 InnoDB 是默认引擎,因此您无需像上面那样显式设置它,只需删除{{ 1}}(如果存在),那么您就可以参加了。

答案 20 :(得分:2)

如果尚未为数据库分配任何数据,请执行以下操作:

  1. 转到app / Providers / AppServiceProvide.php并添加
  

使用Illuminate \ Support \ ServiceProvider;

以及方法boot()内;

  

Schema :: defaultStringLength(191);

  1. 现在删除数据库中的记录,例如用户表。

  2. 运行以下

  

php artisan config:cache

     

php artisan迁移

答案 21 :(得分:2)

这很常见,因为Laravel 5.4将默认数据库字符集更改为utf8mb4。您需要做的是:通过将此代码放在类声明之前编辑您的App \ Providers.php

use Illuminate\Support\Facades\Schema;

另外,将其添加到'boot'功能 Schema::defaultStringLength(191);

答案 22 :(得分:2)

我刚刚修改了 users password_resets 迁移文件中的以下行。

旧的:$table->string('email')->unique();

新功能:$table->string('email', 128)->unique();

Voila !!

答案 23 :(得分:1)

推荐的解决方案是启用MySQL的innodb_large_prefix选项,这样您就不会陷入后续问题。这是这样做的方法:

打开my.ini MySQL配置文件,然后在[mysqld]行下面添加以下行。

[mysqld]
innodb_file_format = Barracuda
innodb_large_prefix = 1
innodb_file_per_table = ON

然后,保存更改并重新启动MySQL服务。

如果需要回滚,然后重新运行迁移。


以防万一您的问题仍然存在,请转到数据库配置文件并设置

'engine' => null,'engine' => 'innodb row_format=dynamic'

希望有帮助!

答案 24 :(得分:1)

对我来说很有魅力!

将此添加到 config/database.php

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

代替

'engine' => 'null',

答案 25 :(得分:1)

为了避免更改代码中的任何内容,只需将MySQL服务器更新为至少5.7.7

请参阅此以获取更多信息:https://laravel-news.com/laravel-5-4-key-too-long-error

答案 26 :(得分:1)

尝试使用默认字符串长度 125(对于 MySQL 8.0)。

defaultStringLength(125)

答案 27 :(得分:1)

我认为将StringLenght强制为191是一个非常糟糕的主意。 所以我调查了解发生了什么。

我注意到此消息错误:

  

SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥   太长了最大密钥长度为767字节

在我更新MySQL版本后开始显示。所以我用PHPMyAdmin检查了表格,我注意到所有创建的新表都是使用归类 utf8mb4_unicode_ci 而不是 utf8_unicode_ci 的旧表格。

在我的doctrine配置文件中,我注意到charset设置为utf8mb4,但我之前的所有表都是在utf8中创建的,所以我想这是一些更新魔法,它开始在utf8mb4上工作。

现在,简单的解决方法是更改​​ORM配置文件中的行字符集。 然后,如果您处于开发模式,则使用utf8mb4_unicode_ci删除表,或者如果您不能删除它们,请修复字符集。

对于Symfony 4

  

charset:utf8mb4 更改为 config / packages / doctrine.yaml

charset:utf8

现在我的学说迁移工作再次正常。

答案 28 :(得分:0)

如果在运行“ php artisan migration”时遇到此错误。您可以通过编写以下代码来更改要更新的表:

    DB::statement('ALTER TABLE table_name ROW_FORMAT = DYNAMIC;');        

在您的迁移脚本中。例子:

class MyMigration extends Migration {

/**
 * Run the migrations.
 */
public function up()
{
    DB::statement('ALTER TABLE table_name ROW_FORMAT = DYNAMIC;');        
    Schema::table('table_name', function ($table) {
        //....
    });
}

/**
 * Undo the migrations.
 */
public function down()
{
    //....
}
}

然后再次运行php artisan migrate

答案 29 :(得分:0)

我从GitHub解决了我的问题

Laravel Database Migration, Too long key issue

语法错误或访问冲突:1071指定的密钥太长了。

答案 30 :(得分:0)

需要使用以下命令创建数据库。

CREATE DATABASE database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

,然后运行以下命令来迁移数据库表。

php artisan migrate

答案 31 :(得分:0)

在/etc/mysql/mariadb.conf.d/50-server.cnf或您的配置所在的位置仅几行:

innodb-file-format=barracuda
innodb-file-per-table=ON
innodb-large-prefix=ON
innodb_default_row_format = 'DYNAMIC'

sudo service mysql restart

https://stackoverflow.com/a/57465235/778234

查看文档:{​​{3}}

答案 32 :(得分:0)

将我的本地数据库服务器类型从“ mariadb” 更改为“ mysql” 可以解决此问题,而无需编辑任何Laravel文件。

我按照本教程更改了数据库服务器类型:https://odan.github.io/2017/08/13/xampp-replacing-mariadb-with-mysql.html

答案 33 :(得分:0)

如要解决此问题的《迁移指南》所述,只需编辑AppServiceProvider.php文件,并在启动方法内设置默认字符串长度即可:

//edit your AppServiceProvider.php file contains in providers folder
use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

希望这会对您有所帮助。。。

答案 34 :(得分:0)

首先删除本地主机中数据库的所有表

将config / database.php文件中的Laravel默认数据库(utf8mb4)属性更改为:

'字符集'=>'utf8', 'collat​​ion'=>'utf8_unicode_ci',

然后 更改本地数据库属性utf8_unicode_ci。 PHP的工匠迁移 没关系。

答案 35 :(得分:0)

对于流明:

添加到.env文件

DB_ENGINE=InnoDB

答案 36 :(得分:0)

您可以按如下所示设置索引字段的字符串长度:

  $table->string('email', 200)->unique();

答案 37 :(得分:0)

即使我已经遇到了这个错误(实际上是因为我已经有了) 架构:: defaultStringLength(191);在我的AppServiceProvider.php文件中。

原因是因为我试图在一次迁移中将字符串值设置为大于191的值:

Schema::create('order_items', function (Blueprint $table) {
    $table->primary(['order_id', 'product_id', 'attributes']);
    $table->unsignedBigInteger('order_id');
    $table->unsignedBigInteger('product_id');
    $table->string('attributes', 1000); // This line right here
    $table->timestamps();
});

删除1000或将其设置为191解决了我的问题。

答案 38 :(得分:0)

在这里工作的方法是传递第二个参数,该参数的名称为键名(简称):

$table->string('my_field_name')->unique(null,'key_name');

答案 39 :(得分:0)

对于可能遇到此问题的其他任何人,我的问题是我正在创建一个string类型的列,并尝试将其设为->unsigned(),当我将其设为整数时。

答案 40 :(得分:-1)

对我来说,起作用的是通过运行来更新依赖项。

composer update

您还应该安装最新的mysql版本。