データベースに保存されているタスクの優先リスト


10

私は次のことをするための最良の方法を考えています:

データベースに保存されているタスクのリストがあります。タスクには優先度が割り当てられています。タスクの優先度を変更して、実行する順序を並べ替えることができます。

Pivotal Trackerに非常によく似たものを考えています。

次のように想像してください。

1 Task A
2 Task B
3 Task C
4 Task D
5 Task E

Eが最も重要なタスクであると判断します

1 Task E
2 Task A
3 Task B
4 Task C
5 Task D

5つのタスクすべてを更新して、新しい優先順位を付ける必要があります。

タスクBがより重要になると、AIは

1 Task E
2 Task B
3 Task A
4 Task C
5 Task D

タスクBとAのみを更新する必要があります。

これをDBで構造化するにはどうすればよいですか?同じテーブルに異なるプロジェクトが格納されており、独自の重みがあると思います。

その後に実行されるタスクを指す方がよいでしょうか(リンクリストのように)。

これは本当に頭痛の種です。このようなものを実装するにはどうすればいいのかと思っていました。

回答:


5
  1. 優先キューを探しているようです。おそらく、タスクの優先順位の数値を再計算するべきではなく、それらの固定値を計算するだけです。タスクEをより重要にしたい場合は、その値を減らします。
  2. あなたは本質的に関係について話している。BはAよりも重要です。Eは最も重要なタスクなどである必要があります。ツリー構造のように聞こえ、親リンクを使用してRDBMSに格納できます。

4

倍精度浮動小数点数を使用して優先順位を示す場合、順序を変更する必要はありません。

1.00 Task A
2.00 Task B
3.00 Task C
4.00 Task D
5.00 Task E

タスクEをAとBの間に配置する場合:-

  E.priority = B.priority + ((B.priority - A.priority) / 2)

だから今あなたは持っています:

1.00 Task A
1.50 Task E
2.00 Task B
3.00 Task C
4.00 Task D

EとBの間にDを挿入する場合は、優先度を1.75に設定します。浮動小数点数の約18桁の10進数字(1.75は実際には1.7500000000000000)を考えると、最悪の場合、前に53の連続した挿入があるはずです。

 B.priority + ((B.priority - A.priority) / 2) = B.priority

そして、誰かがdoubleとintegerを使用するオーバーヘッドについて不満を言う前に、データベース内のリストを並べ替える処理とI / Oオーバーヘッドが数桁大きくなるのと比較して、ハードウェア命令はほんの数個です。


1
私はこのアプローチが好きですが、次のようにする必要があります:E.priority = A.priority +((B.priority-A.priority)/ 2)およびA.priority +((B.priority-A.priority)/ 2)= B.priority
Marcel

1

私たちはあなたが話しているまさにこのことをしました。これを行うには、アイテムのリストを並べ替える1つのストアドプロシージャを使用しました。リストの各アイテムには、一意のIDとソート順番号がありました。

例えば:

TaskId int identity(1,1),
Task varchar(50),
SortOrder int

アイテムを並べ替えたストアドプロシージャは、2つの入力パラメーターを取ります。

@TaskId int,
@NewSortOrder int

一時テーブルを使用して、アイテムを新しい順序で格納しました。

CREATE TABLE #Tasks
(
RowId int identity(1,1),
TaskId int
)

3つのselectステートメントを使用して、それらを新しい順序にしました。

-- Step 1
INSERT INTO #Tasks
SELECT TaskId FROM tblTasks
WHERE SortOrder < @NewSortOrder
ORDER BY SortOrder

--Step 2
INSERT INTO #Tasks
VALUES(@TaskId)

--Step 3
INSERT INTO #Tasks
SELECT TaskId FROM tblTasks
WHERE SortOrder >= @NewSortOrder
ORDER BY SortOrder

次に、実際の一時テーブルのRowId ID列である新しい並べ替え順序でベーステーブル(tblTask​​s)を更新しました。

-- Update Base Table
UPDATE tblTasks
SET SortOrder = t2.RowId
FROM tblTasks t1
INNER JOIN #Tasks t2
ON t1.TaskId = t2.TaskId

