MySQL Laravel 4 迁移问题中的外键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16928740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 17:50:44  来源:igfitidea点击:

Foreign keys in Laravel 4 migrations issue

mysqllaravellaravel-4

提问by JasonMortonNZ

I've just created a new Laravel 4 project and am finding strange things happening with the foreign key aspect of the schema builder. If I use the ->foreign()method in any of my migrations I get thrown MySQL errors 150 and general error 1005. According to the documentation at laravel.com/docs the two scenario's at the bottom should work? Anyone know why they don't?

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

The following does work:

以下确实有效:

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

But these two do not work:

但是这两个不起作用:

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

回答by netvision73

Check your idtype. Laravel 4 creates an incremental id with a int(10) unsigned. If you create a basic integer and try to put a foreign key on it, it will fail.

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

As suggested in the documentation at this link, you should create the foreign id with $table->unsignedInteger(YOUR_ID_NAME);to make it work.

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

回答by Tim Ogilvy

Also some answers over at this question "General error: 1005 Can't create table" Using Laravel Schema Build and Foreign Keys

在这个问题“General error: 1005 Can't create table” Using Laravel Schema Build and Foreign Keys上也有一些答案

A Summary of the answers listed there, including mine:

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

  1. Foreign Keys generally require InnoDb, so set your default engine, or explicitly specify $table->engine = 'InnoDB'; If your table is already created and has defaulted to MyISAM, you may need to alter it.

  2. Foreign keys require the referenced table to exist. Make sure the referenced table is created in an earlier migration, prior to creating the key. Consider creating the keys in a separate migration to be sure.

  3. Foreign Keys require the data type to be congruent. Check whether the referenced field is the same type, whether its signed or unsigned, whether it's length is the same (or less).

  4. If you are switching between hand coding migrations, and using generators, make sure you check the id type you are using. Artisan uses increments()by default but Jeffrey Way appears to prefer integer('id', true).

  1. 外键一般需要 InnoDb,所以设置你的默认引擎,或者明确指定 $table->engine = 'InnoDB'; 如果你的表已经创建并且默认为 MyISAM,你可能需要改变它。

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

  3. 外键要求数据类型一致。检查引用的字段是否相同类型,是否有符号或无符号,长度是否相同(或更少)。

  4. 如果您在手动编码迁移和使用生成器之间切换,请确保检查您使用的 id 类型。Artisan默认使用increments(),但 Jeffrey Way 似乎更喜欢integer('id', true)

回答by nned

Had same problem day ago.

前天有同样的问题。

Root of problem is : column with foreign key must be same type as that key. And you have different types: INT/UNSIGNED INT

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

this makes id an UNSIGNED INT

这使 id 成为 UNSIGNED INT

$table->increments('id');

and this makes region_id an INT

这使得 region_id 成为 INT

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

To solve this, make region_id an UNSIGNED INTtoo

为了解决这种情况,请REGION_ID的UNSIGNED INT

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

Documentation of Laravel has mentionabout this :

Laravel 的文档中提到了这一点:

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

注意:创建引用递增整数的外键时,请记住始终使外键列无符号。

回答by Antonio Carlos Ribeiro

It works, but sometimes you just have to be careful and try to understand what is happening behind the scene.

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

As I said in my comment. When you first ran the migration without creating the related column, Laravel migration services created your table and then, when you tried to migrate again it will always give you an error saying that the table already exists.

正如我在评论中所说。当您第一次在没有创建相关列的情况下运行迁移时,Laravel 迁移服务创建了您的表,然后当您再次尝试迁移时,它总是会提示您该表已存在。

So you just have to drop table areasand run php artisan migrateagain to fix it all.

所以你只需要再次drop table areas运行php artisan migrate来修复它。

EDIT:

编辑:

I just created your migration (below) here and it worked.

我刚刚在这里创建了您的迁移(如下)并且它起作用了。

As you can see I'm not using MySQL, so it must be a MySQL problem. Check MySQL foreign key documentation to see if your metadata fits in InnoDB requirements: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html.

正如你所看到的,我没有使用 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');
    }

}

enter image description here

在此处输入图片说明

回答by Jur P

antonio carlos is right, make sure that you created first the reference table of your foreign key.

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

try migrate first the tables without foreign keys , then make another migration assigning the foreign keys. on this state, laravel is sure that the reference key(s) are existing. and you dont have to drop tables during the artisan errors.

尝试先迁移没有外键的表,然后再进行一次分配外键的迁移。在这种状态下,laravel 确保引用键存在。并且您不必在工匠错误期间删除表。