正在使用唯一列更新 table
Updating table with unique column
A table 包含以下数据,正在使用 INNODB
,对 position/fk
有 UNIQUE
约束,并且不允许 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 |
+----+----------+-----+
PHP 收到将 table 更新为以下内容的请求。可以提供最方便的请求格式,例如 [2,1,4,3,6,5,8,7,10,9]
或 [{"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;
不允许暂时禁用唯一检查,并且不希望实际删除唯一索引,更新 table,然后重新应用唯一索引.
如何更新这个table?
如果没有简单的方法,我想到了几个选项,但不喜欢它们:
- 允许
NULL
在 position
中。有没有办法暂时允许 NULL
类似于 SET FOREIGN_KEY_CHECKS=0;
可以禁用外键?
- 先删除所有记录,再重新插入。这可能会导致性能问题,因为 table 上有需要重新创建的索引。
我能想到的是,您需要首先将所有位置更改为一些其他值,这些值不在您最终需要设置的新位置值的范围内,但在行中仍然是唯一的。
假设您的头寸列是有符号整数,一种简单的方法是将所有头寸设置为相反(负)值。它们将保持唯一性,但不会出现在新值的集合中。
您可以在一个事务中执行此操作以及您的后续更新,因此其他并发事务将永远不会看到负值。
BEGIN;
UPDATE MyTable SET position = -position;
UPDATE MyTable SET position = 2 WHERE id = 1;
...etc...
COMMIT;
这是一个技巧。整数的符号位用于显示负数以外的目的。
A table 包含以下数据,正在使用 INNODB
,对 position/fk
有 UNIQUE
约束,并且不允许 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 |
+----+----------+-----+
PHP 收到将 table 更新为以下内容的请求。可以提供最方便的请求格式,例如 [2,1,4,3,6,5,8,7,10,9]
或 [{"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;
不允许暂时禁用唯一检查,并且不希望实际删除唯一索引,更新 table,然后重新应用唯一索引.
如何更新这个table?
如果没有简单的方法,我想到了几个选项,但不喜欢它们:
- 允许
NULL
在position
中。有没有办法暂时允许NULL
类似于SET FOREIGN_KEY_CHECKS=0;
可以禁用外键? - 先删除所有记录,再重新插入。这可能会导致性能问题,因为 table 上有需要重新创建的索引。
我能想到的是,您需要首先将所有位置更改为一些其他值,这些值不在您最终需要设置的新位置值的范围内,但在行中仍然是唯一的。
假设您的头寸列是有符号整数,一种简单的方法是将所有头寸设置为相反(负)值。它们将保持唯一性,但不会出现在新值的集合中。
您可以在一个事务中执行此操作以及您的后续更新,因此其他并发事务将永远不会看到负值。
BEGIN;
UPDATE MyTable SET position = -position;
UPDATE MyTable SET position = 2 WHERE id = 1;
...etc...
COMMIT;
这是一个技巧。整数的符号位用于显示负数以外的目的。