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事务还包括索引更改。