【问题标题】:Laravel foreign_key Incorrect table definition; there can be only one auto column and it must be defined as a keyLaravel foreign_key 表定义不正确;只能有一个自动列,并且必须将其定义为键
【发布时间】:2020-01-01 00:41:12
【问题描述】:
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateOrderProductTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('order_product', function (Blueprint $table) {
            $table->bigIncrements('order_id');
            $table->foreign('order_id')->references('id')->on('orders');
            $table->bigIncrements('product_id');
            $table->foreign('product_id')->references('id')->on('products');
        });
    }

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


I expected to create a pivot table, but when I run the "php artisan migrate" it give me this: 

    SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key

(SQL: 创建表order_product (order_id bigint unsigned not null auto_increment 主键,product_id bigint unsigned not null auto_increment 主键) 默认字符集 utf8mb4 collat​​e 'utf8mb4_unicode_ci')

What is wrong with my code? :(

【问题讨论】:

  • 我认为bigIncrements() 也会使主键成为主键,并且您不能在同一个表中拥有多个主键。虽然错误似乎与外键有关,但我不是 100% 确定。
  • bigIncrements() 使自动递增 UNSIGNED BIGINT(主键)等效列。 MySQL 不允许两个主键存在于一个表中。我假设您需要使用 $table-&gt;bigInteger('product_id');,这应该是一个 BIGINT 数据类型。
  • 把两个bigIncrements改成unsignedBigInteger。您正在尝试在数据透视表中创建两个自动增量列。
  • 我将 bigIncrements 更改为 unsignedBigInteger 并且它可以工作。非常感谢! :)

标签: mysql laravel


【解决方案1】:

将第一行保留为$table-&gt;bigIncrements('id')-&gt;unsigned();,将其余带有bigIncrements 的行改为bigInteger()

public function up()
{
    Schema::create('order_product', function (Blueprint $table) {
        $table->bigIncrements('id')->unsigned();
        $table->bigInteger('order_id')->unsigned();
        $table->foreign('order_id')->references('id')->on('orders');
        $table->bigInteger('product_id')->unsigned();
        $table->foreign('product_id')->references('id')->on('products');
    });
}

更好的是,您可以使用Eloquent's built in relationships 而不是对中间数据透视表进行人工处理。

【讨论】:

    【解决方案2】:

    通过您的迁移,您尝试在同一个表中创建 两个 主键,这就是您遇到的错误。

    当您将字段声明为 bigIncrements 时,您是在要求 laravel 创建一个 auto incrementing primary key;你在同一个表中有两个这样的声明,这不是possible

    看到你想创建一个pivot 表,如果你不想有一个代表中间表order_productModel,你真的不需要一个主键

    要消除错误,您必须对两个外键使用unsignedBigInteger,因为它们所引用的字段(ordersproducts 表的id 列)是unsigned bigintegers 即:

    public function up()
    {
        Schema::create('order_product', function (Blueprint $table) {
            $table->unsignedBigInteger('order_id');
            $table->foreign('order_id')->references('id')->on('orders');
            $table->unsignedBigInteger('product_id');
            $table->foreign('product_id')->references('id')->on('products');
        });
    }
    

    如果您想在两个外键上使用composite primary key,您可以在迁移中写下这个:

    $table->primary(['order_id', 'product_id']);
    

    此行还确保您的表中不会出现重复行(order_idproduct_id)。声明composite unique index 可以达到同样的效果:

    $table->unique(['order_id', 'product_id']);
    

    如果您想要 one primary key,您可以添加一个 id 列,只需将此行写入上面的迁移:

    $table->bigIncrements('id');
    

    但这只有在您想要intermediate table Model 时才真正有用。

    顺便说一句,除了 bigIncrements 的错误之外,用于数据透视表和字段的命名约定已经很完美了。

    【讨论】:

    • @serg11u 如果它解决了您的问题,请考虑接受并支持答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 2015-04-05
    • 2013-07-12
    • 1970-01-01
    • 2017-05-31
    • 2013-12-17
    • 1970-01-01
    • 2015-05-07
    相关资源
    最近更新 更多