如何实现对商品列表的排序?

如图所示,前端的界面是这样的,需求是:前端通过拖动商品完成对商品的排序。前端是有分页的,第二页的商品也可以拖动到第一页进行排序。
现在数据库中有sort字段,字段全部为0。目前商品列表是按照时间倒序排序的。
那么接口的排序算法应该如何设计?如果采用最小的代价去实现排序,同时尽量不去在添加和修改商品处做改动。
image.png

阅读 4.4k
4 个回答

按照已有顺序更新 sort 列,并且给一个较大的间隙,比如每个产品之间的间隔为 1000,这就是原始间隙。

set @sort := 0;
update product set sort=(@sort:= @sort+1000) order by id

每次当拖动排序产品到新位置时,计算新位置前后两个 sort 的中间值,然后作为新位置的 sort 值。

idsort
11000
22000
33000

3 拖动到 12 中间,那就把 3 的排序值改为 1000+(2000-1000)/2=1500,也可以加点儿随机数,让其不那么均匀。

idsort
11000
31500
22000

每次拖动时都这样,当然,拖动次数多了以后,就还是可能会出现,无法再继续分了,这时候就可以又根据当前的顺序,去重排间隙。

set @sort := 0;
update product set sort=(@sort:= @sort+1000) order by sort

大概就是这样吧

这样说我就理解你的问题了,这个问题其实不难,其实把数组转变成链表就可以了。

起始的状态如下,sort 里面放的是链表下一环的 id

idnamesort
1xx2
2xx3
3xx4
4xx5
5xx0

当你把 4 拖到 2 前面的时候,变成如下状态

idnamesort
1xx4
2xx3
3xx5
4xx2
5xx0

每次拖动的时候只需要修改:

  1. 原来指向自己的条目 (这里是 3,把 4 改成 5)
  2. 将要指向自己的条目 (这里是 1,把 2 改成 4)
  3. 自己将要指向的条目 (这里是 4,把 5 改成 2)

每次拖动只需要改动3条数据。
排序的时候,最好有个额外的地方记录第一个条的 id,这样不停的 next 就可以了,不记录也可以,但处理起来可能会麻烦一点。

考虑使用场景,我认为采用数组调整顺序修改下标那样,批量修改排序即可
原因:
1、这种使用场景下,用户拖动的范围不会很大,几十个了不起,就算几百个,后端批量更新几百条数据的排序字段也并非不可接受的性能损耗,每次批量更新,事务管理,失败还是成功,也不会导致额外的影响
2、采用比如一楼的方法,确实是一种巧妙的解决方案,但是本身引入了其他额外的复杂处理,代码上变复杂,逻辑上也变复杂,并不易于维护以及可能引入新的问题

当然要根据具体的业务场景考虑,用户量不大,修改不会很频繁的场景下,我认为采用这种简单直接的方式更加合理

sort字段修改成double类型
sort 按顺序1,2,3,4,5排序
每换一次顺序,将前后两者的除以2的结果作为新的sort
image.png
考虑到精度的问题,这个方案是存在问题的


还有一种方法

sort字段还是按照1,2,3...排序
前端能判断出用户移动商品的跨页数的话,比如从第五页移动到第一页
那么就把前五页的商品数据全部传递给后端,后端按照前端传递商品数据的顺序,生成sort顺序
这样只需要修改前五页的数据,批量修改有可能会遇到唯一索引的问题(我遇到过,场景不仔细描述),可以删除前五页的数据,再新建前五页的数据(简单粗暴)

极限情况:用户把最后一页的商品拖拽到第一页,那么就需要修改全部数据
处理方式:可以对用户的拖拽商品移动的页数进行限制

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