これは毎回チャンピオンのように機能します。


0

私はまだこれを考えていません.....しかし、小数を許可して、すべてを更新せずに他のものの間で詰め込むことができるのはなぜですか?

1.5の値で1と2の間の何かを圧縮することができます。

また、最小値と最大値も避けます。優先順位が現在0であるものよりも前にある場合に、数値がネガに転がることを許可します。

奇妙な小数や負の値が表示されないようにするには、内部の「順序付け」優先順位とは別に「人間の表示」優先順位を設定することを検討してください。


小数を使用しないでください。数字またはアルファベットの文字列を使用します。次に、少なくとも文字列の長さの制限に達するまで、常に2つの古い値の間に新しい値を挿入できます。
ケビンクライン

0

リンクリストとその操作をRDBMSに実装することは非常に合理的です。配列と参照の操作をSQLクエリに置き換えるだけです。ただし、いくつかの単純な操作には多くのSQLクエリが必要になるため、これが本当に最も効率的な方法であるかどうかはわかりません

タスクテーブルの場合、外部キーである列「next_task」と「prev_task」を同じテーブルのid列に追加します(「-1」はNULLと同等であると想定)

highest_priority()でタスクを返す:prev_task = -1でタスクを返すSQLクエリ

Eは最も重要なタスクです。Eのnext_taskを最も優先度の高いタスクのIDに変更するSQLクエリ。そして、Eのprev_taskを-1に変更します...

これと、EをAの前に置く、またはタスクの順序付きリストを印刷するなどの他の操作では、さらに多くのSQLクエリが必要になります(最適化できない場合)。これは良い練習ですが、おそらく最も効率的な方法ではありません。


0

優先順位の問題に対する別のアプローチは、アイテムよりも重要なアイテムを指定することです。人事アプリケーションでは、これは従業員の上司が誰であるかを言うようなものです。

ID  Name           ParentPriority
1   TopPriority    NULL
2   Medium         1
3   Low            2
4   AnotherMedium  1
5   Less than 2    2

次に、このhttp://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/を読んで、優先順位を与えるクエリを作成しますレベル。

ID  Name           ParentPriority  PriorityLevel
1   TopPriority    NULL            1
2   Medium         1               2
3   Low            2               3
4   AnotherMedium  1               2
5   Less than 2    2               3

これは、優先度を設定する際のユーザーエクスペリエンスが単純になると思いますが、同じレベルの複数の優先度を使用できます。


-1

簡単な方法の1つは、次のようなものから始めることです。

100 Task A
200 Task B
300 Task C
400 Task D
500 Task E

次に、「タスクE」をタスクAとタスクBの間で移動するには、「タスクE」の優先度をタスクAとタスクBの中間に設定します(この場合は「150」)。

もちろん、常に優先順位を並べ替えると、最終的に、隣接する2つのタスクに新しいエントリを挿入するための「ギャップ」がないという問題が発生します。ただし、その場合は、すべての優先度を一度に「リセット」して、100、200、300などに戻すことができます。


1
これは実際には私の答えと同じですが、小数部を密にグループ化するのではなく、より大きな整数から始めます。:)
jojo

-1

私はデータベースの第一人者ではないので、これをAccess 2010でできる最も論理的な方法で解決しました。数値フィールドである「優先度」フィールドがあります。次に、このフィールドのイベントがあります。

このイベントは、フィールド "Priority"の更新後イベントであり、更新クエリ "qryPriority"をトリガーして、入力した優先順位番号以上の優先順位を持つ他のすべてのレコードの優先順位番号に1を追加します。

イベントVBコードと更新クエリSQLは次のとおりです。

「優先」イベントVBコード:

Private Sub Priority_AfterUpdate()
Me.Refresh
If Priority > 0 Then
DoCmd.OpenQuery ("qryPriority")
End If
Me.Refresh
Priority = Priority - 1
End Sub

「qryPriority」更新クエリSQL:

UPDATE YOURTABLENAME SET YOURTABLENAME.Priority = [Priority]+1
WHERE (((YOURTABLENAME.Priority)>=[Forms]![YOURFORMNAME]![Priority]));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.