Laravel 迁移: 即使指定了惟一键,也太长了

我正在尝试迁移 Laravel 的用户表,当我运行迁移时,我得到了这个错误:

[ Illumination Database QueryException ] SQLSTATE [42000] : 语法错误 指定的密钥太长; 最大密钥长度 是767字节(SQL: alter table users add only Users _ email _ uniq (email))

我的迁移如下:

Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name', 32);
$table->string('username', 32);
$table->string('email', 320);
$table->string('password', 64);
$table->string('role', 32);
$table->string('confirmation_code');
$table->boolean('confirmed')->default(true);
$table->timestamps();


$table->unique('email', 'users_email_uniq');
});

经过一些谷歌我遇到了 这个漏洞报告,在那里泰勒说,你可以指定的第二个参数的 unique()的索引键,我已经这样做了。还是会出错。这是怎么回事?

267866 次浏览

指定较小的电子邮件长度:

$table->string('email', 250);

实际上,这是默认值:

$table->string('email');

你应该没问题的。

对于 Laravel 5.4,你可以在这篇 Laravel 5.4: 指定键错误太长,Laravel 新闻文章中找到一个解决方案:

正如《迁移指南》中提到的,要解决这个问题,只需编辑 AppServiceProvider.php 文件,并在启动方法中设置默认字符串长度:

use Illuminate\Database\Schema\Builder;




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

如果其他人像我一样偶然发现了这个答案,但是由于不同的原因,你可以检查你的 Laravel 数据库字符集/排序。

我正在安装一个应用程序(Snipe-IT) ,并将 Laravel 数据库配置配置为使用以下内容:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',

从两个字符串中删除 mb4固定的问题,虽然我相信安东尼奥的答案是真正的解决问题。

更新1

Laravel 5.4开始,这些变化就不再需要了。

Laravel 5.4默认使用 utf8mb4字符集,包括支持在数据库中存储“ emoji”。如果要从 Laravel 5.3升级应用程序,则不需要切换到这个字符集。

更新2

当前生产 MariaDB 版本 不要默认情况下全局支持此设置。

解决方案

如果您有意使用正确的 future-default (从 Laravel 5.4开始) UTF8多字节 utf8mb4支持,那么可以开始修复数据库配置。

在 Laravel config/database.php中定义:

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',

DYNAMIC允许存储 长钥匙索引。

服务器设置(默认包含在 MySQL 5.7.7 +/MariaDB 10.2.2 + 中) :

[mysqld]
# default character set and collation
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4


# utf8mb4 long key index
innodb_large_prefix = 1
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = 1

客户:

[mysql]
default-character-set=utf8mb4

然后 别说了你的 MySQL/MariaDB 服务器。在这之后开始。热重启可能不工作。

sudo systemctl stop mysqld
sudo systemctl start mysqld

现在您有了支持 UTF8的 Laravel 5.x。

如果您使用的是 MySQL 5.7.7 + 或 MariaDB 10.2.2 + ,则不会出现这个问题。

要使用 Brew 在 Mac 上更新 MariaDB,首先要断开当前的链接: 然后使用 brew install mariadb --devel安装一个 dev one

安装完成后,停止/启动服务运行: 啤酒服务站 Mariadb 啤酒服务开始 Mariadb

当前的开发版本是10.2.3。安装完成后,你就不用再担心这个问题了,你可以使用 utf8mb4(现在在 Laravel 5.4中是默认的) ,而不用切换回 utf8,也不用像 Laravel 文档中建议的那样编辑 AppServiceProvider: https://laravel.com/docs/master/releases#laravel-5.4(向下滚动到: 迁移默认字符串长度)

这对我很有效:

 $table->charset = 'utf8';
$table->collation = 'utf8_unicode_ci';

如果你在或更新到 Laravel 5.4,这对我很有用;

在 AppServiceProvider.php 中只有1个更改

use Illuminate\Support\Facades\Schema;


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

如迁移指南 https://laravel.com/docs/master/migrations#creating-indexes所述

对于 laravel 5.4,只需编辑文件

应用程序提供商 AppServiceProvider.php

use Illuminate\Support\Facades\Schema;


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

从 charset 中删除 mb4并从 config/database. php 中排序,然后它将成功执行。
‘ charset’= > ‘ utf8’,
‘ colation’= > ‘ utf8 _ unicode _ ci’,

