【问题标题】:MySQL table structure for task manager app with task dependencies具有任务依赖关系的任务管理器应用程序的 MySQL 表结构
【发布时间】:2013-09-19 08:53:19
【问题描述】:

我需要设计一个“任务管理器”表结构,其中任务可以依赖于其他任务。例如我可以有以下任务:

TASK A: independent
TASK B: independent
TASK C: can not start before TASK B is finished
TASK D: independenet
TESK E: can not start before TASK C and TASK E are finished

每个任务都有标准属性(started_by、assigned_to、due_date、description、status)。我想要一个可以让我轻松完成此查询的表结构:

  1. 选择所有用户打开的任务,但只选择那些已经可以启动的(意思是上面场景中的任务C和E在依赖任务完成之前不能在这里选择)。

目前我的解决方案是有 2 个表:

  • tasks:保存任务记录的表
  • task_dependencies:保存任务到任务依赖关系的表(id、task_id、dependent_task_id)

我对上述场景的当前查询和我当前的表结构是这样的:

SELECT description, from_unixtime( date_due )
FROM tasks
WHERE 
   assigned_user_id = 751
  AND status_id = 'Q'
  AND id NOT
  IN (
    SELECT TD.task_id
    FROM task_dependencies TD
    INNER JOIN tasks T ON TD.dependent_task_id = T.id
    AND T.status_id = 'Q') 
  ORDER BY date_due

  -- status 'Q' = new uncompleted task

这让我得到了正确的结果,但这是正确的方法还是我应该做出更好的表结构和/或查询?

上面的场景也是SQL fiddle

【问题讨论】:

    标签: mysql sql database-design


    【解决方案1】:

    不知道为什么这么长时间都没有得到答复。您的建议绝对是正确的方法 - taskstask_dependencies。它已经正确规范化,允许您在一个查询中选择所需的信息,并在正确的列上建立索引。

    小建议:

    • 查询没有错,但最好避免使用 all-dep-task-selecting 子查询并将其表示为:

      SELECT T.description, from_unixtime( T.date_due )
      FROM tasks T
      LEFT JOIN task_dependencies TD
        ON TD.task_id = T.id
      LEFT JOIN tasks T2
        ON T2.task_id = TD.dependent_task_id
      WHERE
        T.assigned_user_id = 751
        AND T.status_id = 'Q'
        AND (T2.status_id != 'Q' OR T2.status_id IS NULL)
      ORDER BY T.date_due
      

      应该优化得更好。 (我假设我的查询中有一些错误,无法 sqlfiddle 测试它。但你明白了。)

    • task_dependencies 表不需要单独的 PK。你可以做的是对task_iddep_task_id 进行复杂的PK。尽管拥有单独的 PK 并将 task_id+dep_task_id 作为唯一密钥被认为是一种很好的做法。

    【讨论】:

    • 我根据上面的问题实现了一个解决方案,并稍作调整。我会看看你的建议。感谢您提出这个问题。
    猜你喜欢
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2020-05-10
    • 2016-06-27
    • 1970-01-01
    • 2017-10-29
    相关资源
    最近更新 更多