启用softDeletes时如何定义唯一索引

时间:2014-04-27 12:10:02

标签: sql laravel laravel-4

当softDeletes时,Laravel 4.1会自行管理唯一索引(其中deleted_at = null)的创建吗?

以下方法是否正确?或者是否会混合已删除的记录?

Schema::create('example', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('example')->unsigned()->unique(); //?????
    $table->softDeletes();
});

数据库是mysql,但如果有其他DB的某些解决方案,你也可以提供它们。但是,它应该在laravel框架内完成!与laravel官方支持的所有dbs一起使用的统一解决方案值得赞赏。

更新 看起来这种方法不起作用,因为它只是忽略了softDeletes()选项。

所提议的解决方案

Schema::create('exampe', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('example')->unsigned();
    $table->softDeletes();
    $table->unique('example', 'deleted_at');
});

问题是在deleted_at列中可能存在两个完全相似的时间戳。

我真正需要的是一个条件。

$table->unique('example', array('where', 'deleted_at', '=', null));

$table->integer('example')->unsigned()->unique()->where('deleted_at', '=', null)

3 个答案:

答案 0 :(得分:1)

使用$table->softDeletes()不会更改Schema设置unique索引的方式。在您的示例中,只有example列是唯一的。

如果您希望unique索引中有多列,只需运行$table->unique(['column1', 'column2'])

要设置unique索引,您可以在链上使用它,例如$table->integer('example')->unique()或将其放在新行上,就像我上面写的那样。

答案 1 :(得分:0)

我有同样的问题。使用2列作为唯一列,在软删除后,我无法创建具有相同唯一数据的另一行。 我想要的是使用Blueprint表对象实现(不是RAW查询)那个SQL:

CREATE UNIQUE INDEX test ON test_table USING btree (test_id, user_id) WHERE deleted_at IS NULL;

但Blueprint和Fluent对象没有任何where方法。

答案 2 :(得分:0)

我建议对你想要唯一的列(example)和一个名为is_live的虚拟列进行双列UNIQUE约束。当行软删除时,此列始终为“1”。当您软删除行时,请设置is_live=NULL

原因与“唯一性”的定义方式有关。 唯一约束允许任意数量的具有NULL值的行。这是因为在SQL中NULL不等于NULL,因此两个NULL计为“不相同”。

对于多列唯一键,如果任何列为NULL,则唯一键中的整个列行为就好像它与任何其他行不同。因此,只要唯一键中的另一列为NULL,您就可以拥有任意数量的唯一键的一列相同的行。

create table example (
  id serial primary key,
  example int unsigned not null,
  is_live tinyint default 1,
  unique key (example, is_live)
);

演示:http://sqlfiddle.com/#!9/8d1e4d/1

PS:关于在MySQL中实现索引条件的问题的直接答案是MySQL不支持这一点。支持部分索引的数据库包括: