Veritabanında depolanan görevlerin öncelik listesi


9

Aşağıdakileri yapmanın en iyi yolunu düşünmeye çalışıyorum:

Veritabanında depolanan görevlerin bir listesi var. Bir görevin kendisine atanmış bir önceliği vardır. Yapılması gereken sırayı yeniden sıralamak için görevin önceliğini değiştirebilirsiniz.

Pivotal Tracker'a çok benzeyen bir şey düşünüyorum.

Öyleyse aşağıdakilere sahip olduğumuzu hayal edin:

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

E'nin artık en önemli görev olduğuna karar veriyoruz

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

Onlara yeni bir öncelik vermek için 5 görevi de güncellemem gerekiyor.

Eğer Görev B daha önemli hale gelirse yapay zekâ

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

Yalnızca Görev B ve A'yı güncellemem gerekiyor.

Bunu bir DB'de yapılandırmanın yolları nelerdir? Aynı tabloda depolanan ve kendi ağırlığına sahip farklı bir projeniz olacağını hayal ediyorum.

Bundan sonra gerçekleşen bir Görevi işaret etmek daha iyi olur mu (biraz bağlantı listesi gibi).

Bu gerçekten bir beyin dökümü. Sadece böyle bir şeyi nasıl uygulayacağınızı merak ediyordum.

Yanıtlar:


6
  1. Görünüşe göre bir öncelik kuyruğu arıyorsunuz. Muhtemelen görevler için öncelik sayılarını yeniden hesaplamamalısınız, sadece onlar için sabit bir değer hesaplamalısınız. E görevinin daha önemli olmasını istiyorsanız, değerini azaltın.
  2. Aslında ilişkilerden bahsediyorsunuz. B, A'dan daha önemli olmalı. E, en önemli görev, vb .

5

Önceliği belirtmek için çift kayan noktalı sayılar kullanıyorsanız, yeniden sipariş vermenize gerek yoktur:

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

E görevini A ve B arasına yerleştirmek istiyorsanız: -

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

Şimdi var:

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

E ve B arasına D eklemek isterseniz, önceliğini 1,75 olarak ayarlamanız yeterlidir. Kayan noktalı sayıdaki yaklaşık 18 ondalık basamağı (1.75 gerçekten 1.7500000000000000) göz önüne alındığında, daha önce 53 ardışık kesici uç eklenmesi gerekir:

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

Ve herkes çiftler ve tamsayıların kullanım yükü hakkında şikayet etmeden önce, sadece birkaç donanım talimatı, birkaç büyüklük sırası daha büyük olacak şekilde veritabanındaki listeyi yeniden sıralama işlemiyle karşılaştırılır.


1
Bu yaklaşımı beğendim, ancak şöyle olmalıdır: E.priority = A.priority + ((B. priority - A. priority) / 2) ve A. priority + ((B. priority - A. priority) / 2) = B.priority
Marcel Panse

Bunu işaret ettiğiniz için teşekkürler - cevap buna göre değiştirildi
James Anderson

1

Bahsettiğiniz bu şeyi yaptık. Bunu, öğe listesini yeniden sıralayan bir saklı yordam kullanarak yaptık. Listedeki her öğenin benzersiz bir kimliği ve bir sıralama düzeni numarası vardı.

Örneğin:

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

Öğeleri yeniden sıralayan saklı yordam iki giriş parametresi alır:

@TaskId int,
@NewSortOrder int

Öğeleri yeni siparişte saklamak için bir geçici tablo kullandık:

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

Bunları yeni siparişe dahil etmek için üç belirli ifade kullandık:

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

Daha sonra temel tabloyu (tblTasks) , geçici tablonun RowId kimlik sütunu olan yeni sıralama düzeniyle güncelledik :

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

Bu her seferinde bir şampiyon gibi çalışır.


0

Bunu henüz düşünmedim ..... Ama neden sadece ondalıklara izin vermiyorsunuz, böylece her şeyi güncellemeden diğerleri arasında bir şeyler yapabilirsiniz?

1.5 değeri ile 1 ve 2 arasında bir şey ezebilirsin.

