如何高效的存储手工排序

2017-10-23 18:33:57 +08:00
 workwonder
比如有两个实体,Project 和 Task,一个 project 对应多个 tasks。
现在要求能够通过 UI 拖动实现单个 project 下的 tasks 自定义排序。
我看通用的做法是在 task 上加排序字段,但这样的话每次拖动都可能导致所有相关的 tasks 重写,拖来拖去容易导致写风暴。

请教下有没有更有效的实现方案?
1679 次点击
所在节点    数据库
12 条回复
noNOno
2017-10-23 18:59:17 +08:00
允许延迟写么,先把排序放临时表,然后延迟更新到控制表中.这样可以控制一定时间内频繁拖动只有最后一次写入
workwonder
2017-10-23 19:07:30 +08:00
@noNOno 你这种方案需要额外引入异步调度任务
lizon
2017-10-23 19:08:31 +08:00
写风暴是啥?
你拖动的时候不是在内存读写吗
workwonder
2017-10-23 19:12:00 +08:00
@lizon 我的意思是拖动实时生效,一次拖动,需要改 N 个 task 的 position 字段。同时一个 project 是多人管理的,如果有好几个人拖来拖去,那写操作就比较夸张了。
noNOno
2017-10-23 19:12:01 +08:00
@workwonder 是的,只能想到这个.频繁写的情况考虑用列式存储库(redis)么.
workwonder
2017-10-23 19:18:50 +08:00
@noNOno 暂时往简单的方向做,尽量兼顾性能。

我还有个方案是在 Project 上添加一个数组字段( Project.tasks_order, e.g. ['t001', 't002', 't003']),用来保存 tasks 的顺序,这样每次拖动都只用改单个 project 的 tasks_order 属性。这种方法在存储上比较冗余( Task 上面已经有了到 Project 的外键),同时如果想按 tasks_order 的顺序读取出来,还无法利用数据库做到,需要额外在程序中排序。总之感觉这种方案怪怪的。
ZnZt
2017-10-23 19:31:21 +08:00
workwonder
2017-10-23 19:43:34 +08:00
@ZnZt 多谢老搭档,其实我的业务实体不是 Project+Task,看来这两个关键词好搜索。
workwonder
2017-10-23 19:58:03 +08:00
@ZnZt 拖动到目标位置后把 position 设置为前后之和取平均的方法确实也考虑了并实施了,但正如大家都提到的,很快就会消耗完所有能够表达的数字(哪怕支持小数),而且我当时把没有搞那么的的步长,很快就觉得这种机制不靠谱。

文中提到可以在闲时再重拍,避免数字被消耗光,我觉得靠谱。准备再考虑下这种方案。
ZnZt
2017-10-23 20:00:55 +08:00
@workwonder 嗯, 真实场景校验过的方案, 应该没啥问题
ZnZt
2017-10-23 20:03:58 +08:00
@workwonder 现在写前端,写 Python/Django, 感觉是在走你老路啊。不知道还能走多久 =。=
workwonder
2017-10-23 20:09:23 +08:00
@ZnZt 我现在写 Flask+ArangoDB

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/400011

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX