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

时间:2014-05-21 14:35:38

标签: php mysql laravel

我正在尝试在Laravel中迁移用户表。当我运行迁移时出现此错误:

  

[Illuminate \ Database \ QueryException] SQLSTATE [42000]:语法错误   或访问冲突:1071指定密钥太长;最大密钥长度   是767字节(SQL:alter table users添加唯一   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');
});

经过一些谷歌搜索后,我遇到了this bug report,泰勒说你可以将索引键指定为unique()的第二个参数,我已经完成了。它仍然给出了错误。这是怎么回事?

39 个答案:

答案 0 :(得分:242)

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

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

这是默认值,实际上是:

$table->string('email');

你应该做得好。

对于Laravel 5.4,您可以在此Laravel 5.4: Specified key was too long error, Laravel News帖子中找到解决方案:

正如迁移指南中所述,为了解决这个问题,您只需编辑AppServiceProvider.php文件并在boot方法中设置默认字符串长度:

use Illuminate\Support\Facades\Schema;

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

答案 1 :(得分:98)

更新1

Laravel 5.4开始,不再需要这些更改。

  

Laravel 5.4默认使用utf8mb4字符集,其中包括支持存储" emojis"在数据库中。如果要从Laravel 5.3升级应用程序,则无需切换到此字符集。

更新2

当前生产的MariaDB版本不要默认全局支持此设置。它在MariaDB 10.2.2+ by default中实现。

<强>解决方案

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

在Laravel config/database.php中定义:

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

DYNAMIC允许存储long key个索引。

服务器设置(默认包含在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.

答案 2 :(得分:42)

如果您正在使用或更新Laravel 5.4这对我有用;

只需1次更改。在AppServiceProvider.php中

use Illuminate\Support\Facades\Schema;

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

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

中所述

答案 3 :(得分:32)

如果有其他人像我一样偶然发现了这个答案,但出于不同的原因,你可以查看你的Laravel DB字符集/校对。

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

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

从这两个字符串中删除mb4解决了这个问题,但我相信安东尼的回答是问题的真正解决方案。

答案 4 :(得分:19)

这对我有用:

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

答案 5 :(得分:13)

从charset中删除mb4并从config / database.php中删除排序,然后它将成功执行 'charset'=&gt; 'UTF-8',
'collat​​ion'=&gt; 'utf8_unicode_ci',

答案 6 :(得分:12)

对于laravel 5.4,只需编辑文件

  

应用\提供商\ AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

答案 7 :(得分:11)

对于laravel 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'

答案 8 :(得分:10)

我遇到了同样的问题,并通过在我的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',

    ......

答案 9 :(得分:6)

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

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

答案 10 :(得分:5)

在文件config / database.php中:

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

将此行更改为:

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

答案 11 :(得分:4)

我添加了迁移本身

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

是的,我知道我需要在每次迁移时考虑它,但我宁愿将其隐藏在一些完全不相关的服务提供商中

答案 12 :(得分:3)

对于laravel 5.7,请在appserviceprovider.php中编写这些代码

  use Illuminate\Support\Facades\Schema;

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

答案 13 :(得分:3)

如果某人甚至在执行此操作后仍遇到此问题,则上述更改。例如,在我的情况下,我做了以下更改,

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

但是由于两个原因,它不会立即起作用。一种是如果您使用流明而非laravel,则可能必须先在app.php文件中取消注释此行。

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

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

php artisan make:migration <your_table_name>

从现在开始,只有您对ServiceProvider所做的更改将起作用。

答案 14 :(得分:3)

转到您的config/database.php并将字符集和排序规则从utf8mb4更改为utf8

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

使用这种方法解决了我的问题,祝您好运!

答案 15 :(得分:2)

将charset从'utf8mb4'更改为'utf8'和

将'utf8mb4_unicode_ci'整理为'utf8_unicode_ci'

在config / database.php文件中

它对我有用。

答案 16 :(得分:2)

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

app \ Providers \ AppServiceProvider.php中添加

use Illuminate\Support\Facades\Schema;

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

你应该好好去。

答案 17 :(得分:2)

如果您正在使用或更新到Laravel 5.4及其最新版本,则可以使用; 只需在AppServiceProvider.php中进行1次更改

use Illuminate\Support\Facades\Schema;

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

答案 18 :(得分:2)

Laravel&gt; = 5.6 用户

打开AppServiceProvider.php文件

使用以下课程

use Illuminate\Support\Facades\Schema;

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

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

答案 19 :(得分:1)

2016年10月24日 Taylor Otwell Laravel发布的作者是Twitter

  

“ utf8mb4”将是Laravel 5.4中的默认MySQL字符集,以更好地支持表情符号。 Taylor Otwell Twitter Post

在5.4版之前的字符集为utf8

在本世纪中,许多网络应用程序都包括聊天或某种允许用户交流的平台,并且许多人喜欢使用表情符号或笑脸。这是某种超级字符,需要存储更多空间,并且只能将utf8mb4用作 charset 。这就是为什么它们仅出于太空目的而迁移到utf8mb4的原因。

如果您在Illuminate\Database\Schema\Builder类中查找,则会看到$defaultStringLength设置为 255 ,并进行了修改,可以继续进行{{1} }外观并调用defaultStringLength方法并传递新的长度。

要执行该更改,请在您的Schema类中调用该方法,该类位于app \ providers子目录下

AppServiceProvider

我建议使用 191 作为值,因为MySQL支持767个字节,并且因为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 } (即每个多字节字符占用的字节数)将得到{{1 }}。

您可以在此处了解更多信息 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding)     Limits on Table Column Count and Row Size

答案 20 :(得分:1)

我遇到了问题,请更改“ config / database”的配置

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

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

然后我给出了命令

php artisan migrate

答案 21 :(得分:1)

您可以转到app/Providers/AppServiceProvider.php并将其导入

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

也在启动功能中添加此

Schema::defaultStringLength(191);

答案 22 :(得分:1)

我想指出一些我错过的东西......

我是Laravel的新手,我没有复制“使用Illuminate .....”,因为我真的没有注意,因为正好在功能启动之上你已经使用< / strong>声明。

希望能帮到任何人

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

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

答案 23 :(得分:1)

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

中的AppServiceProvider方法进行配置
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

答案 24 :(得分:0)

如果您尝试过其他所有答案,但都无法解决问题,则可以从数据库中删除所有表,然后使用此命令一次执行全部migration命令:

php artisan migrate:fresh

答案 25 :(得分:0)

如果您看到此错误,则绝对需要在以下位置进行以下更改 ['11', '2', '3', '4', '333', '6', '44', '33'] 文件->可以在AppServiceProvider.php内找到

要进行更改

app->providers:

这应该可以解决您的问题,您可以查看有关此问题的Laravel新闻。 https://laravel-news.com/laravel-5-4-key-too-long-error

答案 26 :(得分:0)

设置数据库引擎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();
        });

答案 27 :(得分:0)

其他人在Anwser的其他人中都有很好的描述 你可以在下面的链接中看到更多细节(使用键'索引长度&amp; MySQL / MariaDB'搜索) https://laravel.com/docs/5.5/migrations

但是这个答案不是什么意思!即使做了以上你还会得到另一个错误(就像你喜欢发布时那样{{1}命令并且由于长度的问题,操作就像卡在中间。解决方案如下,用户表就像创建没有其余的或不完全正确的) 我们需要滚动 k。默认回滚不会。因为迁移的操作不喜欢完成。您需要手动删除数据库中新创建的表。

我们可以使用修补程序来执行此操作,如下所示:

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

答案 28 :(得分:0)

解决方案:

首先在 app \ Providers \ AppServiceProvider.php 中将defaultStringLength更改为191:

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

然后,在 config \ database.php 中按如下所示更改charset and collation值:

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

link to know about MariaDB charset

答案 29 :(得分:0)

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

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

100个作品

答案 30 :(得分:0)

请记住,这些文章附带了简单和错误的解决方案。这就像因为您的袜子不合脚而将您的脚踩碎了。

正确的答案(买新袜子)要复杂一些,因为它要求您再次去商店。在这种情况下,它需要您配置mysql实例,并且复制/粘贴的错误答案不如错误答案,因此我们一直在传播错误答案。我们想看起来像是可复制/可粘贴且易于使用,对吧?

您忘记了指定要使用的Laravel或mysql版本。发生此问题是因为您使用的是较旧的mysql(或更新了错误设置的mysql)。

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

如果您没有innodb_default_row_format设置(在5.7.9中引入),则必须将config / database.php更改为使用'engine'=>'innodb row_format = dynamic'。

Laravel 5.2.14中引入了引擎设置,因此希望您对此有所更新。

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

答案 31 :(得分:0)

在某些情况下,如果您仅同意唯一前191个harhars

,可能会有所帮助
public function up()
{
    DB::statement('ALTER TABLE `YOUR_TABLE_NAME`    ADD UNIQUE INDEX `NAME_FOR_INDEX` (`YOUR_COLUMN_NAME` (191) );');
}

答案 32 :(得分:0)

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

无需更改DB conf和Laravael config/database.php。就像@scorer注意到10.2.2 +的默认行为一样。

答案 33 :(得分:0)

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

要使用Brew更新Mac上的MariaDB,请首先取消链接当前的: brew unlink mariadb然后使用brew install mariadb --devel

安装开发者

安装完成后停止/启动服务运行: brew services stop mariadb brew services start mariadb

当前的开发版本是10.2.3。安装完成后,您将不再需要担心这一点,您可以使用utf8mb4(现在是Laravel 5.4中的默认设置),而无需切换回utf8,也无法按照Laravel文档中的建议编辑AppServiceProvider:https://laravel.com/docs/master/releases#laravel-5.4 (向下滚动到:迁移默认字符串长度

答案 34 :(得分:0)

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

您唯一需要做的就是指定一个较短的索引名称,例如。

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

答案 35 :(得分:0)

编辑 config 文件夹中的 database.php 文件。来自

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

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

它应该可以工作!!!

答案 36 :(得分:-1)

请打开userpassword剩余文件。文件位于“数据库/迁移”文件夹中。

添加行

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

然后运行

php artisan migrate

答案 37 :(得分:-1)

在顶部包含此行

use Illuminate\Support\Facades\Schema;

然后在内部启动功能添加此

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

答案 38 :(得分:-1)

为您的电子邮件字符串提供较小的长度,例如:

df['new_colum'] = np.where(conditions, 1, 0)

print (df)
   A  B   C  new_colum
0  5  8   6          1
1  9  2   1          0
2  6  0   0          0
3  2  2   6          0
4  0  1   2          0
5  5  8  10          1
6  5  5   1          0
7  9  5   6          1


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

这肯定可以。