web-dev-qa-db-ja.com

Laravel migration:一意キーが指定されていても長すぎます

Laravelのユーザーテーブルを移行しようとしています。移行を実行すると、このエラーが発生します。

[Illuminate\Database\QueryException] SQLSTATE [42000]:構文エラーまたはアクセス違反:1071指定されたキーが長すぎます。最大キー長は767バイトです(SQL:変更テーブル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');
});

いくつかのグーグルの後、私は出会った このバグレポート で、Taylorはインデックスキーをunique()の2番目のパラメータとして指定できると言います。それでもエラーが発生します。ここで何が起こっているの?

138
harryg

電子メールの長さを短くしてください。

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

これはデフォルトです、実際には:

$table->string('email');

そしてあなたは良いはずです。

Laravel 5.4の場合、これで解決策を見つけることができます Laravel 5.4:指定されたキーは長すぎますエラー、Laravel News 役職:

これを修正するためのMigrationsガイドに概説されているように、あなたはあなたのAppServiceProvider.phpファイルを編集しそして起動方法の中でデフォルトの文字列長を設定することです:

use Illuminate\Support\Facades\Schema;

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

アップデート1

Laravel 5.4 現在、これらの変更は不要です。

Laravel 5.4はデフォルトでutf8mb4文字セットを使用します。これには、データベースに「emojis」を保存するサポートが含まれます。アプリケーションをLaravel 5.3からアップグレードする場合、この文字セットに切り替える必要はありません。

更新2

現在の本番MariaDBバージョンは、デフォルトでグローバルにこの設定をサポートしませんデフォルトではMariaDB 10.2.2 + で実装されています。

ソリューション

意図的に正しい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

そして、STOPMySQL/MariaDBサーバー。そのSTARTの後。ホットリスタートが機能しない場合があります。

Sudo systemctl stop mysqld
Sudo systemctl start mysqld

これで、UTF8をサポートしたLaravel 5.xができました。

98
scorer

あなたがオンになっているか、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

42
varta

他の誰かが私がしたのとは違う理由でこの答えを見つけた場合、あなたはあなたのLaravel DB文字セット/照合順序をチェックすることができます。

私はアプリケーション(Snipe-IT)をインストールしていて、Laravel database configを以下のように設定しました。

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

両方の文字列からmb4を削除することで問題は解決しましたが、Antonioの答えが問題の本当の解決策であると私は信じています。

32
Brendan

これは私のために働いた:

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

Charsetからmb4を削除し、config/database.phpから照合順序を削除すると、正常に実行されます。
'charset' => 'utf8'、
'照合' => 'utf8_unicode_ci'、

15
Ramv V

Laravel 5.4では、ファイルを編集するだけです

App\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\Schema;

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

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,
],

この2つのフィールドを変更

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

これとともに

'charset' => 'utf8',
'collation' => 'utf8_unicode_ci'
11
Avijit Mandal

私は同じ問題に直面しており、私のapp/database.phpに以下の2行を追加することでそれを修正しました。

'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',

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

TO ->
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
6
Faizan Noor

Config/database.phpファイルの内容は次のとおりです。

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

この行をこれに変更してください。

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

私は同じ問題を抱えていて、私はwampを使っています

解決策:ファイルを開く:config/database.php

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

ありがとう

4
Purvesh

移行自体に追加しました

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

はい、すべての移行で考慮する必要があることはわかっていますが、まったく関係のないサービスプロバイダに隠しておくよりもむしろ望みます。

4
Manoj Thapliyal

誰かがやった後でもこの問題を抱えているならば、上記の変更点。例として、私の場合、私は以下の変更を行いました、

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

しかし、それは2つの理由ですぐにはうまくいかないでしょう。 1つは、laravelの代わりにLumenを使用している場合、まずapp.phpファイルでこの行のコメントを外してください。

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

その後、artisanコマンドを使用して移行スクリプトをもう一度作成する必要があります。

php artisan make:migration <your_table_name>

今からServiceProviderに加えた変更だけが機能します。

3
dilantha111

laravel 5.7のためにappserviceprovider.phpにこれらのコードを書いてください。

  use Illuminate\Support\Facades\Schema;

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

これは、Laravel 5.4が絵文字の保存をサポートするutf8mb4を使用するためです。

これをあなたのapp\Providers\AppServiceProvider.phpに追加してください

use Illuminate\Support\Facades\Schema;

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

そして、あなたは行ってもいいはずです。

2
Irteza Asad

あなたがLaravel 5.4と最新バージョンに更新しているなら、それは動作します。
AppServiceProvider.phpを1回だけ変更

use Illuminate\Support\Facades\Schema;

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

Laravel> = 5.6ユーザーの場合

AppServiceProvider.phpファイルを開く

次のクラスを使う

use Illuminate\Support\Facades\Schema;

それからbootメソッドの中に次の行を追加します

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

文字セットを 'utf8mb4'から 'utf8'に変更し、

'utf8mb4_unicode_ci'から 'utf8_unicode_ci'への照合

config/database.phpファイルに

それは私のために働きました。

