“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键

Posted

技术标签:

【中文标题】“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键【英文标题】:"General error: 1005 Can't create table" Using Laravel Schema Build and Foreign Keys 【发布时间】:2012-08-07 07:38:03 【问题描述】:

基本上,我和这个人有同样的问题,减去表前缀。因为我没有表前缀,所以他的修复不起作用。 http://forums.laravel.com/viewtopic.php?id=972

我正在尝试使用 Laravel 的 Schema Builder 构建一个表,如下所示:

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

基于网络上的帖子和关于如何设置 Laravel 的 Eloquent 关系的有限文档,我不确定我做错了什么......

users 已经存在,并且它确实有一个id 字段,即auto_increment。我也在用正确的关系(belongs_tohas_many)设置我的模型,但据我所知,这不是问题——这是数据库设置。 DB InnoDB。

外键到底做错了什么?

【问题讨论】:

【参考方案1】:

通过使用:

 $table->unsignedInteger('author');

代替:

 $table->integer('author');

问题会解决的。

问题是整数生成一个 int(11) 变量,而您需要一个 int(10) 变量。 unsignedInteger 会为你做的。

【讨论】:

【参考方案2】:

基本上,您会收到此错误,因为迁移命令创建表的顺序与您为表提供的 FK 引用不匹配。

如果你想创建一个 FK,它应该引用用户表中的 id,那么用户表必须存在。

在您的示例中,需要先创建作者表和课程表。

所以,我通过按这样的顺序(一个一个)创建表来解决这个问题,我可以成功地将 FK 引用到现有表。这样 Php Artisan Migration 就无法决定顺序。

另一种解决方案是,您可以简单地重命名迁移命令提供的表或时间戳

【讨论】:

【参考方案3】:

使用外键-s时,请确保您的外键是unsigned。这对我有用

【讨论】:

【参考方案4】:

已经列出的答案摘要,加上我的:

    外键一般需要InnoDb,所以设置你的默认引擎,或者明确指定

    $table->engine = 'InnoDB';
    

    外键需要引用的表存在。在创建密钥之前,请确保在较早的迁移中创建了引用的表。确保在单独的迁移中创建密钥。

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

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

【讨论】:

第 4 步已修复,现在 Jeffrey 的生成器中为 increments() 酷!那是什么时候改变的?有 Github 链接吗? Check This,之前有一个提交修复了创建,这个拉取请求也修复了数据透视表。【参考方案5】:

你必须在 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();
    );

【讨论】:

【参考方案6】:

我也遇到了同样的问题。我刚刚注意到Laravel Schema docs 最底部的以下注释:

注意:外键中引用的字段很可能是自动递增的,因此会自动成为无符号整数。请确保使用 unsigned() 创建外键字段,因为两个字段必须是完全相同的类型,两个表上的引擎必须设置为 InnoDB,并且引用的表必须在具有外键的表之前创建.

对我来说,只要我这样设置外键字段:

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

我没问题。

编辑:另外,请确保外表中的字段已经创建,否则这可能会失败并出现同样的错误。

【讨论】:

数据类型也是我的问题,两个表都是 InnoDB。 int() 类型不匹配引发了一般错误 1005,然后是 errno:150。当 table_a 上的两个 PK 都与 table_b 上的 FK 列类型完全匹配时,一切都很好。谢谢! 对于我代码中的类似情况,我不得不添加->nullable();在->unsigned(); 之后,它工作得很好:) @ArifulHaque 在这里使用 ->nullable() 破坏了外键的目的。只要 ->unsigned() 就足够了。 就我而言,问题是我的外键上没有 ->unsigned() 您必须始终使用->unsigned(),如果您的 onDelete 操作设置为“设置 null”->onDelete('set null'),请添加 ->nullable()【参考方案7】:

这在 Yii Framework 1.x 迁移中也发生在我身上。原来是 与上面的 Laravel 解决方案类似,它可能是由一个

表名拼写错误(或尚不存在) 列名拼写错误(或尚不存在) 在不同表中使用同一数据库中的重复外键名称

【讨论】:

