V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
workwonder
V2EX  ›  数据库

如何高效的存储手工排序

  •  
  •   workwonder · 2017-10-23 18:33:57 +08:00 via Android · 1698 次点击
    这是一个创建于 2613 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如有两个实体,Project 和 Task,一个 project 对应多个 tasks。
    现在要求能够通过 UI 拖动实现单个 project 下的 tasks 自定义排序。
    我看通用的做法是在 task 上加排序字段,但这样的话每次拖动都可能导致所有相关的 tasks 重写,拖来拖去容易导致写风暴。

    请教下有没有更有效的实现方案?
    12 条回复    2017-10-23 20:09:23 +08:00
    noNOno
        1
    noNOno  
       2017-10-23 18:59:17 +08:00
    允许延迟写么,先把排序放临时表,然后延迟更新到控制表中.这样可以控制一定时间内频繁拖动只有最后一次写入
    workwonder
        2
    workwonder  
    OP
       2017-10-23 19:07:30 +08:00
    @noNOno 你这种方案需要额外引入异步调度任务
    lizon
        3
    lizon  
       2017-10-23 19:08:31 +08:00
    写风暴是啥?
    你拖动的时候不是在内存读写吗
    workwonder
        4
    workwonder  
    OP
       2017-10-23 19:12:00 +08:00
    @lizon 我的意思是拖动实时生效,一次拖动,需要改 N 个 task 的 position 字段。同时一个 project 是多人管理的,如果有好几个人拖来拖去,那写操作就比较夸张了。
    noNOno
        5
    noNOno  
       2017-10-23 19:12:01 +08:00
    @workwonder 是的,只能想到这个.频繁写的情况考虑用列式存储库(redis)么.
    workwonder
        6
    workwonder  
    OP
       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
        7
    ZnZt  
       2017-10-23 19:31:21 +08:00   ❤️ 1
    workwonder
        8
    workwonder  
    OP
       2017-10-23 19:43:34 +08:00
    @ZnZt 多谢老搭档,其实我的业务实体不是 Project+Task,看来这两个关键词好搜索。
    workwonder
        9
    workwonder  
    OP
       2017-10-23 19:58:03 +08:00
    @ZnZt 拖动到目标位置后把 position 设置为前后之和取平均的方法确实也考虑了并实施了,但正如大家都提到的,很快就会消耗完所有能够表达的数字(哪怕支持小数),而且我当时把没有搞那么的的步长,很快就觉得这种机制不靠谱。

    文中提到可以在闲时再重拍,避免数字被消耗光,我觉得靠谱。准备再考虑下这种方案。
    ZnZt
        10
    ZnZt  
       2017-10-23 20:00:55 +08:00
    @workwonder 嗯, 真实场景校验过的方案, 应该没啥问题
    ZnZt
        11
    ZnZt  
       2017-10-23 20:03:58 +08:00
    @workwonder 现在写前端,写 Python/Django, 感觉是在走你老路啊。不知道还能走多久 =。=
    workwonder
        12
    workwonder  
    OP
       2017-10-23 20:09:23 +08:00
    @ZnZt 我现在写 Flask+ArangoDB
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3441 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 00:43 · PVG 08:43 · LAX 16:43 · JFK 19:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.