Laravel 4:如何使用迁移创建非主自动递增列?

Posted

技术标签:

【中文标题】Laravel 4:如何使用迁移创建非主自动递增列?【英文标题】:Laravel 4: How do I create a non-primary auto incrementing column with migrations? 【发布时间】:2013-03-01 18:34:03 【问题描述】:

我目前正在开发一个由主服务器和许多客户端组成的 Laravel 4 项目。客户端创建数据并将其发送到主服务器。为避免冲突,我使用 UUID v4 作为主键。

但是,一旦在服务器上创建了数据,我想分配一个唯一的自动递增整数,以便用户更容易识别数据。例如:用户可以谈论item #24567,而不是谈论item 5a8e896d-3ab4-48d2-9d39-faeb5227f012

为了让我的应用程序易于管理,我正在使用迁移,我当前对该表的迁移如下所示:

public function up()

    Schema::table('items', function($table)
    
        $table->create();
        $table->string('id')->primary(); //'id' For the purpose of keeping the ORM working, this field stores the UUID.
        $table->integer('number', true); //The human readable item number, the second parameter is true for auto-increment
        $table->text('otherdata');
        $table->timestamps();
    );

问题是 Laravel 在定义自动增量时会自动创建一个主键,因此迁移最终会失败,因为有两个主键。

[Exception] SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary key defined
  (SQL: alter table `items` add primary key items_id_primary(`id`)) (Bindings: array ())

有没有办法使用 Laravel 4 迁移来获得一个具有主键和一个单独的自动递增字段的表。

【问题讨论】:

【参考方案1】:

我发现了问题,Laravel 似乎正在为每个 auto_increment 字段创建一个主键。当我删除primary key 部分时,它要求我提供一个索引,所以我在迁移时调用->unique(),但这也不起作用。将return ' auto_increment primary key'; 更改为return ' auto_increment unique';解决了我的问题,尽管它现在在核心中被黑了,这当然是不好的做法。

/**
 * Get the SQL for an auto-increment column modifier.
 *
 * @param  Illuminate\Database\Schema\Blueprint  $blueprint
 * @param  Illuminate\Support\Fluent  $column
 * @return string|null
 */
protected function modifyIncrement(Blueprint $blueprint, Fluent $column)

    if ($column->type == 'integer' and $column->autoIncrement)
    
        return ' auto_increment unique'; //return ' auto_increment primary key';
    

【讨论】:

我不认为这是更好的解决方案(改变 laravel Db 类的核心功能。)。 如果您阅读了我的评论,您就会明白您的解决方案没有回答我的问题。这就是我否决它的原因。我知道我的解决方案不是最佳实践,但您的解决方案并不能解决我的问题。 所以你需要两个单独的列,一个是自动递增的主键,另一个是 uuid 的键。我说的对吗? UUID 是主键,另一列必须是唯一的并且自动递增,正确。但是,这是关于一个不起作用的迁移,这与 ORM 无关。 您忘记指定您修改的是哪个文件。此外,您可以扩展该类并更新 Façade 以避免硬编码到核心......【参考方案2】:

诀窍是像这样将它添加到 Schema::create 之外

Schema::create('payments', function(Blueprint $table)

   $table->string('primaryKey', 30);
   $table->primary('primaryKey');
   //...
);
DB::statement('ALTER Table tableName add id INTEGER NOT NULL UNIQUE AUTO_INCREMENT;');

然后重做迁移,键将在表 tableName 中创建名称 id 然后您可以像访问任何其他键一样访问它。

【讨论】:

【参考方案3】:

我认为不修改核心文件是无法做到的,因为创建 auto_increment 会自动使其成为主键。

如果你能在 Larvel 框架开发中将它报告为错误就更好了。团队。

here 谢谢:)

【讨论】:

【参考方案4】:

是的,您可以在 Items 类的模型声明中这样做

class Items extends Eloquent 
   /**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = false;


现在您的主键不再是自动递增字段。

【讨论】:

在我的问题中,我说我需要一个递增(非主)和一个主键,但是当我将列标记为自动递增时,Laravel 似乎正在创建第二个主键。在模型中禁用自动增量(我说的是迁移)会如何改变这种行为? 这和他问的正好相反。

以上是关于Laravel 4:如何使用迁移创建非主自动递增列?的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework 4.1 Code First - 插入非主键时自动递增字段

如何让 Laravel Migration 中的 ID 自动递增从某个数字开始

使用迁移 Laravel 5.4 更新列

在 Ruby on Rails 中自动增加非主键字段

如果我们使用自动递增的标识列和 PK,则违反 3NF

如果我们使用自动递增的标识列和PK,则违反3NF