从索引

时间:2019-05-17 20:07:16

标签: mysql sql indexing mariadb

如果在两者之间添加了一些内容,我有一个查询来更新索引

update My_Table
     set NS_LEFT = NS_LEFT + 10
     where NS_THREAD = parentThread and NS_LEFT > oldRight
     order by NS_LEFT desc

工作正常-

现在,如果我必须在两次删除之间删除某些内容,那么我将使用以下查询

update My_Table
    set NS_LEFT = NS_LEFT - 10
    where NS_THREAD = parentThread and NS_LEFT > oldRight
    order by NS_LEFT desc

它不起作用并抛出重复索引错误-

  

[代码:1062,SQL状态:23000](conn = 1517)重复的条目“ 1-1110”   键“ INDEX”

索引(NS_THREAD,NS_LEFT)

如何解决删除元素

注意 这是我针对MariaDB的解决方案,仅适用于其他不支持OrderBy的其他数据库(为什么。对我来说,它仍然是一个悬而未决的问题)

2 个答案:

答案 0 :(得分:2)

我过去在控制订单时所做的选择不是执行两次更新。第一个将组向上移动超过任何当前使用的值,以确保没有冲突。然后第二个将它们转移到应有的位置。在一般形式下,可以通过以下方式说明该想法:

UPDATE aTable SET somevalue = somevalue + 10000 WHERE somevalue > x;
UPDATE aTable SET somevalue = somevalue - 10000 - y WHERE somevalue > x + 10000;

“ 10000”只是将范围推到碰撞后的值,y是您实际要移动它们的量。显然,如果已经有10000左右的值,则该数字将需要不同。为了避免查询安全值,在设计允许的情况下,还有另一种选择。...

如果未使用负值,并且表格设计允许使用负数,则此过程的版本要更简单一些:

UPDATE aTable SET somevalue = somevalue * -1 WHERE somevalue > x;
UPDATE aTable SET somevalue = (somevalue * -1) - y WHERE somevalue < 0; 

这假定通常不存在负值,并且为安全起见,应在事务内执行更新(以及原始删除),以使该解决方案的潜在并发应用程序不会冲突。 (编辑:请注意,交易/并发要求适用于我介绍的两种表格。)

编辑:哦,我刚刚注意到Gordon的回答非常相似...裸露的减号看起来像我屏幕上的斑点。如果戈登(Gordon)无法正常工作,那么也不会。

答案 1 :(得分:1)

发生了。一种解决方案是进行两次更新:

update My_Table
    set NS_LEFT = - (NS_LEFT - 10)
    where NS_THREAD = parentThread and NS_LEFT > oldRight
    order by NS_LEFT desc;

update My_Table
    set NS_LEFT = - NS_LEFT
    where NS_THREAD = parentThread and NS_LEFT < 0;