2
Chetan Godhani

2016年10月24日にTaylor Otwellが発表したLaravelの作者はTwitterです

"utf8mb4"は、より良い絵文字サポートのためにLaravel 5.4でデフォルトのMySQL文字セットになります。 ???? Taylor Otwellツイッターポスト

バージョン5.4より前は、文字セットはutf8でした

今世紀の間に多くのウェブアプリは、チャットやユーザーが会話をすることを可能にするためのある種のプラットフォームを含み、そして多くの人々は絵文字やスマイリーを好む。そしてこれは、より多くのスペースを格納することを必要とするある種のスーパーキャラクタであり、文字セットとしてutf8mb4を使用する場合にのみ可能です。それが、彼らがスペースのためだけにutf8mb4に移行する理由です。

Illuminate\Database\Schema\Builderクラスを調べると、 $defaultStringLength255に設定されていることがわかります。変更するには、Schemaファサードを進んで defaultStringLength メソッドを呼び出して新しい長さを渡します。

このような変更を行うには、app\providerサブディレクトリの下にある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
}

MySQLが767バイトをサポートしているので、191を値として使用することをお勧めします。また、各マルチバイト文字のバイト数である767 / 4は、191を取得するためです。

あなたはここでもっと学ぶことができます utf8mb4文字セット(4バイトUTF-8 Unicodeエンコーディング)テーブルカラムの制限カウントと行サイズ

1
Yves Kipondo

Laravelはデフォルトでutf8mb4文字セットを使用します。これはデータベースに "emojis"を格納するためのサポートを含みます。バージョン5.7.7より前のMySQLまたはバージョン10.2.2より前のMariaDBを実行している場合は、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-errorhttps://laravel.com/docs/5.5/migrations#indexes

1
Barakat Turki

問題がありました、 'config/database'の設定を変更してください

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

データベースに同じパターンを保持します。

それから私は命令を与えました

php artisan migrate

私が逃した何かを指摘したいのですが….

私はLaravelの新人です、そして私は本当に注意を払っていなかったので、私は "use Illuminate ....."をコピーしませんでした。なぜなら、関数ブートの真上に use ステートメントがあるからです。 。

誰にでも役立つことを願っています

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

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

先頭にこの行を含める

use Illuminate\Support\Facades\Schema;

それから内部ブート機能はこれを加えます

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

MariaDB 10.2.4 RCをインストールしたばかりで、新しい空のLaravel 5.4プロジェクトが起動し、デフォルトの移行(varchar(255)列)が機能します。

DB confとLaravael config/database.phpを変更する必要はありません。 @scorerが10.2.2以降のデフォルトの振る舞いについて述べたように。

0
kroko

データベースエンジン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();
        });
0
Harshad Vala

メール文字列の長さを短くしてください:

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

そして

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

これは間違いなく機能します。

0
Abid Shah

あなたがこのエラーを見ているなら、間違いなくあなたは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

0
Sandesh Poudel

電子メールの長さを短くしてください。

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

100作品

0
Pir Abdul

すべては他のAnwserで詳しく説明されています。詳細については、以下のリンクを参照してください(キー 'Index Lengths&MySQL/MariaDB "で検索) https://laravel.com/docs/5.5/migrations

しかし、それはこの答えが何であるかではありません!物事は上記を行っても同じです error(それはlaunch php artisan migrateコマンドが好きなときで、長さの問題のため、操作が途中で止まるようなものです。ソリューションはbellow、そしてユーザーテーブルは残りなしで作成されたか、完全に正しくないようです)backをロールする必要があります。デフォルトのロールバックは行いません。移行の操作が終了を好まなかったからです。データベースに新しく作成されたテーブルを手動で削除する必要があります。

以下のようにティンカーを使用してそれを行うことができます:

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
0
Mohamed Allal

MySQL 5.7.7+またはMariaDB 10.2.2+を使用している場合、この問題は発生しません。

Brewを使用してMacでMariaDBを更新するには、まず現在のリンクを解除します:brew unlink mariadb、次にbrew install mariadb --develを使用してdev oneをインストールします

インストールが完了したら、実行中のサービスを停止/開始します:brew services stop mariadb brew services start mariadb

現在の開発バージョンは10.2.3です。インストールが完了したら、これについて心配する必要はもうありません。utf8mb4(現在はLaravel 5.4のデフォルト)を使用できます。utf8に戻ったり、Laravelドキュメント: https://laravel.com/docs/master/releases#laravel-5.4 (スクロールダウン:移行デフォルト文字列の長さ))

0
Richard Dawson

解決策:

最初にapp\Providers\AppServiceProvider.phpでdefaultStringLengthを191に変更します。

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

次に、config\database.phpで、 文字セットと照合順序 の値を次のように変更します。

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

MariaDB文字セットについて知るためのリンク

0
Naveen Kumar V

他のすべての答えを試してもうまくいかなかった場合は、データベースからすべてのテーブルを削除してから、次のコマンドを使用してmigrateコマンドを一度に実行します。

php artisan migrate:fresh
0
Treasure