Prioritätsliste der in einer Datenbank gespeicherten Aufgaben

10

Ich versuche mir den besten Weg zu überlegen, um Folgendes zu tun:

Ich habe eine Liste von Aufgaben in der Datenbank gespeichert. Einer Aufgabe ist eine Priorität zugewiesen. Sie können die Priorität einer Aufgabe ändern, um die Reihenfolge zu ändern, in der sie ausgeführt werden soll.

Ich denke an etwas sehr Ähnliches wie Pivotal Tracker.

Stellen Sie sich vor, wir hätten Folgendes:

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

Wir entscheiden, dass E jetzt die wichtigste Aufgabe ist

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

Ich muss alle 5 Aufgaben aktualisieren, um ihnen eine neue Priorität zu geben.

Wenn Aufgabe B dann wichtiger wird als KI, hätte ich sie

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

Ich muss nur Aufgabe B und A aktualisieren.

Wie würde dies in einer DB strukturiert werden? Ich stelle mir vor, dass Sie verschiedene Projekte in derselben Tabelle haben würden, die ihr eigenes Gewicht hätten.

Wäre es besser, auf eine Aufgabe zu verweisen, die danach stattfindet (ein bisschen wie eine Linkliste).

Dies ist wirklich nur ein Brain Dump. Ich habe mich nur gefragt, wie Sie so etwas implementieren würden.

Pete
quelle

Antworten:

5
  1. Es sieht so aus, als würden Sie nach einer Prioritätswarteschlange suchen. Sie sollten Prioritätsnummern für Aufgaben wahrscheinlich nicht neu berechnen, sondern nur einen festen Wert für sie berechnen. Wenn Sie möchten, dass Aufgabe E wichtiger ist, verringern Sie den Wert.
  2. Sie sprechen im Wesentlichen über Beziehungen. B sollte wichtiger sein als A. E sollte die wichtigste Aufgabe sein usw. Es klingt wie eine Baumstruktur, und Sie können diese in einem RDBMS mit übergeordneten Links speichern.
Karoly Horvath
quelle
4

Wenn Sie doppelte Gleitkommazahlen verwenden, um die Priorität anzuzeigen, müssen Sie nicht neu anordnen:

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

Wenn Sie Aufgabe E zwischen A und B platzieren möchten, gehen Sie wie folgt vor:

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

Jetzt haben Sie also:

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

Wenn Sie D zwischen E und B einfügen möchten, setzen Sie einfach die Priorität auf 1,75. Angesichts der ungefähr 18 Dezimalstellen in einer Gleitkommazahl (1,75 ist wirklich 1,7500000000000000) sollten Sie vor 53 aufeinanderfolgenden Einfügungen den schlimmsten Fall haben:

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

Und bevor sich jemand über den Aufwand für die Verwendung von Doppel- oder Ganzzahlen beschwert, sind es nur ein paar Hardwareanweisungen, verglichen mit dem Verarbeitungs- und E / A-Aufwand für die Neuordnung der Liste in der Datenbank, der mehrere Größenordnungen größer wäre.

James Anderson
quelle
1
Ich mag diesen Ansatz, aber er sollte sein: E. Priorität = A. Priorität + ((B. Priorität - A. Priorität) / 2) und A. Priorität + ((B. Priorität - A. Priorität) / 2) = B. Priorität
Marcel Panse
1

Wir haben genau das getan, wovon Sie sprechen. Wir haben dazu eine gespeicherte Prozedur verwendet, mit der die Liste der Elemente neu angeordnet wurde. Jeder Artikel in der Liste hatte eine eindeutige ID und eine Sortierreihenfolge.

Zum Beispiel:

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

Die gespeicherte Prozedur, die die Elemente neu anordnet, benötigt zwei Eingabeparameter:

@TaskId int,
@NewSortOrder int

Wir haben eine temporäre Tabelle verwendet, um die Artikel in der neuen Reihenfolge zu speichern:

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

Wir haben drei select-Anweisungen verwendet, um sie in die neue Reihenfolge zu bringen:

-- 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

Anschließend haben wir die Basistabelle (tblTasks) mit der neuen Sortierreihenfolge aktualisiert, die eigentlich die RowId- Identitätsspalte der temporären Tabelle ist:

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

Dies funktioniert jedes Mal wie ein Champion.

Michael Riley - AKA Gunny
quelle
0

Ich habe das noch nicht durchdacht ..... Aber warum nicht einfach Dezimalstellen zulassen, damit Sie Dinge zwischen andere stopfen können, ohne alles zu aktualisieren?