Min ve maks değerlerinden de kaçınırım. Şu anda 0'dan önce öncelik gelmesi durumunda sayıların negatiflere dönmesine izin verin.

Garip ondalık sayıları ve negatif değerleri göstermekten kaçınmak için "insan görüntüleme" önceliğini dahili "sipariş" önceliklerinden ayrı tutmayı düşünebilirsiniz.


Ondalık sayılar kullanmayın. Sayısal veya alfabetik dizeler kullanın. Ardından, en azından dize uzunluğu sınırına ulaşıncaya kadar, iki eski arasında yeni bir değer ekleyebilirsiniz.
kevin cline

0

Bağlantılı Liste ve işlemlerini RDBMS'de uygulamak çok mantıklıdır. Sadece dizi ve referans manipülasyonlarını SQL sorguları ile değiştirin. Ancak, bazı basit işlemw birçok SQL sorgusu gerektireceğinden, bunun gerçekten en etkili yol olup olmadığından emin değilim

Görev tablosu için, aynı tablonun id sütununa yabancı anahtarlar olan "next_task" ve "prev_task" sütunlarını eklersiniz ("-1" değerinin NULL değerine eşit olduğu varsayılarak)

Görevi en yüksek_priority () ile döndür : Görevi prev_task = -1 ile döndüren SQL sorgusu

E en önemli görevdir : E'nin next_task'ını en yüksek önceliğe sahip görevin ID'sine değiştiren SQL sorgusu. Ve E'nin önceki görevini -1 olarak değiştirir ...

Bu ve E'yi A'dan önce koymak veya sıralı bir görev listesi yazdırmak gibi tüm işlemler, atomik olması gereken çok daha fazla SQL sorgusu gerektirir (optimize edemediğiniz sürece). İyi bir egzersizdir, ancak belki de bunu yapmanın en etkili yolu değildir.


0

Öncelikli soruna başka bir yaklaşım, hangi öğenin öğeden daha önemli olduğunu belirtmektir. İK başvurusunda, bu bir çalışanın yöneticisinin kim olduğunu söylemek gibidir.

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

Ardından , öncelik veren bir sorgu yapmak için bu http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/ adresini okuyun. seviyeleri.

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

Bunun öncelikleri belirlemede daha basit bir kullanıcı deneyimi olduğunu düşünüyorum, ancak aynı seviyenin birden fazla önceliğine izin veriyor.


-1

Bunun basit bir yolu şöyle bir şeyle başlamak olabilir:

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

Ardından, "Görev E" yi Görev A ve Görev B arasında taşımak için, "Görev E" nin önceliğini Görev A ile Görev B arasında yarıya ayarlamanız gerektiğini söyleyin (bu durumda "150").

Elbette, öncelikleri sürekli olarak yeniden düzenlerseniz, nihayetinde iki bitişik görevin yeni girişler eklemek için "boşluğu" olmadığı bir sorunla karşılaşırsınız. Ancak bu olduğunda, tüm öncelikleri tek seferde 100, 200, 300 vb. Seviyelere "sıfırlayabilirsiniz".


1
Bu aslında cevabımla aynı, sadece yakın gruplanmış ondalık sayılar yerine daha büyük tamsayılarla başlıyor. :)
jojo

-1

Ben veritabanı gurusu değilim, bu yüzden bu Access 2010'da olabilir en mantıklı şekilde çözüldü. Sayısal bir alan olan bir "Öncelik" alan var. Sonra bu alan için bir olay var.

Olay, "Öncelik" alanı için, girilen öncelik numarasından daha büyük veya ona eşit önceliğe sahip tüm diğer kayıtların öncelik numarasına 1 eklemek üzere bir Güncelleme Sorgusu "qryPriority" tetikleyen bir güncelleme sonrası olayıdır.

İşte olay VB kodu ve Güncelleme Sorgusu SQL:

"Öncelikli" Etkinlik VB Kodu:

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

"qryPriority" Güncelleme Sorgusu SQL:

UPDATE YOURTABLENAME SET YOURTABLENAME.Priority = [Priority]+1
WHERE (((YOURTABLENAME.Priority)>=[Forms]![YOURFORMNAME]![Priority]));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.