web-dev-qa-db-ja.com

「一般的なエラー:1005はテーブルを作成できません」を使用してLaravel Schema Build and Foreign Keys

基本的に、私はこの男と同じ問題を抱えていますが、テーブルの接頭辞はありません。私にはテーブルのプレフィックスがないため、彼の修正は機能しません。 http://forums.laravel.com/viewtopic.php?id=972

私は次のようにLaravelのスキーマビルダーを使用してテーブルを構築しようとしています:

Schema::create('lessons', function($table)
{
    $table->increments('id');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->timestamps();
});

Schema::create('tutorials', function($table)
{
    $table->increments('id');
    $table->integer('author');
    $table->integer('lesson');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->string('tagline')->nullable();
    $table->text('content')->nullable();
    $table->text('attachments')->nullable();
    $table->timestamps();
});

Schema::table('tutorials', function($table)
{
    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

問題は、このコードを(/ setupルートで)実行すると、次のエラーが発生することです。

SQLSTATE[HY000]: General error: 1005 Can't create table 'tutorials.#sql-2cff_da' (errno: 150)

SQL: ALTER TABLE `tutorials` ADD CONSTRAINT tutorials_author_foreign FOREIGN KEY (`author`) REFERENCES `users` (`id`)

Bindings: array (
)

Web上の投稿とsetupLaravelのEloquentリレーションシップの方法に関する限られたドキュメントに基づいて、何が間違っているのかわかりません。 。

usersは既に存在し、doesidフィールドにauto_increment。また、適切な関係(belongs_toおよびhas_many)、しかし、私が知る限り、これは問題ではありません-それはデータベースのセットアップです。 DBisInnoDB。

外部キーで何が間違っていますか?

32
Andrew M

これらがこれが失敗する理由であるかどうかは100%確信していませんが、いくつかのポインタがあります。データベースとしてmySQLの古いバージョンを使用している場合、デフォルトのテーブル実装は外部キーの制限をサポートしないmyISAMです。外部キーの割り当てでスクリプトが失敗するため、スキーマのcreateメソッドでこの構文を使用して、INNODBをエンジンとして使用することを明示的に述べる方が適切です。

Schema::create('lessons', function($table)
{
    $table->engine = 'InnoDB';

    $table->increments('id');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->timestamps();
});

うまくいけば、あなたが抱えている問題を軽減できるはずです。

また、外部キーを後付けとして宣言できますが、適切なDBエンジンが設定されていることを確認する簡単なチェックを行うことができるため、初期スキーマ内で外部キーを作成します。

Schema::create('tutorials', function($table)
{
    $table->engine = 'InnoDB';

    $table->increments('id');
    $table->integer('author');
    $table->integer('lesson');
    $table->string('title')->nullable();
    $table->string('summary')->nullable();
    $table->string('tagline')->nullable();
    $table->text('content')->nullable();
    $table->text('attachments')->nullable();
    $table->timestamps();

    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

これがあなたの問題を助ける/解決することを願っています。

11
David Barker

私は同じ問題を抱えています。 Laravel Schema docs の一番下に次の注意事項があります。

注:外部キーで参照されるフィールドは、おそらく自動インクリメントであるため、自動的に符号なし整数になります。両方のフィールドはまったく同じタイプである必要があり、両方のテーブルのエンジンをInnoDBに設定する必要があるため、unsigned()を使用して外部キーフィールドを作成してください。 。

私にとっては、外部キーフィールドを次のように設定するとすぐに:

$table->integer('author')->unsigned();

問題ありませんでした。

編集:また、外部テーブルのフィールドが既に作成されていることを確認してください。そうでない場合、同じエラーで失敗する可能性があります。

79
maackle

すでにリストされている答えの要約と私のもの:

  1. 通常、外部キーにはInnoDbが必要なので、デフォルトのエンジンを設定するか、明示的に指定します

    $table->engine = 'InnoDB';
    
  2. 外部キーには、参照されるテーブルが存在する必要があります。キーを作成する前に、参照されるテーブルが以前の移行で作成されていることを確認してください。確実に別の移行でキーを作成することを検討してください。

  3. 外部キーでは、データ型が一致している必要があります。参照されているフィールドが同じ型であるかどうか、署名されているかどうかにかかわらず、フィールドの長さが同じ(またはそれ以下)かどうかを確認します。

  4. 手動コーディングの移行を切り替えて、ジェネレーターを使用する場合は、使用しているIDタイプを確認してください。 Artisanはデフォルトでincrements()を使用しますが、Jeffrey Wayはinteger( 'id'、true)を好むようです。

8
Tim Ogilvy

私もこの問題に遭遇しました。

私が見つけた解決策は、別のテーブルがそれを参照する前に、外部IDとして使用されているIDを含むテーブルを作成する必要があるということです。基本的に、テーブルを作成し、MySQLに別のテーブルの主キーを参照するように指示していますが、そのテーブルはまだ存在していません。

あなたの例では、著者とレッスンのテーブルを最初に作成する必要があります。

テーブルが作成される順序は、職人と移行ファイルを作成した順序に依存します。

私の意見では、すべてのテーブルのデータベースを空にし、移行ファイル名のタイムスタンプを変更(または削除して正しい順序で再作成)し、チュートリアルテーブルの前に作成者とレッスンのテーブルが作成されるようにします。

6
Justin Flammia

参照されるテーブルでテーブルタイプをInnoDBに設定するのを忘れたため、同じエラーを受け取りました。

$table->engine = 'InnoDB';

Laravel5、MySQL55、CentOS65

私の場合、エラーはこれと同じでした。

エラー:[Illuminate\Database\QueryException]
SQLSTATE [HY000]:一般エラー:1005テーブル 'nabsh。#sql-5b0_e'を作成できません(errno:121)(SQL:alter table usermeta add constraint usermeta_uid_foreign foreign key(uid)参照users(削除カスケードのid))。

この問題の承認された答えに良いヒントを見つけました: エラー:エラー1005:テーブルを作成できません(errno:121)

ヒント:すでに別の場所で使用されている名前の制約を追加しようとすると、このメッセージが表示されます。

私の場合、このエラーは、追加しようとした制約が既にどこかに存在することを意味します(ただし、どこにも表示されませんでした)。

出力エラークエリをコピーし、sequel pro内で実行しました。その後、同じエラーが再び表示されることを願っています。ヒントにあるように、制約名を別の名前に変更するとエラーなしで影響を受けるため、laravel5 + MySQL55 + CentOS65の制約名ビルダーに問題があります。

解決策:テーブルスキーマの外部メソッドで2番目のパラメーターを送信して、制約の名前を変更します。

Schema::table('tutorials', function($table)
{
    $table->foreign('author')->references('id')->on('users');
    $table->foreign('lesson')->references('id')->on('lessons');
});

に->

Schema::table('tutorials', function($table)
{
    $table->foreign('author', 'fk_tutorials_author')->references('id')->on('users');
    $table->foreign('lesson', 'fk_tutorials_lesson')->references('id')->on('lessons');
});

役に立てば幸いです。私の場合はうまくいきます

3

これは、Yii Framework 1.xの移行でも発生しました。Laravel

  • スペルが間違っている(またはまだ存在しない)テーブル名
  • スペルが間違っている(またはまだ存在しない)列名
  • 異なるテーブルで使用されている同じデータベース内の重複する外部キー名
1
joffdd

foreign key-sを使用する場合は、外部キーがunsignedであることを確認してください。これは私のために働いた

1
Guka Gunia

Laravel 5.4では、整数に符号なしフラグを指定する必要があります。次のようになります。

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('post_id');
        $table->text('title');
        $table->text('text');
        $table->integer('employee_post_id_number')->unsigned();
        $table->foreign('employee_post_id_number')->references 
        ('employee_id_number')->on('employees');
        $table->timestamps();
    });
}
0
Nina

Laravel 5:

// CREATING TABLE
Schema::create('your_table_name', function (Blueprint $table) {
    $table->engine = 'InnoDB';
    $table->increments('id'); // index field example sample
    $table->string('field2'); // some varchar/string field sample
    $table->integer('field3'); // some integer field sample
    $table->integer('field_some_table_id')->unsigned; //for field that contains foreign key constraint
});

// FOREIGN KEY CONSTRAINT
Schema::table('stock', function ($table) {
    $table->foreign('field_some_table_id')->references('id')->on('some_table')->onDelete('cascade')->onUpdate('cascade');
});

これで結論は終わりです。私にとってはうまくいきます。

0
JoenMarz

最も簡単な方法は、外部キーチェックを無効にすることです。

DB::statement('set foreign_key_checks=0');

Schema::table( ... );

DB::statement('set foreign_key_checks=1');
0
Daniel