Yii2 mysql如何在列值已经存在且应该是唯一的表中插入记录?

Yii2 mysql如何在列值已经存在且应该是唯一的表中插入记录?,mysql,yii2,Mysql,Yii2,我有一个表,比如“mytable”,它使用一个唯一的“rank”列。在创建了一些记录之后,其中秩依次为rec A(秩=0)、rec B(秩=1)、rec C(秩=2)、rec D(秩=3)、rec E(秩=4)。 我需要插入一个新记录,它将采用现有的排名,比如1,并相应地修改以下记录的排名值。 结果是:rec A(秩=0)、新rec(秩=1)、rec B(秩=2)、rec C(秩=3)、rec D(秩=4)、rec E(秩=5) 我该怎么做?这只能用mysql来解决吗?还是我应该用PHP(Yii

我有一个表,比如“mytable”,它使用一个唯一的“rank”列。在创建了一些记录之后,其中秩依次为rec A(秩=0)、rec B(秩=1)、rec C(秩=2)、rec D(秩=3)、rec E(秩=4)。 我需要插入一个新记录,它将采用现有的排名,比如1,并相应地修改以下记录的排名值。 结果是:rec A(秩=0)、新rec(秩=1)、rec B(秩=2)、rec C(秩=3)、rec D(秩=4)、rec E(秩=5)


我该怎么做?这只能用mysql来解决吗?还是我应该用PHP(Yii2)编写一些重要的代码呢?

如果不跳过任何列组,则需要在保存新记录之前移动现有列组。为此,您可以使用
ActiveRecord
beforeSave()
方法,如下所示:

类MyModel扩展\yii\db\ActiveRecord
{
保存之前的公共函数($insert)
{
如果(!parent::beforeSave($insert)){
返回false;
}
如果($insert){//仅当我们正在保存新记录时
{
$query=self::find()
->其中(['rank'=>$this->rank]);
如果($query->exists()){//检查列组是否已存在于数据库中
//我们将直接创建查询,因为yii2
//不支持按订单进行更新
$command=static::getDb()->createCommand(
“UPDATE”.static::tableName()。
“设置秩=秩+1,其中秩>=:按秩描述排序”,
[':排名'=>$this->rank]
);
$command->execute();
}
}
返回true;
}
//…模型的其他内容。。。
}
MySQL允许在
UPDATE
查询中使用
orderby
,这将帮助我们处理这样一个事实,即在表上执行
UPDATE
不是原子的,并且在每行更新后检查
UNIQUE
约束

如果存在跳过的列组,问题会更大。在这种情况下,您只需要移动列组,直到您到达第一个跳过的列组

另一个选项可能是在表上创建一个before insert触发器,该触发器将执行秩转移

注意:

在删除某些记录时,最好也实现
afterDelete
方法,以沿oposite方向移动列组,以避免跳过列组

资源:

  • -替换为直接更新

如果列组存在,则它不能是数据库中唯一的列…我不明白为什么此列必须是唯一的谢谢。我猜是这样的,但我不知道updateAllCounters函数。我将尝试一下。尝试成功,但我必须删除表中colunm列组的唯一性。否则,updateAllCounter由于重复,尝试增加秩的第一个值时失败。例如,3必须变成4,但4已经存在。嗯,我一直认为mysql中的查询是原子的,我想不是。但我找到了其他方法,我会更新我的答案。@meaulnes我已经用
update
使用
ORDER BY
应该能够处理
UNIQUE
索引如果您使用秩对记录进行简单排序,为什么不使用时间戳呢?如果您确实想使用您正在使用的方法,可以插入具有下一个序列号(max+1)的新记录,然后呈现为(max-rank)这将创建您正在寻找的订单。