Daftar prioritas tugas yang disimpan dalam database


10

Saya mencoba memikirkan cara terbaik untuk melakukan hal berikut:

Saya memiliki daftar tugas yang disimpan dalam database. Suatu tugas memiliki prioritas yang ditetapkan padanya. Anda dapat mengubah prioritas tugas untuk menyusun ulang urutan yang seharusnya dijalankan.

Saya sedang memikirkan sesuatu yang sangat mirip dengan Pelacak Penting.

Jadi bayangkan kita memiliki yang berikut ini:

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

Kami memutuskan bahwa E sekarang adalah tugas yang paling penting

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

Saya perlu memperbarui semua 5 tugas untuk memberi mereka prioritas baru.

Jika Tugas B kemudian menjadi lebih penting maka AI akan saya miliki

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

Saya perlu memperbarui Tugas B dan A saja.

Cara apa yang akan dilakukan untuk menyusun ini dalam DB? Saya membayangkan bahwa Anda akan memiliki proyek yang berbeda disimpan dalam tabel yang sama yang akan memiliki bobot sendiri.

Apakah lebih baik untuk menunjuk Tugas yang terjadi setelahnya (sedikit seperti daftar tautan).

Ini benar-benar dump otak. Hanya ingin tahu bagaimana Anda akan menerapkan sesuatu seperti ini.

Jawaban:


5
  1. Sepertinya Anda mencari antrian prioritas. Anda mungkin tidak harus menghitung ulang angka prioritas untuk tugas, Anda hanya harus menghitung nilai tetap untuk mereka. Jika Anda ingin tugas E menjadi lebih penting, kurangi nilainya.
  2. Anda pada dasarnya berbicara tentang hubungan. B harus lebih penting daripada A. E harus menjadi tugas yang paling penting, dll. Kedengarannya seperti struktur pohon, dan Anda dapat menyimpannya dalam RDBMS dengan tautan induk.

4

Jika Anda menggunakan angka floating point ganda untuk menunjukkan prioritas, Anda tidak perlu memesan ulang:

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

Jika Anda ingin menempatkan tugas E antara A dan B maka: -

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

Jadi sekarang Anda memiliki:

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

Jika Anda ingin memasukkan D antara E dan B maka cukup tetapkan prioritasnya menjadi 1,75. Dengan sekitar 18 digit desimal dalam angka floating point (1,75 benar-benar 1,750000000000000000), Anda harus memiliki kasus terburuk dengan 53 sisipan berurutan sebelumnya:

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

Dan sebelum ada yang mengeluh tentang overhead menggunakan doubles vs integer, itu hanya beberapa instruksi perangkat keras, dibandingkan dengan pemrosesan dan I / O overhead menyusun kembali daftar dalam database yang akan beberapa kali lipat lebih besar.


1
Saya suka pendekatan ini, tetapi harus: E.priority = A.priority + ((B.priority - A.priority) / 2) dan A.priority + ((B.priority - A.priority) / 2) = B.prioritas
Marcel Panse

1

Kami melakukan hal yang Anda bicarakan ini. Kami melakukan ini dengan menggunakan satu prosedur tersimpan yang menyusun ulang daftar item. Setiap item dalam daftar memiliki id unik dan nomor urut urutan.

Sebagai contoh:

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

Prosedur tersimpan yang menyusun ulang item membutuhkan dua parameter input:

@TaskId int,
@NewSortOrder int

Kami menggunakan tabel temp untuk menyimpan item dalam pesanan baru:

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

Kami menggunakan tiga pernyataan pilih untuk memasukkannya ke orde baru:

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

Kami kemudian memperbarui tabel dasar (tblTasks) dengan urutan baru yang sebenarnya adalah kolom identitas RowId dari tabel temp:

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

Ini bekerja seperti juara setiap saat.


0

Saya belum memikirkan ini secara menyeluruh ..... Tapi mengapa tidak hanya membolehkan desimal sehingga Anda dapat memasukkan berbagai hal di antara yang lain tanpa memperbarui semuanya?

Anda bisa meremas sesuatu antara 1 dan 2 dengan nilai 1,5.

Saya juga menghindari nilai minimum dan maksimum. Bolehkan angka untuk memasukkan negatif jika prioritasnya datang sebelum apa pun yang saat ini 0.

Anda dapat mempertimbangkan memiliki prioritas "tampilan manusia" yang terpisah dari prioritas "pemesanan" internal untuk menghindari menunjukkan desimal aneh dan nilai negatif.


Jangan gunakan desimal. Gunakan string, numerik atau alfabet. Kemudian Anda selalu dapat memasukkan nilai baru di antara dua yang lama, setidaknya sampai Anda mencapai batas panjang string.
kevin cline

0

Sangat masuk akal untuk mengimplementasikan Daftar Tertaut dan operasinya dalam RDBMS. Cukup ganti array dan manipulasi referensi dengan query SQL. Namun, saya tidak yakin apakah ini benar-benar cara yang paling efisien untuk pergi karena beberapa operasi sederhana akan memerlukan banyak pertanyaan SQL

Untuk tabel tugas, Anda menambahkan kolom "next_task" dan "prev_task" yang merupakan kunci asing ke kolom id dari tabel yang sama (dengan asumsi bahwa "-1" setara dengan NULL)

Kembali tugas dengan tertinggi_prioritas () : Permintaan SQL yang mengembalikan tugas dengan prev_task = -1

E adalah tugas yang paling penting : SQL query yang mengubah next_task dari E ke ID tugas dengan prioritas tertinggi. Dan perubahan prev_task dari E ke -1 ...

Ini dan operasi lainnya seperti meletakkan E sebelum A, atau mencetak daftar tugas yang diurutkan akan membutuhkan lebih banyak pertanyaan SQL yang semuanya atomik (kecuali Anda dapat mengoptimalkan). Ini adalah latihan yang bagus tapi mungkin bukan cara yang paling efisien untuk melakukannya.


0

Pendekatan lain untuk masalah prioritas adalah menentukan item apa yang lebih penting daripada item tersebut. Dalam aplikasi SDM, ini seperti mengatakan siapa manajer karyawan.

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

Kemudian baca http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/ untuk membuat kueri yang mengutamakan level.

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

Saya pikir ini adalah pengalaman pengguna yang lebih sederhana dalam menetapkan prioritas, tetapi memungkinkan beberapa prioritas pada tingkat yang sama.


-1

Salah satu cara sederhana adalah memulai dengan sesuatu seperti ini:

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

Kemudian, untuk memindahkan "Tugas E" antara Tugas A dan Tugas B, katakanlah, Anda baru saja menetapkan prioritas "Tugas E" untuk sesuatu yang setengah jalan antara Tugas A dan Tugas B (yaitu "150" dalam kasus ini).

Tentu saja, jika Anda terus mengatur ulang prioritas, Anda akhirnya akan mengalami masalah di mana dua tugas yang berdekatan tidak memiliki "celah" untuk memasukkan entri baru. Tetapi ketika itu terjadi, Anda cukup "mengatur ulang" semua prioritas dalam satu kembali ke 100, 200, 300, dll.


1
Ini sebenarnya sama dengan jawaban saya, hanya memulai dengan bilangan bulat yang lebih besar daripada desimal yang dikelompokkan dengan ketat. :)
jojo

-1

Saya bukan guru basis data, jadi saya memecahkan ini dengan cara paling logis yang saya bisa di Access 2010. Saya memiliki bidang "Prioritas" yang merupakan bidang angka. Lalu saya punya acara untuk bidang ini.

Acara ini adalah acara setelah pembaruan untuk bidang "Prioritas" yang memicu Permintaan Pembaruan "qryPriority" untuk menambahkan 1 ke nomor prioritas semua catatan lain yang memiliki prioritas lebih besar atau sama dengan nomor prioritas yang baru saja dimasukkan.

Berikut ini adalah kode acara VB dan Perbarui Query SQL:

Kode VB Acara "Prioritas":

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

"qryPriority" Memperbarui Query SQL:

UPDATE YOURTABLENAME SET YOURTABLENAME.Priority = [Priority]+1
WHERE (((YOURTABLENAME.Priority)>=[Forms]![YOURFORMNAME]![Priority]));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.