25

新しい Laravel 4 プロジェクトを作成したところ、スキーマ ビルダーの外部キーの側面で奇妙なことが起こっていることがわかりました。いずれかの移行でこの方法を使用する->foreign()と、MySQL エラー 150 と一般エラー 1005 がスローされます。laravel.com/docs のドキュメントによると、下部の 2 つのシナリオは機能するはずですか? なぜそうしないのか誰か知っていますか?

以下は機能します:

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

        $table->integer('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });

ただし、次の 2 つは機能しません。

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

        $table->foreign('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });

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

        $table->integer('region_id');
        $table->foreign('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });
4

5 に答える 5

53

あなたのタイプをチェックしてくださいid。Laravel 4 は int(10) unsigned でインクリメンタル ID を作成します。基本整数を作成して外部キーを配置しようとすると、失敗します。

このリンクのドキュメントで提案されているように、それを機能させるには、で外部 ID を作成する必要があります$table->unsignedInteger(YOUR_ID_NAME);

于 2013-06-05T08:21:01.823 に答える
7

また、この質問「一般エラー: 1005 テーブルを作成できません」Laravel Schema Build and Foreign Keys を使用していくつかの回答があります

私のものを含め、そこにリストされている回答の要約:

  1. 通常、外部キーには InnoDb が必要なため、デフォルト エンジンを設定するか、明示的に指定 $table->engine = 'InnoDB'; します。テーブルが既に作成されていて、MyISAM にデフォルト設定されている場合は、それを変更する必要がある場合があります。

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

  3. 外部キーでは、データ型が合同である必要があります。参照されたフィールドが同じ型であるか、符号付きか符号なしか、長さが同じ (またはそれ以下) かどうかを確認します。

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

于 2013-09-20T13:31:49.377 に答える
5

前日も同じ問題がありました。

問題の根本は次のとおりです。外部キーを持つ列は、そのキーと同じ型でなければなりません。そして、さまざまなタイプがあります: INT/UNSIGNED INT

これは id をUNSIGNED INT

$table->increments('id');

これにより、region_id がINT

$table->integer('region_id')->references('id')->on('regions'); 

これを解決するには、region_idUNSIGNED INT

$table->integer('region_id')->unsigned()->references('id')->on('regions'); 
                              ^^^^^^^^^ note here

Laravelのドキュメントには、これについて言及されています:

注: 増加する整数を参照する外部キーを作成するときは、常に外部キー列を符号なしにすることを忘れないでください。

于 2014-03-23T13:29:57.180 に答える
2

それは機能しますが、時には注意して、舞台裏で何が起こっているのかを理解しようとする必要があります.

私のコメントで言ったように。関連する列を作成せずに最初に移行を実行すると、Laravel 移行サービスによってテーブルが作成され、再度移行しようとすると、テーブルが既に存在するというエラーが常に表示されます。

したがって、すべてを修正するには、もう一度drop table areas実行する必要があります。php artisan migrate

編集:

ここで移行 (以下) を作成したところ、うまくいきました。

ご覧のとおり、私は MySQL を使用していないため、MySQL の問題に違いありません。MySQL 外部キーのドキュメントをチェックして、メタデータが InnoDB の要件に適合するかどうかを確認してください: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

<?php

use Illuminate\Database\Migrations\Migration;

class CreateAreasTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('regions', function($table)
         {
             // $table->engine = 'InnoDB';
             $table->increments('id');
             $table->string('name', 160)->unique();
             $table->timestamps();
        });

        Schema::create('areas', function($table)
        {
            // $table->engine ='InnoDB';
            $table->increments('id');

            $table->integer('region_id');
            $table->foreign('region_id')->references('id')->on('regions');

            $table->string('name', 160);
            $table->timestamps();
        });     
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
    Schema::drop('areas');
    Schema::drop('regions');
    }

}

ここに画像の説明を入力

于 2013-06-04T22:58:30.830 に答える