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

abs*_*ive 134 mysql pdo laravel laravel-5 laravel-5.4

Laravel 5.4上的迁移错误 php artisan make:auth

[Illuminate\Database\QueryException] SQLSTATE [42000]:语法错误或访问冲突:1071指定密钥太长; 最大密钥长度为767字节(SQL:alter tabl e usersadd unique users_email_unique(email))

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

abs*_*ive 210

根据官方文档,您可以很容易地解决这个问题.

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

use Illuminate\Database\Schema\Builder; // Import Builder where defaultStringLength method is defined

function boot()
{
    Builder::defaultStringLength(191); // Update defaultStringLength
}
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意此解决方案。例如,如果您为电子邮件字段编制索引,则存储的电子邮件最多只能有 191 个字符。这比官方 RFC 规定的要少。 (8认同)
  • 这是一个丑陋的黑客行为,它使您的代码无法适应错误/过时的数据库配置,并且它的呈现方式就好像它是一个实际的解决方案一样。 (3认同)
  • Laravel 建议的解决方案 https://github.com/laravel/framework/issues/17508 https://laracasts.com/discuss/channels/laravel/laravel-54-failing-on-php-artisan-migrate-after- php-artisan-makeauth (2认同)
  • 为什么只有191个字符@absiddiqueLive (2认同)
  • 工作在5.7.0.但为什么191? (2认同)

Kou*_*Das 93

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

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

AppServiceProvider没有为我工作.有用的是编辑database.php文件config夹中的文件.只需编辑

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

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

它应该工作.希望能帮助到你.

  • 我认为您错过了顶部的“使用Illuminate \ Support \ Facades \ Schema;”这一部分。 (4认同)
  • `utf8mb4` 排序规则的存在是有原因的,如果可以的话我建议使用它。 (4认同)
  • 使用此字符集将只允许您保存标准ASCII,而不能保存多字节特殊字符,例如阿拉伯,希伯来语,大多数欧洲脚本中的字符,当然还有表情符号。另请参阅/sf/answers/1058967241/ (2认同)

Dex*_*gil 64

我只是在这里添加这个答案,因为它是quickest我的解决方案.只需将默认数据库引擎设置为'InnoDB'on即可

/config/database.php

'mysql' => [
    ...,
    ...,
    'engine' => 'InnoDB',
 ]
Run Code Online (Sandbox Code Playgroud)

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

  • 这是实际的解决方案,其他是解决方法 (6认同)
  • 我在 Laravel 8 项目上使用了这个解决方案,效果非常好,谢谢! (6认同)
  • 但这背后的逻辑是什么 (5认同)
  • 这应该被标记为最佳解决方案 (4认同)
  • 完美的解决方案。更好地提供一些文档以供将来解释 (4认同)
  • 这是正确的解决方案。但为什么不将其包含在默认安装中呢? (3认同)
  • 很好,谢谢。也可以使用 Laravel 9 (3认同)
  • 将引擎从null更改为InnoDB的工作 (2认同)
  • 我可以确认它在 Laravel 8 全新的 laravel 安装中有效 (2认同)
  • 快速更新:我写了“InnoDB ROW_FORMAT=DYNAMIC”,而不是“InnoDB”,正如下面其他评论中提到的,它起作用了。但是我不知道这意味着什么以及它如何影响 Laravel 应用程序。如果有人知道,我真的很感激。 (2认同)

小智 34

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

use Illuminate\Support\Facades\Schema;

public function boot()
{
Schema::defaultStringLength(191);
}
Run Code Online (Sandbox Code Playgroud)

并在boot方法中添加此代码.

use Illuminate\Support\Facades\Schema;

public function boot()
{
Schema::defaultStringLength(191);
}
Run Code Online (Sandbox Code Playgroud)


Est*_*era 21

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

根据文档(在本Index Lengths & MySQL / MariaDB节中):

Laravel utf8mb4默认使用字符集,其中包括支持在数据库中存储"emojis".如果您运行的是早于5.7.7版本的MySQL版本或早于10.2.2版本的MariaDB,您可能需要手动配置迁移生成的默认字符串长度,以便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);
}

// ...

}
Run Code Online (Sandbox Code Playgroud)

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

小心这个解决方案.例如,如果您对电子邮件字段编制索引,则存储的电子邮件最多只能包含191个字符.这比官方的RFC状态要少.

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

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


小智 21

对我来说就像魅力一样!

将其添加到 config/database.php

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
Run Code Online (Sandbox Code Playgroud)

代替