我也有同样的问题,而且我用的是 Wamp

解决方案: 打开文件: Config/database. php

'engine' => null, => 'engine' => 'InnoDB',

谢谢

刚刚安装了 MariaDB 10.2.4 RC,启动了新的空白 Laravel 5.4项目和默认迁移(varchar (255)列)。

不需要更改 DB conf 和 Laravael config/database.php

我也遇到过同样的问题,通过在 app/database. php 中添加以下两行来解决这个问题

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

我的文件如下:

<?php


return [


/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/


'default' => env('DB_CONNECTION', 'mysql'),


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


......

我添加了迁移本身

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

是的,我知道我需要在每次迁移时都考虑它,但我宁愿这样,也不愿把它藏在某个完全不相关的服务提供商里

将字符集从‘ utf8mb4’更改为‘ utf8’,然后

校对到‘ utf8mb4 _ unicode _ ci’到‘ utf8 _ unicode _ ci’

在 config/database. php 文件中

这招对我很管用。

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

use Illuminate\Support\Facades\Schema;


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

你可以退房了

Https://laravel-news.com/laravel-5-4-key-too-long-error Https://laravel.com/docs/5.5/migrations#indexes

在顶部包括这一行

use Illuminate\Support\Facades\Schema;

然后内部启动函数添加这个

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

这是因为 Laravel 5.4使用支持存储表情符号的 Utf8mb4

把这个加到你的 应用程序提供商

use Illuminate\Support\Facades\Schema;


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

你应该可以出发了。

在 config/database. php 文件中,其中:

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

把这一行改为:

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

如果你正在使用 Laravel5.4或者升级到了 Laravel5.4和最新版本,它就可以工作了;
在 AppServiceProvider.php 中只做了一个更改

use Illuminate\Support\Facades\Schema;


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

其他的回答都很好地描述了这一切 你可以在下面的链接中看到更多的细节(使用“ Index Lengths & MySQL/MariaDB”键进行搜索) Https://laravel.com/docs/5.5/migrations

但是这个答案不是关于这个的! 即使做上面的 你会喜欢得到另一个错误(这是你喜欢启动 php artisan migrate命令的时候,由于长度的问题,操作像卡在中间。解决方案是波纹管,用户表就像是没有创建其他表或者不完全正确) 我们需要回滚(rollbac) k. 默认的回滚不起作用。因为迁移的操作不喜欢结束。您需要手动删除数据库中新创建的表。

我们可以使用下面的修补工具:

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

设置数据库引擎 InnoDB:

  Schema::create('users', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});

我想指出我遗漏的一点。

我是 Laravel 的新人,我没有抄袭“ use Illumination... ...”,因为我真的没有注意到,因为在函数启动的正上方,你已经有了一个 ABc0语句。

希望这对大家有帮助

**use Illuminate\Support\Facades\Schema;**


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

对于 幼虫 > = 5.6用户

打开 AppServiceProvider.php文件

使用以下类

use Illuminate\Support\Facades\Schema;

然后在 boot方法中添加以下行

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

对于幼虫5.6
这个解决方案解决了我的问题
转到 config/database.php
找到下面的代码

'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' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],

改变这两个字段

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

用这个

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

如果您已经尝试了所有其他的方法,但都没有效果,那么您可以从数据库中删除所有表,然后使用以下命令一次性执行侯选命令:

php artisan migrate:fresh
File: config/database.php
change the following
FROM ->
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',


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

如果您看到这个错误,那么您肯定需要在 AppServiceProvider.php文件-> ,可以在 app->providers:中找到

要做的改变

use Illuminate\Support\Facades\Schema; //see if you have this class if not add it.


public function boot()
{
Schema::defaultStringLength(191); //make sure you add this line
}

这应该可以解决你的问题,你可以看到更多关于这个问题的 Laravel 新闻。 Https://laravel-news.com/laravel-5-4-key-too-long-error

我遇到了一个问题,修改了“ config/database”的配置

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

在数据库中保持相同的模式。

然后我下了命令

php artisan migrate

请打开 userpassword休息文件。文件位于数据库/迁移文件夹。

加线

Schema::defaultStringLength(191); in up function in both files.

那就快跑

php artisan migrate

2016年10月24日,《 Laravel 》的作者在 Twitter 上宣布

