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

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

[Illuminate\Database\QueryException] SQLSTATE[42000]:语法错误或访问违规:1071指定的键太长;最大密钥长度是767字节(SQL: alter table e users添加唯一的users_email_unique(email))

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

372582 次浏览

根据Laravel 7。x文档,你可以很容易地解决这个问题。

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

use Illuminate\Support\Facades\Schema;


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

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

Laravel 5.4由数据库版本导致。

根据文档(在Index Lengths & MySQL / MariaDB部分):

Laravel默认使用utf8mb4字符集,其中包括 支持在数据库中存储“表情包”。如果你正在运行一个 MySQL版本高于5.7.7或MariaDB版本高于5.7.7 对于10.2.2版本,您可能需要手动配置默认值 由迁移生成的字符串长度,以便MySQL创建 它们的索引。方法进行配置 在你的AppServiceProviderSchema::defaultStringLength方法

换句话说,在<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个字符。这个更少

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

或者,你可以为你的 数据库。有关的说明,请参阅数据库的文档

对于不想改变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();

如果您想在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_reset条目

与其设置长度限制,我建议以下方法,这对我来说很有效。

内部:

配置/ database.php

将这一行替换为mysql:

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

:

'engine' => null,

我不知道为什么上面的解和官方的解是相加的

Schema::defaultStringLength(191);

AppServiceProvider中的>对我不起作用。 有效的方法是编辑config文件夹中的database.php文件。 只是编辑< / p >

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

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

并且它应该工作,虽然您将无法存储扩展的多字节字符,如emoji

这是一个丑陋的黑客,如果你想存储字符串在非英语语言,表情符号

我用Laravel 5.7做的。希望能有所帮助。

不要忘记停止并再次启动服务器。

我只是在这里添加了这个答案,因为它是我的< >强quickest < / >强解决方案。只需要将默认的数据库引擎设置为'InnoDB' on

< >强/config/database.php < / >强

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

然后运行< >强php artisan config:cache < / >强来清除和刷新配置缓存

< p >编辑: 找到< a href = " https://stackoverflow.com/questions/1814532/1071 -指定的关键- - - - - - -太长- max -关键- -是- 767字节长度" > < / >在这里的答案可能解释了这个

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

更多信息请参考:https://laravel-news.com/laravel-5-4-key-too-long-error

如前所述,我们在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
}

你可以在下面的链接中看到更多细节(搜索“索引长度&MySQL / MariaDB”) https://laravel.com/docs/5.5/migrations < / p >

但这并不是我发表文章的全部内容!事情是即使在做上面的您可能会得到另一个错误(当你运行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

正如Migrations 指南中所概述的那样,你所要做的就是编辑你的app/Providers/AppServiceProvider.php文件,并在引导方法中设置默认字符串长度:

use Illuminate\Support\Facades\Schema;


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

注意:首先你必须从数据库中删除(如果你有)users table, password_resets table,并从migrations table中删除users和password_resets entries。

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

php artisan migrate

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

对于这个错误,我找到了两个解决方案

选项1:

打开数据库/迁移文件夹中的用户password_reset

只需要改变邮件的长度:

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

选项2:

打开你的< em > app/Providers/AppServiceProvider.php < / em >文件,在< em > boot() < / em >方法中设置一个默认字符串长度:

use Illuminate\Support\Facades\Schema;


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

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

use Illuminate\Support\Facades\Schema;
另外,将此添加到'boot'函数中 Schema::defaultStringLength(191); < / p >

我已经解决了这个问题,并编辑了我的config->database.php文件,以喜欢我的数据库('charset'=>'utf8')('collation'=>'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,
],

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

只需在数据库迁移类中定义任何特定列的长度。例如,我在CreateUsersTable类中定义了"name"、"username"和"email",如下所示:

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();
});
}

对于其他可能遇到这种情况的人来说,我的问题是我正在创建类型为string的列,并试图使其为->unsigned(),而我的意思是它是一个整数。

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

我注意到这个消息错误:

SQLSTATE[42000]:语法错误或访问违规:1071指定的密钥 太长了;最大密钥长度是767字节

在我更新MySQL版本后开始出现。所以我用PHPMyAdmin检查了表,我注意到所有新创建的表都是用utf8mb4_unicode_ci而不是旧的utf8_unicode_ci排序。

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

现在最简单的解决方法是改变ORM配置文件中的行字符集。 如果你在dev模式下,使用utf8mb4_unicode_ci删除表,如果你不能删除它们,则修复字符集

Symfony 4

配置/包/ doctrine.yaml中将字符集:utf8mb4改为字符集:utf8

现在我的理论迁移又开始起作用了。

我添加了两个sollution,为我工作。

< a href = " https://youtu。be/ dsulkxdlju " rel="noreferrer">第一个解是:

  1. 打开配置目录/文件夹中的database.php文件。
  2. 编辑'engine' => null,'engine' => 'InnoDB',

第二个解决方案是:

  1. 打开配置目录/文件夹中的database.php文件 2.编辑
    'charset' =>“utf8mb4”, “排序”=比;‘utf8mb4_unicode_ci’,> < /代码
    < br > < / p > < p > <代码>“字符集”=比;“use utf8”, “排序”=比;“utf8_unicode_ci”,< /代码> < / p > < /李>

< p > < br > 古德勒克< / >强

这里的方法是传递一个带有键名的第二个参数(一个短参数):

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

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

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

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

推荐的解决方案是启用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'

希望能有所帮助!

1 -< em > /config/database.php < / em >找到这些行

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

并更改为:

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

2 -执行< em > php artisan config:cache < / em >重新配置laravel

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

如果你没有任何数据已经分配到你的数据库执行以下操作:

  1. 进入app/Providers/ appserviceprovider .php并添加

使用说明\ \ ServiceProvider的支持;

在方法boot()内部;

模式:defaultStringLength (191);

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

  2. 执行以下命令

PHP工匠配置:缓存

PHP工匠迁移

我得到这个错误,即使我已经有(实际上因为我已经有) 模式:defaultStringLength (191);

.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解决了我的问题。

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

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

你可以这样设置索引字段的字符串长度:

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

腔:

添加到.env文件

DB_ENGINE=InnoDB

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

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

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

. < p >之后 更改我的本地数据库属性utf8_unicode_ci。 PHP工匠迁移

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

default-storage-engine=MYISAM

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

default-storage-engine=InnoDB

如果你在MySql v5.5或更高版本,那么InnoDB是默认引擎,所以你不需要像上面那样显式地设置它,只要从你的ini文件中删除default-storage-engine=MYISAM(如果它存在),你就可以开始了。

只要在/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 < a href = " https://stackoverflow.com/a/57465235/778234 " > < / >

参见文档:https://dev.mysql.com/doc/refman/5.6/en/innodb-row-format.html

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

CREATE DATABASE database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

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

php artisan migrate

如果您在运行“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

简单的解决方案

选项1:

php artisan db:wipe

更新/ config / database.phpmysql数组的这些值(如下)

< >强'charset' => 'utf8', 'collation' => 'utf8_general_ci', < / >强

然后

php artisan migrate

将创建这是完成了!迁移表。


选项2:

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

更新你的AppServiceProvider.php 位于app /供应商/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个字符。这个更少


我尝试了这些可能的方法(如下面)。

php artisan config:cache php artisan migrate:fresh

php artisan migrate:reset

对我来说很有魅力!

将此添加到config/database.php

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

而不是

'engine' => 'null',

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

defaultStringLength(125)

最干净的解决方案是去你的数据库并更改:

default_storage_engine to InnoDB

你很可能有MyISAM。

打开这个文件:/app/Providers/AppServiceProvider.php

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

use Illuminate\Support\Facades\Schema;


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

enter image description here

在database.php

-添加这一行:

“引擎”=比;“InnoDB ROW_FORMAT =动态',

enter image description here

在laravel

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

/config/database.php

'engine' => 'InnoDB',

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

php artisan db:wipe

修改/config/database.php中mysql数组的这些值,如下所示 'charset' => 'utf8', 'collation' => 'utf8_general_ci', < / p > < p > php artisan migrate 这是所有!

.迁移表创建成功