'engine' => 'null',
Run Code Online (Sandbox Code Playgroud)


per*_*st1 19

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

选项1:

php artisan db:wipe 
Run Code Online (Sandbox Code Playgroud)

更新这些值的(下)的MySQL阵列/config/database.php

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

进而

php artisan migrate
Run Code Online (Sandbox Code Playgroud)

完成! 迁移表将被成功创建。


选项 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); 
}
Run Code Online (Sandbox Code Playgroud)

进而

php artisan migrate
Run Code Online (Sandbox Code Playgroud)

完成!

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

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


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

php artisan config:cache php artisan migrate:fresh

php artisan migrate:reset


小智 15

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

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

create_users_table.php

$table->string('name',64);
$table->string('email',128)->unique();
Run Code Online (Sandbox Code Playgroud)

create_password_resets_table.php

$table->string('email',128)->index();
Run Code Online (Sandbox Code Playgroud)


小智 12

在此处打开此文件:/app/Providers/AppServiceProvider.php

并将此代码更新为我的图像:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


小智 11

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

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

请检查这张图片。然后php artisan migrate再次运行命令。


Ars*_*mad 9

我要添加两种对我有用的解决方案。

第一种解决方案是

  1. 打开insde config dir / folder中的database.php文件。
  2. 编辑'engine' => null,'engine' => 'InnoDB',

    这对我有用。

第二种解决方案是:

  1. 打开insde config dir / folder中的database.php文件。 2. 编辑

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

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


祝好运


Anj*_*wal 9

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

use Illuminate\Support\Facades\Schema;  // add this line at top of file

public function boot()
{
    Schema::defaultStringLength(191); // add this line in boot method
}
Run Code Online (Sandbox Code Playgroud)


小智 9

在 Laravel 9 中

首先将默认数据库引擎设置为InnoDBon

/config/database.php

'engine' => 'InnoDB',
Run Code Online (Sandbox Code Playgroud)

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

php artisan db:wipe

'charset' => 'utf8', 'collation' => 'utf8_general_ci', 如下更改 /config/database.php 中 mysql 数组的这些值然后

php artisan migrate 就这样!迁移表将成功创建。


Udh*_*iya 7

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

$table->string('email',191)->unique();
Run Code Online (Sandbox Code Playgroud)

首先你必须从数据库中删除(如果有)users表, password_resets表,并从迁移表中删除用户和password_resets条目,然后删除旧表后运行boot()命令


小智 7

我已经解决了这个问题,并将我的config-> database.php文件编辑为我的数据库('charset'=>'utf8')('collat​​ion'=>'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,
    ],
Run Code Online (Sandbox Code Playgroud)

  • 请注意,并非所有 Unicode 字符都受 utf8 支持。 (3认同)

Ali*_*lon 7

没有人告诉的解决方案是,在Mysql v5.5和更高版本的InnoDB 中是默认的存储引擎,它没有这个问题,但在许多情况下,像我这样的,有一些旧的 mysql ini 配置文件使用旧的MYISAM存储引擎,如下所示。

default-storage-engine=MYISAM
Run Code Online (Sandbox Code Playgroud)

这造成了所有这些问题,解决方案是在 Mysql 的ini配置文件中一劳永逸地将 default-storage-engine 更改为InnoDB,而不是进行临时黑客攻击。

default-storage-engine=InnoDB
Run Code Online (Sandbox Code Playgroud)

如果您使用的是MySql v5.5或更高版本,那么InnoDB是默认引擎,因此您不需要像上面那样显式设置它,只需default-storage-engine=MYISAMini文件中删除它是否存在就可以了。


moh*_*ari 6

1-转到/config/database.php并找到这些行

'mysql' => [
    ...,
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    ...,
    'engine' => null,
 ]
Run Code Online (Sandbox Code Playgroud)

并将它们更改为:

'mysql' => [
    ...,
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    ...,
    'engine' => 'InnoDB',
 ]
Run Code Online (Sandbox Code Playgroud)

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

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


小智 6

在数据库.php中

-添加这一行:

'引擎' => 'InnoDB ROW_FORMAT=DYNAMIC',

在此输入图像描述


小智 5

我没有设定长度限制,而是提出以下建议,这对我有用.

配置/ database.php中

将此行替换为mysql

'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
Run Code Online (Sandbox Code Playgroud)

'engine' => null,
Run Code Online (Sandbox Code Playgroud)


Udd*_*wal 5

AppServiceProvider.php文件中:

 use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}
Run Code Online (Sandbox Code Playgroud)