Php 使用唯一列更新表

Php 使用唯一列更新表,php,mysql,unique-constraint,reorderlist,Php,Mysql,Unique Constraint,Reorderlist,表包含以下数据,正在使用INNODB,对位置/fk具有唯一的约束,并且不允许位置为空 +----+----------+-----+ | id | position | fk | +----+----------+-----+ | 1 | 1 | 123 | | 2 | 2 | 123 | | 3 | 3 | 123 | | 4 | 4 | 123 | | 5 | 5 | 123 | | 6 | 6

表包含以下数据,正在使用
INNODB
,对
位置/fk
具有
唯一的
约束,并且不允许
位置

+----+----------+-----+
| 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 |
+----+----------+-----+
PHP收到将表更新为以下内容的请求。可以以最方便的方式提供请求的格式,例如
[2,1,4,3,6,5,8,7,10,9]
[{“id”:1,“position”:2},…][/code>等

+----+----------+-----+
| 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\u checks=0
不允许临时禁用唯一性检查,并且不希望实际删除唯一性索引、更新表和重新应用唯一性索引

如何更新此表

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

  • 位置允许
    NULL
    。是否有一种临时允许
    NULL
    的方法,类似于
    设置外键检查=0可以禁用外键吗
  • 首先删除所有记录,然后重新插入。这可能会导致性能问题,因为表上存在需要重新创建的索引

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

    一个简单的方法是,假设您的位置列是一个有符号整数,将所有位置设置为它们的相反(负)值。它们将保持唯一性,但不在新值集中

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

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

    这是一个黑客。整数的符号位用于显示负数以外的用途

    谢谢Bill,我已经看到其他答案建议不要保留从0开始的职位列表,但我不希望采用这种方式,因为我正在使用
    TINYINT
    ,并且没有很大的
    INT
    范围可供使用。是的,带符号的值是完全可以接受的,这非常有效。您可以临时删除唯一索引。@Barmar当您说“临时”时,是指删除它,然后在完成后创建一个新索引,还是其他什么?是的,这正是我的意思。我考虑过这样做,但担心性能,就算我没有测试过这种影响,也可能不是。我还没有检查,但expect事务还包括索引更改。