“ utf8mb4”将是 Laravel 5.4中默认的 MySQL 字符集,以获得更好的表情符号支持

在版本5.4之前,字符集是 utf8

在本世纪,许多网络应用程序,包括聊天或某种平台,允许他们的用户交谈,许多人喜欢使用表情符号或笑脸。这是一些超级字符,需要更多的空间存储,这是唯一可能的使用 utf8mb4作为 Charset。这就是为什么他们迁移到 utf8mb4只是为了空间的目的。

如果您在 Illuminate\Database\Schema\Builder类中查找,您将看到 $defaultStringLength被设置为 255,为了修改,您可以通过 Schema Facade 进行处理,并调用 defaultStringLength方法并传递新的长度。

在应用程序提供程序子目录下的 AppServiceProvider类中执行更改调用该方法,如下所示

class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// all other code ...


Schema::defaultStringLength(191);
}
// and all other code goes here
}

我建议使用 191作为值,因为 MySQL 支持767字节,而且因为 767 / 4是每个多字节字符所占用的字节数,所以您将得到 191

你可以在这里学到更多 Utf8mb4字符集(4字节 UTF-8 Unicode 编码) 表列计数和行大小的限制

如果有人有这个问题,甚至在做了,上面提到的变化。例如,在我的例子中,我做了以下更改,

namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;


class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}


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

但它不会马上工作的原因有两个。一种是,如果您使用的是 lumen 而不是 laravel,那么您可能必须首先在 app.php 文件中取消注释这一行。

$app->register(App\Providers\AppServiceProvider::class);

然后您必须使用 Artian 命令再次创建迁移脚本,

php artisan make:migration <your_table_name>

因为现在只有您对 ServiceProvider 所做的更改才能正常工作。

对于 laravel 5.7,请在 appserviceProver.php 中编写以下代码

  use Illuminate\Support\Facades\Schema;


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

解决方案:

首先在 应用程序提供商中将默认的 StringLlength 更改为191:

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

然后,在 Config database. php中修改 字符集和校对值如下:

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

(链接了解 MariaDB 字符集)

给你的电子邮件字符串一个更小的长度,如:

$table->string('email',128)->unique(); //In create user table

和 < br/>

$table->string('email',128)->index(); // create password resets table

这绝对会成功的。

指定较小的电子邮件长度:

$table->string('email', 100);

100件作品

请记住,这些文章都是简单而错误的解决方案。这就像因为袜子不合脚而砍掉你的一部分脚。

正确的答案(买一只新袜子)有点复杂,因为它要求你再去一次商店。在这种情况下,它需要您配置 mysql 实例,而这并不像错误答案那样具有拷贝/可粘贴性,所以我们一直在传播错误答案。我们希望看起来复制/粘贴和易于使用,对不对?

您忘记指定正在使用的 Laravel 或 mysql 版本。出现这个问题是因为您正在使用一个较旧的 mysql (或者使用设置错误的较新的 mysql)。

Set innodb_file_format=Barracuda
Set innodb_large_prefix=1
Set innodb_default_row_format=dynamic

如果没有 Innovdb _ default _ row _ format 设置(在5.7.9中引入) ,那么必须将 config/database. php 更改为使用‘ engine’= > ‘ injdb row _ format = Dynamic’。

发动机设置是在 Laravel 5.2.14中引入的,所以我希望你有更新的东西。

Https://github.com/laravel/framework/issues/22660#issuecomment-355725923

在某些情况下,它可以帮助,如果你同意唯一的只有 第一批191个

public function up()
{
DB::statement('ALTER TABLE `YOUR_TABLE_NAME`    ADD UNIQUE INDEX `NAME_FOR_INDEX` (`YOUR_COLUMN_NAME` (191) );');
}

转到 config/database.php,将字符集和排序从 utf8mb4改为 utf8

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

用这个方法解决了我的问题,祝你好运!

您可以转到 app/Providers/AppServiceProvider.php并导入这个

use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;

也在启动函数中添加这个

Schema::defaultStringLength(191);

由于 Laravel only ()函数的工作方式,同样的错误会弹出。

您唯一需要做的事情是指定一个更短的索引名称 eg. 。

$table->unique(['email', 'users_email_uniq'],'my_custom_uniq');

编辑 config 文件夹中的 database.php文件

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

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

它应该起作用! ! !