Sie könnten etwas zwischen 1 und 2 mit dem Wert 1,5 zerquetschen.

Ich würde auch Min- und Max-Werte vermeiden. Lassen Sie Zahlen in die Negative rollen, wenn ihre Priorität vor der aktuellen 0 liegt.

Sie können in Betracht ziehen, eine "menschliche Anzeige" -Priorität von den internen "Ordnungs" -Prioritäten zu trennen, um zu vermeiden, dass seltsame Dezimalstellen und negative Werte angezeigt werden.

Jojo
quelle
Verwenden Sie keine Dezimalstellen. Verwenden Sie numerische oder alphabetische Zeichenfolgen. Dann können Sie immer einen neuen Wert zwischen zwei alten einfügen, zumindest bis Sie das Zeichenfolgenlängenlimit erreicht haben.
Kevin Cline
0

Es ist sehr vernünftig, eine verknüpfte Liste und ihre Operationen in einem RDBMS zu implementieren. Ersetzen Sie einfach Array- und Referenzmanipulationen durch SQL-Abfragen. Ich bin mir jedoch nicht sicher, ob dies wirklich der effizienteste Weg ist, da für einige einfache Vorgänge viele SQL-Abfragen erforderlich sind

Für die Aufgabentabelle fügen Sie der ID-Spalte derselben Tabelle eine Spalte "next_task" und "prev_task" hinzu, die Fremdschlüssel sind (vorausgesetzt, ein "-1" entspricht NULL).

Geben Sie die Aufgabe mit der höchsten_priority () : SQL-Abfrage zurück, die die Aufgabe mit prev_task = -1 zurückgibt

E ist die wichtigste Aufgabe : SQL-Abfrage, die die next_task von E in die ID der Aufgabe mit der höchsten Priorität ändert. Und ändert prev_task von E in -1 ...

Diese und andere Vorgänge wie das Setzen von E vor A oder das Drucken einer geordneten Liste von Aufgaben erfordern viel mehr SQL-Abfragen, die alle atomar sein sollten (es sei denn, Sie können optimieren). Es ist eine gute Übung, aber vielleicht nicht die effizienteste.

HH
quelle
0

Ein anderer Ansatz für das Prioritätsproblem wäre die Angabe, welcher Artikel wichtiger ist als der Artikel. In einer HR-Anwendung wäre dies so, als würde man sagen, wer der Manager eines Mitarbeiters ist.

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

Lesen Sie dann diese http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/ , um eine Abfrage mit Priorität durchzuführen Ebenen.

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

Ich denke, dies ist eine einfachere Benutzererfahrung beim Festlegen von Prioritäten, aber es ermöglicht mehrere Prioritäten auf derselben Ebene.

Steven Brown
quelle
-1

Ein einfacher Weg wäre, mit so etwas zu beginnen:

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

Um dann "Aufgabe E" zwischen Aufgabe A und Aufgabe B zu verschieben, setzen Sie beispielsweise die Priorität von "Aufgabe E" auf einen halben Weg zwischen Aufgabe A und Aufgabe B (in diesem Fall "150").

Wenn Sie die Prioritäten ständig neu anordnen, stoßen Sie natürlich irgendwann auf ein Problem, bei dem zwei benachbarte Aufgaben keine "Lücke" zum Einfügen neuer Einträge haben. In diesem Fall können Sie einfach alle Prioritäten auf einmal auf 100, 200, 300 usw. zurücksetzen.

Dean Harding
quelle
1
Dies ist eigentlich das Gleiche wie meine Antwort. Ich beginne nur mit größeren ganzen Zahlen anstelle eng gruppierter Dezimalstellen. :)
Jojo
-1

Ich bin kein Datenbank-Guru, daher habe ich dies so logisch wie möglich in Access 2010 gelöst. Ich habe ein Feld "Priorität", das ein numerisches Feld ist. Dann habe ich eine Veranstaltung für dieses Feld.

Das Ereignis ist ein Ereignis nach der Aktualisierung für das Feld "Priorität", das eine Aktualisierungsabfrage "qryPriority" auslöst, um 1 zur Prioritätsnummer aller anderen Datensätze hinzuzufügen, deren Priorität größer oder gleich der gerade eingegebenen Prioritätsnummer ist.

Hier ist der Ereignis-VB-Code und Update Query SQL:

Ereignis "Priorität" VB-Code:

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

"qryPriority" Update Query SQL:

UPDATE YOURTABLENAME SET YOURTABLENAME.Priority = [Priority]+1
WHERE (((YOURTABLENAME.Priority)>=[Forms]![YOURFORMNAME]![Priority]));
Keegan
quelle