什么是在SQL中存储记录顺序的最佳方法

时间:2010-09-28 14:19:15

标签: sql

我有一张用户个人资料表。每个用户都可以拥有多个配置文件,并且用户可以排列它们在网格中的显示顺序。

有2个表用户和个人资料(1:M)

我在Users表中添加了orderby列,其中的值为1,2,3 ..

到目前为止似乎还可以。但是当用户将最后一条记录的顺序更改为第一条记录时,我必须完成所有记录并将其值增加+1。这在我看来非常难看。

对于这种情况,有没有更方便的解决方案?

7 个答案:

答案 0 :(得分:9)

在序列中留下间隙或使用小数而不是整数数据类型。

答案 1 :(得分:4)

如何按列使用浮点数? 这样,您可以随时在两个其他人之间挤压配置文件,而无需更改这两个值。 例如,如果我想在配置文件B(ordervalue 1)和C(ordervalue 2)之间放置配置文件A,我可以将ordervalue 1.5分配给A. 要将它放在顶部,在顶部曾经有ordervalue为1之前,你可以使用ordervalue 0.5

没有理由为orderby设置整数,没有理由在配置文件的顺序之间增加1。

答案 2 :(得分:3)

最佳解决方案是镜像功能,这是一个简单的整数列表。按顺序保存列表只是一些SQL语句,比其他建议的解决方案更容易理解(浮点数,有缺口的整数)。

如果您的列表非常大(数万个),那么性能考虑因素可能会起作用,但我认为这些列表并不长。

答案 3 :(得分:2)

当用户添加配置文件时,将每个新配置文件的订购号设置为前一个+1000000。例如首先:

p1   1000000
p2   2000000
p3   3000000

重新排序时,将配置文件的顺序设置为它们之间的两个中间位置:

p1   1000000
p2   2000000
p3   1500000

这给出了阶数p1,p3,p2

答案 4 :(得分:2)

如果数据集很小(似乎是这种情况),我宁愿使用正常的整数列表,并在配置文件获得新位置时批量更新它们。这更好地反映了应用程序的功能。

在Sql Server中,对于下表User_Profiles (user_id, profile_id, position),我会有这样的事情:

--# The variables are: 
--#   @user_id - id of the user
--#   @profile_id - id of the profile to change
--#   @new_position - new position that the profile will take
--#   @old_position - current position of the profile 

select @old_position = position 
from User_Profiles where 
user_id = @user_id and profile_id = @profile_id

update p set position = pp.new_position
from User_Profiles p join (
  select user_id, profile_id,
    case 
    when position = @old_position then @new_position 
    when @new_position > @old_position then --# move up
      case 
      when @old_position < position and 
           position <= @new_position 
      then position - 1
      else position
      end
    when @new_position < @old_position then --# move down
      case 
      when position < @old_position and 
           @new_position <= position 
      then position + 1
      else position
      end
    else position --# the same
    end as new_position
  from User_Profiles p where user_id = @user_id
) as pp on 
p.user_id = pp.user_id and p.profile_id = pp.profile_id

答案 5 :(得分:1)

我认为在订单之间留下空白的想法很有意思,但我不知道它是否是解决问题的“更方便”的解决方案。

我认为您最好只更新order by列。因为您仍然需要确定状态在哪些行之间移动,以及如果两个状态切换到位,该怎么办(您是按第一个计算新订单的值,还是第二个计算新订单)。如果两者之间的差距不够大会怎么样?

这不应该是数据密集,只是列举他们放入的顺序并将每条记录更新到订单。

答案 6 :(得分:0)

我认为您可以在orderby列中保留订单,而不是在您的设计中引入链接列表概念。添加像nextId这样的列,它将包含链中的下一个配置文件。 当您查询profiles表时,您可以在代码中对类型进行排序(java,C#等)