关于mysql:Laravel 4迁移中的外键

Foreign keys in Laravel 4 migrations issue

我刚刚创建了一个新的Laravel 4项目,并且发现架构生成器的外键方面发生了奇怪的事情。如果我在任何迁移中都使用->foreign()方法,则会抛出MySQL错误150和常规错误1005。根据laravel.com/docs上的文档,底部的两种情况应该起作用吗?有人知道为什么他们不这样做吗?

以下内容确实有效:

1
2
3
4
5
6
7
8
9
10
    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();
    });

但是这两个不起作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    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();
    });


检查您的id类型。 Laravel 4创建一个带有int(10)无符号的增量ID。
如果创建一个基本整数并尝试在其上放置一个外键,它将失败。

如在此链接的文档中所建议的那样,您应使用$table->unsignedInteger(YOUR_ID_NAME);创建外部ID以使其起作用。


在使用" Laravel模式构建和外键"的"一般错误:1005无法创建表"这个问题上,还有一些答案

那里列出的答案的摘要,包括我的:

  • 外键通常需要InnoDb,因此请设置默认引擎或明确指定

    $table->engine = 'InnoDB';

    如果您的表已经创建并且默认为MyISAM,则可能需要更改它。

  • 外键要求引用表存在。在创建键之前,请确保引用的表是在较早的迁移中创建的。请确保考虑在单独的迁移中创建密钥。

  • 外键要求数据类型一致。检查所引用字段的类型是否相同,是否为带符号的或无符号的,长度是否相同(或更短)。

  • 如果要在手工编码迁移和使用生成器之间进行切换,请确保检查所使用的ID类型。 Artisan默认使用增量(),但杰弗里·韦(Jeffrey Way)似乎更喜欢整数('id',true)。


  • 一天前有同样的问题。

    问题的根源是:具有外键的列必须与该键具有相同的类型。
    并且您有不同的类型:INT / UNSIGNED INT

    这使id成为UNSIGNED INT

    1
    $table->increments('id');

    ,这使region_id成为INT

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

    要解决此问题,请将region_id也设置为UNSIGNED INT

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

    Laravel的文档对此有所提及:

    Note: When creating a foreign key that references an incrementing integer, remember to always make the foreign key column unsigned.


    它可以工作,但是有时您只需要小心并尝试了解幕后发生的事情。

    正如我在评论中所说。当您第一次运行迁移而未创建相关列时,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。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    <?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');
        }

    }

    enter


    antonio carlos是正确的,请确保您首先创建了外键的引用表。

    首先尝试迁移没有外键的表,然后进行另一次分配外键的迁移。在此状态下,laravel确保参考密钥存在。并且您在工匠错误期间不必删除表。