使用唯一列更新表

时间:2018-03-28 15:41:50

标签: php mysql unique-constraint reorderlist

一个表包含以下数据,正在使用INNODB,在UNIQUE上有一个position/fk约束,并且NULL不允许position +----+----------+-----+ | id | position | fk | +----+----------+-----+ | 1 | 1 | 123 | | 2 | 2 | 123 | | 3 | 3 | 123 | | 4 | 4 | 123 | | 5 | 5 | 123 | | 6 | 6 | 123 | | 7 | 7 | 123 | | 8 | 8 | 123 | | 9 | 9 | 123 | | 10 | 10 | 123 | +----+----------+-----+ }。

[2,1,4,3,6,5,8,7,10,9]

PHP收到将表更新为以下内容的请求。可以提供最方便的请求格式,例如[{"id":1, "position":2}, ... ]+----+----------+-----+ | id | position | fk | +----+----------+-----+ | 1 | 2 | 123 | | 2 | 1 | 123 | | 3 | 4 | 123 | | 4 | 3 | 123 | | 5 | 6 | 123 | | 6 | 5 | 123 | | 7 | 8 | 123 | | 8 | 7 | 123 | | 9 | 10 | 123 | | 10 | 9 | 123 | +----+----------+-----+ 等。

SET unique_checks=0;

我已确认NULL不允许临时禁用唯一检查,并且不希望实际删除唯一索引,更新表并重新应用唯一索引。< / p>

如何更新此表?

如果没有简单的方法,我想到了几个选项,但不喜欢它们:

  1. position中允许NULL。有没有办法暂时允许SET FOREIGN_KEY_CHECKS=0;类似于public class Driver { public static void main (String[] args) { MainShop shop= new MainShop ("Welcome to my Shop"); } } 如何禁用外键?
  2. 首先删除所有记录,然后重新插入。这可能会导致性能问题,因为表上有索引需要重新创建。

1 个答案:

答案 0 :(得分:2)

我能想到的是,您需要先将所有位置更改为其他值,这些值不在您最终需要设置的新位置值范围内,但在行内仍然是唯一的。

假设您的位置列是有符号整数,一种简单的方法是将所有位置设置为相反(负)值。它们将保持独特,但它们不会属于新值的集合。

您可以在事务中执行此操作以及后续更新,因此任何其他并发事务都不会看到负值。

BEGIN;
UPDATE MyTable SET position = -position;
UPDATE MyTable SET position = 2 WHERE id = 1;
...etc... 
COMMIT;

这是一个黑客。整数的符号位用于除显示负数之外的其他目的。