5

タスクが他のタスクに依存できる「タスクマネージャー」テーブル構造を設計する必要があります。たとえば、次のタスクを実行できます。

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 フィドルもあります。

4

1 に答える 1

3

なぜこれが長い間答えられなかったのか分かりません。あなたが提案したことは絶対に正しい方法です-tasksそしてtask_dependencies. すでに適切に正規化されており、正しい列にインデックスが付けられた 1 つのクエリで必要な情報を選択できます。

マイナーな提案:

  • クエリは間違っていませんが、おそらく 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_dependenciesPK は必要ありません。task_id代わりにできることは、との複雑な PK を持つことですdep_task_id。個別の PK を用意task_id+dep_task_idし、一意のキーとして配置することをお勧めします。

于 2014-05-06T05:57:11.720 に答える