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

Mysql Laravel迁移错误:语法错误或访问冲突:1071指定的密钥太长;最大密钥长度为767字节,mysql,laravel,pdo,laravel-5,laravel-5.4,Mysql,Laravel,Pdo,Laravel 5,Laravel 5.4,使用php artisan make:auth在Laravel 5.4上发生迁移错误 $table->string('name',64); $table->string('email',128)->unique(); $table->string('email',128)->index(); [Illumb\Database\QueryException]SQLSTATE[42000]:语法错误或访问冲突:1071指定的密钥太长;最大密钥长度为767字节(SQL

使用php artisan make:auth在Laravel 5.4上发生迁移错误

$table->string('name',64);
$table->string('email',128)->unique();
$table->string('email',128)->index();
[Illumb\Database\QueryException]SQLSTATE[42000]:语法错误或访问冲突:1071指定的密钥太长;最大密钥长度为767字节(SQL:alter table e
users
addunique
users\u email\u unique
email

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

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

更新您的
/app/Providers/AppServiceProvider.php
以包含:

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}
或者,您可以为数据库启用
innodb\u large\u prefix
选项。有关如何正确启用此选项的说明,请参阅数据库文档


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

根据(在
索引长度&MySQL/MariaDB
部分):

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

换句话说,在
/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\u large\u prefix
选项 数据库请参阅数据库文档,以了解有关的说明 如何正确启用此选项


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

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

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();
        });
    }
创建用户表.php

$table->string('name',64);
$table->string('email',128)->unique();
$table->string('email',128)->index();
create\u password\u resets\u table.php

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

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

创建用户表

$table->string('email')->unique();
$table->string('email', 50)->unique();
创建\u密码\u重置\u表

$table->string('email')->index();
$table->string('email', 50)->index();
成功更改后,您可以运行迁移。

注意:首先,您必须从数据库中删除(如果有)用户表密码重置表,并从迁移表中删除用户和密码重置项。

我建议以下内容,而不是设置长度限制,这对我很有效

内部:

config/database.php

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
替换mysql的此行:

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


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

Schema::defaultStringLength(191);
AppServiceProvider中
对我不起作用。 工作原理是编辑
config
文件夹中的
database.php
文件。 编辑

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

它应该可以工作,尽管您将无法存储像表情符号这样的扩展多字节字符

这是一个丑陋的破解,如果您想用非英语语言存储字符串,请不要使用表情符号


我用拉威尔5.7做到了。希望有帮助。

我只是在这里添加这个答案,因为它是我最快的解决方案。只需在上将默认数据库引擎设置为“InnoDB”

/config/database.php

$table->string('name',64);
$table->string('email',128)->unique();
$table->string('email',128)->index();
然后运行php-artisan-config:cache来清除和刷新配置缓存

编辑:
找到的答案可能会解释这一问题的幕后原因

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


有关更多信息,请参考此链接:

如已指定,我们将添加到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
}
您可以在下面的链接中看到更多详细信息(搜索“Index length&MySQL/MariaDB”)

但这不是我出版的全部内容即使在执行上述操作时,也可能会出现另一个错误(当您运行<代码> PHP工匠迁移命令时,由于长度的问题,操作可能会卡在中间。<强>解决方案低于,并且用户表可能在没有剩余或完全不正确的情况下创建)。 我们需要回滚。默认回滚将不起作用。因为迁移操作不喜欢完成。您需要手动删除数据库中新创建的表

我们可以使用tinker完成,如下所示:

L:\todos> php artisan tinker

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

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

=> null
php artisan db:wipe 
我自己对用户表有问题

之后你就可以走了

php artisan迁移:回滚


php artisan migrate

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

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}
注意:首先必须删除(如果有)使用
$table->string('my_field_name')->unique(null,'key_name');
[mysqld]
innodb_file_format = Barracuda
innodb_large_prefix = 1
innodb_file_per_table = ON
'mysql' => [
    ...,
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    ...,
    'engine' => null,
 ]
'mysql' => [
    ...,
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    ...,
    'engine' => 'InnoDB',
 ]
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();
});
  $table->string('email', 200)->unique();
DB_ENGINE=InnoDB
default-storage-engine=MYISAM
default-storage-engine=InnoDB
php artisan db:wipe 
php artisan migrate
use Illuminate\Support\Facades\Schema;
/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191); 
}
php artisan migrate
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
'engine' => 'null',