Laravel Eloquent创建使用自增的复合主键

4

我有一个迁移如下:

        $table->increments('id');
        $table->integer('order_num');
        $table->timestamps();

主键应该是id和order_num的组合。如果我放置以下代码,它会说我正在尝试添加2个主键(因为increments也是主键)。有没有一种方法告诉 eloquent 我正在将这两个内容捆绑在一��?
        $table->primary(['course_id', 'order_num']);

你的第一个代码片段是哪个表?我猜你有一个订单表,但另一个是什么? - Gokigooooks
也许您能多解释一下情况?Increments 为每一行生成一个唯一的自动递增 ID。您不需要添加任何内容以使其唯一。当涉及到的列已经唯一时,我看不出使用复合主键的理由。 - Kelly Kiernan
1个回答

7

我假设您正在使用MySQL

首先,MySQL默认引擎InnoDB不允许复合主键中有一个字段是自动递增的。允许这样做的引擎是MyISAM,因此您需要做的第一件事就是更改表的引擎。

您可以通过将以下内容添加到表定义中来实现:

$table->engine = 'MyISAM';

下一个需要解决的问题是Laravel的架构生成器假设你设置为自动增量的列是主键。这就是为什么你会收到关于主键已经存在的错误信息 - Laravel已经将id字段设置为主键。
要解决这个问题,你需要将id字段声明为普通整数列,定义所有其他列,最后声明组合主键。它可能看起来像这样:
$table->integer('id');
$table->integer('order_num');
$table->timestamps();
$table->primary(['course_id', 'order_num']);

这样你已经创建了一个复合主键。唯一缺少的是在id列上的自增属性。Laravel的模式构建器不提供更改现有列的方法,因此您需要运行原始SQL查询。所需查询如下:

DB::statement('ALTER TABLE my_table MODIFY id INTEGER NOT NULL AUTO_INCREMENT');

总之,您的迁移的up()方法可能如下所示:
public function up()
{
  Schema::create('my_table', function (Blueprint $table) {
    $table->engine = 'MyISAM';

    $table->integer('id');
    $table->integer('order_num');
    $table->timestamps();
    $table->primary(['course_id', 'order_num']);
  });

  DB::statement('ALTER TABLE my_table MODIFY id INTEGER NOT NULL AUTO_INCREMENT');
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接