【参考方案8】:

这是我在 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');
);

这就是结论的全部内容,它对我有用。

【讨论】:

【参考方案9】:

最简单的方法是禁用外键检查:

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

Schema::table( ... );

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

【讨论】:

【参考方案10】:

Laravel5、mysql55、CentOS65

在我的情况下,错误与此相同。

错误:[Illuminate\Database\QueryException] SQLSTATE[HY000]:一般错误:1005 无法创建表 'nabsh.#sql-5b0_e' (errno: 121) (SQL: alter table usermeta add 约束 usermeta_uid_foreign 外键 (uid) 参考 users (id) 删除级联)。

我在这个问题的已批准答案中找到了一个很好的提示: ERROR: Error 1005: Can't create table (errno: 121)

提示:如果您尝试添加名称已在其他地方使用过的约束,您将收到此消息。

在我的情况下,此错误意味着已尝试添加的约束已存在于某处(但我无法在任何地方看到它们)。

我复制了输出错误查询并在 sequel pro 中执行它,然后希望我再次看到相同的错误。正如提示所说,我将约束名称更改为其他名称,然后它没有任何错误影响,因此 laravel5 + MySQL55 + CentOS65 中的约束名称生成器存在问题。

解决方案:尝试通过在表模式的外部方法中发送第二个参数来重命名约束。

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

我希望它有所帮助。它适用于我的情况

【讨论】:

【参考方案11】:

我也遇到过这个问题。

我找到的解决方案是,在另一个表可以引用它之前,需要创建包含正在使用的外部 id 的 id 的表。基本上,您正在创建一个表并告诉 MySQL 引用另一个表的主键,但该表还不存在。

在您的示例中,需要先创建作者表和课程表。

创建表的顺序取决于工匠和您创建迁移文件的顺序。

我的意见是清空所有表的数据库并更改迁移文件名中的时间戳(或删除它们并以正确的顺序重新创建它们),以便在创建教程表之前创建作者表和课程表.

【讨论】:

【参考方案12】:

我收到了同样的错误,因为我忘记在引用的表上将表类型设置为 InnoDB:

$table->engine = 'InnoDB';

【讨论】:

这解决了我的错误。不幸的是,我的引用表已经创建,所以我必须在迁移中进行手动更新: DB::statement('ALTER TABLE my_table ENGINE = InnoDB');【参考方案13】:

我不是 100% 确定这些是否是失败的原因,但有几个指针。如果您使用旧版本的 mySQL 作为数据库,则默认表实现是不支持外键限制的 myISAM。由于您的脚本在外键分配上失败,您最好在 Schema 的 create 方法中使用此语法明确声明您希望 INNODB 作为引擎。

Schema::create('lessons', function($table)

    $table->engine = 'InnoDB';

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

这有望缓解您遇到的问题。

此外,虽然您可以事后声明外键,但我会在初始架构中创建外键,因为我可以轻松检查以确保我拥有正确的数据库引擎集。

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

希望这有助于/解决您的问题。

【讨论】:

在改组一些东西之后,我仍然得到一些关于外键约束的奇怪错误。奇怪的是——它确实工作,尽管有错误。事实证明,我在上面发布的错误是user.id 字段是int(10) unsigned 的结果,而外键是int(11)。不过感谢您的建议:) 没有问题 :) 使用上述架构时是否还会出现错误?或者当您输入数据时? 就在我创建架构的时候。据我所知,插入数据非常有效。 嘿@AndrewM,非常感谢您的跟进。遇到了完全相同的问题。

以上是关于“一般错误:1005 无法创建表”使用 Laravel 架构构建和外键的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.8:一般错误:1005 无法创建表

一般错误:1005 无法创建表

如何解决 laravel 迁移错误“一般错误:1005 无法创建表”

一般错误:1005 无法创建表 errno:150“外键约束格式不正确”)

SQLSTATE[HY000]:一般错误:1005 无法创建表 Laravel 8

SQLSTATE [HY000]:一般错误:1005 无法创建表`Data`.`company eligibilities`(errno:150“外键约束形成错误”)