【问题标题】:Composite constraint where deleted_at is NULLdeleted_at 为 NULL 的复合约束
【发布时间】:2021-09-03 09:33:50
【问题描述】:

我需要在 Laravel 中做一个复合约束,它只考虑非软删除的行。所以如果实体被删除了,deleted_atnot nulldata_1data_2data_3data_4data_5可以再次插入。

我能想到的最好的就是这个(tablecolumn 名称是在以前的迁移中定义的):

public function up()
{
    Schema::table('table_name', function (Blueprint $table) {
        $table->unique(['data_1', 'data_2', 'data_3', 'data_4', 'data_5'])
            ->whereNull('deleted_at');
    });
}

但它不起作用。即使deleted_atnot null,该约束也适用。

我一直在查看其他有类似问题的帖子,但他们的解决方案有不同的方法,与迁移无关。

【问题讨论】:

  • 你想做什么?您不能根据条件使某些列/行唯一...整个集合(data_1data_2data_3data_4data_5)将变得唯一总是...你想达到什么目的?这个基于条件的unique 约束必须在您的业务逻辑上完成。您仍然可以拥有一些数据库唯一性索引,但请解释更多。
  • 它回答了我担心的问题,但并没有解决问题。或者至少不是我的方式。我一开始尝试 (data_1, data_2, data_3, data_4, data_5, deleted_at) 是唯一的。但事实证明 NULL 在我的数据库中始终是唯一的。所以这将允许重复。我可以设置一个默认字符串 'NULL' 来避免这种情况,但也许有更优雅的解决方案
  • 唯一可能的解决方案是在 Laravel 中进行此检查(作为业务逻辑),因为正如您所说,您依赖于该行是否被软删除,因此它可以自我重复,但是对于业务逻辑,删除它是可以的,但不可以是 2 等于 deleted_at = null,那会很糟糕。所以你必须做业务逻辑来处理这个。

标签: php database laravel migration unique


【解决方案1】:

事实证明,制定约束并不是解决问题的正确方法。

唯一索引允许使列的组合唯一,并且允许条件。

在原始 sql 语句中是:

public function up()
{
    DB::statement('CREATE UNIQUE INDEX table_unique_preferredNameOfIndex ON schema.table 
        USING btree (data_1, data_2, data_3, data_4, data_5) WHERE (deleted_at IS NULL)');
}

不完全一样,但它可以完成工作。

如果需要回滚,只需删除索引:

public function down()
{
    DB::statement('DROP INDEX schema.table_unique_preferredNameOfIndex');
}

【讨论】:

    猜你喜欢
    • 2022-12-17
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 2011-04-19
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多