使用 php artisan make:auth
在 Laravel 5.4 上发生迁移错误
[Illuminate\Database\QueryException] SQLSTATE[42000]:语法错误或访问冲突:1071 指定的键太长;最大密钥长度为 767 字节(SQL:alter table e users add unique users_email_unique(email))[PDOException] SQLSTATE[42000]:语法错误或访问冲突:1071 指定的密钥太长;最大密钥长度为 767 字节
根据official Laravel 7.x documentation,您可以很容易地解决这个问题。
更新您的 /app/Providers/AppServiceProvider.php
以包含:
use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
或者,您可以为您的数据库启用 innodb_large_prefix 选项。有关如何正确启用此选项的说明,请参阅数据库的文档。
我不知道为什么上面的解决方案和正在添加的官方解决方案
Schema::defaultStringLength(191);
在 AppServiceProvider
中对我不起作用。有用的是编辑 config
文件夹中的 database.php
文件。只需编辑
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
至
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
它应该可以工作,尽管您将无法存储像表情符号这样的扩展多字节字符。
这是一个丑陋的黑客,如果你想用非英语语言存储字符串,请不要这样做,表情符号
我用 Laravel 5.7 做到了。希望能帮助到你。
不要忘记停止并再次启动服务器。
use Illuminate\Support\Facades\Schema;
。
utf8mb4
排序规则的存在是有原因的,如果可以的话,我建议使用它。
我只是在这里添加这个答案,因为它是我的 quickest
解决方案。只需将默认数据库引擎设置为 'InnoDB'
/config/database.php
'mysql' => [
...,
...,
'engine' => 'InnoDB',
]
然后运行 php artisan config:cache
以清除和刷新配置缓存
编辑:找到的答案 here 可能会解释这个问题的幕后情况
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
这个问题是在 Laravel 5.4 中由数据库版本引起的。
根据 docs(在 Index Lengths & MySQL / MariaDB
部分):
Laravel 默认使用 utf8mb4 字符集,其中包括支持在数据库中存储“表情符号”。如果您运行的 MySQL 版本早于 5.7.7 版本或 MariaDB 版本早于 10.2.2 版本,您可能需要手动配置迁移生成的默认字符串长度,以便 MySQL 为其创建索引。您可以通过在 AppServiceProvider 中调用 Schema::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 个字符。这比官方 RFC 规定的要少。
所以文档还提出了另一种解决方案:
或者,您可以为您的数据库启用 innodb_large_prefix 选项。有关如何正确启用此选项的说明,请参阅数据库的文档。
对于不想改变 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();
我已经解决了这个问题并编辑了我的 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,
],
我正在添加两个对我有用的 sollution。
打开 database.php 文件 insde 配置目录/文件夹。编辑 'engine' => null,到 'engine' => 'InnoDB',这对我有用。
第二个解决方案是:
打开 database.php 文件 insde 配置目录/文件夹。 2.Edit 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', to 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
祝你好运
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
我为这个错误找到了两种解决方案
选项1:
在数据库/迁移文件夹中打开您的用户和密码重置表
只需更改电子邮件的长度:
$table->string('email',191)->unique();
选项 2:
打开您的 app/Providers/AppServiceProvider.php
文件并在 boot()
方法中设置默认字符串长度:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
对我来说就像魅力一样!
将此添加到 config/database.php
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
代替
'engine' => 'null',
没有人告诉的解决方案是,在 Mysql v5.5 和更高版本中,InnoDB 是默认存储引擎,它没有这个问题,但在很多情况下,像我这样,有一些旧的 mysql ini 配置文件使用旧的 MISAM 存储引擎,如下所示。
default-storage-engine=MYISAM
这造成了所有这些问题,解决方案是一劳永逸地在 Mysql 的 ini 配置文件中将 default-storage-engine 更改为 InnoDB,而不是进行临时修改。
default-storage-engine=InnoDB
如果您使用的是 MySql v5.5 或更高版本,则 InnoDB 是默认引擎,因此您不需要像上面那样显式设置它,只需删除 default-storage-engine=MYISAM
if它存在于您的 ini
文件中,您可以开始了。
show global variables like 'innodb_large_prefix';
它应该是 ON。如果它是关闭,那么您可以查看this答案以了解如何打开它。 here 是关于 dev.mysql.com 上的 innodb_large_prefix 的更多信息。
我不会设置长度限制,而是提出以下建议,这对我有用。
里面:
配置/数据库.php
将此行替换为 mysql:
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
和:
'engine' => null,
在此处打开此文件:/app/Providers/AppServiceProvider.php
并将此代码更新为我的图像:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
https://i.stack.imgur.com/naeBO.jpg
如迁移 guide 中所述,要解决此问题,您只需编辑 app/Providers/AppServiceProvider.php
文件并在引导方法中设置默认字符串长度:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
注意:首先您必须从数据库中删除(如果有)用户表、密码重置表,并从迁移表中删除用户和密码重置条目。
要运行所有未完成的迁移,请执行 migrate
Artisan 命令:
php artisan migrate
之后,一切都应该正常工作。
如前所述,我们添加到 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
但这不是我发布的全部内容!问题是即使执行上述操作您也可能会遇到另一个错误(那是在您运行 php artisan migrate
命令时,因为长度的问题,操作很可能会卡在中间。解决办法在下面,用户表很可能是创建没有其余部分或不完全正确)我们需要回滚。默认回滚将不起作用。因为迁移的操作不喜欢完成。您需要手动删除数据库中新创建的表。
我们可以使用 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 migrate:rollback
php artisan migrate
如果要更改 AppServiceProvider,则需要在迁移中定义电子邮件字段的长度。只需将第一行代码替换为第二行。
创建用户表
$table->string('email')->unique();
$table->string('email', 50)->unique();
create_password_resets_table
$table->string('email')->index();
$table->string('email', 50)->index();
成功更改后,您可以运行迁移。注意:首先您必须从数据库中删除(如果有)用户表、密码重置表,并从迁移表中删除用户和密码重置条目。
Schema::defaultStringLength(191);
将默认定义所有字符串的长度 191,这可能会破坏您的数据库。你不能走这条路。
只需定义数据库迁移类中任何特定列的长度即可。例如,我在 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();
});
}
推荐的解决方案是启用 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'
希望能帮助到你!
我刚刚在 users
和 password_resets
迁移文件中修改了以下行。
旧:$table->string('email')->unique();
新:$table->string('email', 128)->unique();
为了避免更改代码中的任何内容,只需将 MySQL 服务器更新到至少 5.7.7
参考此以获得更多信息:https://laravel-news.com/laravel-5-4-key-too-long-error
这很常见,因为 Laravel 5.4 将默认数据库字符集更改为 utf8mb4。您需要做的是:编辑您的 App\Providers.php 通过将此代码放在类声明之前
use Illuminate\Support\Facades\Schema;
此外,将此添加到“启动”功能 Schema::defaultStringLength(191);
如果您还没有为数据库分配任何数据,请执行以下操作:
转到 app/Providers/AppServiceProvide.php 并添加
使用 Illuminate\Support\ServiceProvider;
在方法 boot() 内部;
架构::defaultStringLength(191);
现在删除数据库中的记录,例如用户表。运行以下
php artisan 配置:缓存 php artisan 迁移
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
已经存在。希望你改正
尝试使用默认字符串长度 125(对于 MySQL 8.0)。
defaultStringLength(125)
在 database.php 中
添加这一行:
'引擎' => 'InnoDB ROW_FORMAT=DYNAMIC',
https://i.stack.imgur.com/9GFCx.png
我认为将 StringLenght 强制为 191 是一个非常糟糕的主意。所以我调查以了解发生了什么。
我注意到此消息错误:
SQLSTATE[42000]:语法错误或访问冲突:1071 指定的键太长;最大密钥长度为 767 字节
在我更新我的 MySQL 版本后开始出现。所以我用 PHPMyAdmin 检查了表,我注意到创建的所有新表都使用排序规则 utf8mb4_unicode_ci 而不是旧表的 utf8_unicode_ci。
在我的学说配置文件中,我注意到 charset 设置为 utf8mb4,但我之前的所有表都是在 utf8 中创建的,所以我想这是一些更新魔法,它开始在 utf8mb4 上工作。
现在简单的解决方法是更改 ORM 配置文件中的行字符集。如果您处于开发模式,则使用 utf8mb4_unicode_ci 删除表,如果无法删除它们,请修复字符集。
对于 Symfony 4
在 config/packages/doctrine.yaml 中将 charset: utf8mb4 更改为 charset: utf8
现在我的学说迁移再次正常工作。
首先删除localhost中数据库的所有表
将文件 config/database.php 中的 Laravel 默认数据库(utf8mb4)属性更改为:
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
然后更改我的本地数据库属性 utf8_unicode_ci。 php artisan migrate 没问题。
对于可能遇到此问题的任何其他人,我的问题是我正在创建一个类型为 string
的列,并试图使其成为 ->unsigned()
,而我的意思是它是一个整数。
在这里工作的方法是传递带有键名的第二个参数(一个短的):
$table->string('my_field_name')->unique(null,'key_name');
即使我已经有了(实际上是因为我已经有了)Schema::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 解决了我的问题。
不定期副业成功案例分享