上下文:
我有一个 SQLite 数据库,其表如下所示:
CREATE TABLE items (item TEXT, position INTEGER)
该表包含数百万个条目。该列position
已编入索引。
我的前端偶尔会构建一堆更新以应用于该position
列。要更新的行不是由它们的 id 标识的,因为更新可以在广泛的项目上,并且列出所有相关的 id 可能非常昂贵。例如,可以更新操作,例如“将 +10 添加到位置 >= 500 & 位置 <= 10000” - “添加 -3 到位置 >= 100000 & 位置 <= 100003”等。
问题: 一束更新的条件位置,都是基于一束更新前的位置值。如果我按顺序执行捆绑更新的每个更新操作,那么在一次更新之后可能(实际上存在)一个“重叠”问题。
举例:
item | position
it1 | 1
it2 | 2
it3 | 3
it4 | 4
it5 | 5
it6 | 6
it7 | 7
如果我有这一系列更新:“添加 + 2 到位置 >= 5 和位置 <= 6” - “添加 - 2 到位置 >= 3 和位置 <= 4”,然后我将其转换为这个 SQLite 查询:
UPDATE items SET position=position-2 WHERE position >= 5 AND position <= 6
UPDATE items SET position=position+2 WHERE position >= 3 AND position <= 4
我会得到这个结果:
it1 | 1
it2 | 2
it3 | 5
it4 | 6
it5 | 5
it6 | 6
it7 | 7
这不是我想要的,而是说:
it1 | 1 { it1 | 1 }
it2 | 2 { it2 | 2 }
it3 | 5 { it5 | 3 }
it4 | 6 ===> { it6 | 4 }
it5 | 3 { it3 | 5 }
it6 | 4 { it4 | 6 }
it7 | 7 { it7 | 7 }
这是因为从一项操作到另一项操作的“重叠”。
我的第一个想法是像这样使用 CASE :
UPDATE items SET position=CASE WHEN position >= 5 AND position <= 6 THEN position-2 WHEN position >= 3 AND position <= 4 THEN position+2 ELSE position END
该解决方案工作正常,但速度非常慢,因为 SQLite 似乎在我的表的数百万个条目上执行此操作,即使主要方不关心更新。
所以我这样修改:
UPDATE items SET position=CASE WHEN position >= 5 AND position <= 6 THEN position-2 WHEN position >= 3 AND position <= 4 THEN position+2 ELSE position END WHERE (position >= 5 AND position <= 6) OR (position >= 3 AND position <= 4)
这个解决方案工作正常而且速度非常快,因为 SQLite 只在相关行上执行更新。
问题: 由于我可以在一组更新中执行 10 甚至 100 次更新操作,因此查询可能会变得非常大,这看起来不太……“漂亮”/“漂亮”。
你认为有一个更漂亮的方法来处理这个吗?SQLite 能否通过第一次选择受影响的行来执行一些“更新”查询,然后在之后有效地更新该行?
想法?想法 ?
非常感谢 !