Перелік пріоритетів завдань, що зберігаються в базі даних


9

Я намагаюся придумати найкращий спосіб зробити наступне:

У мене є список завдань, що зберігаються в базі даних. Завдання має пріоритет. Ви можете змінити пріоритет завдання, щоб змінити порядок їх виконання.

Я думаю про щось дуже схоже на 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.

Якими шляхами можна було б структурувати це в БД? Я думаю, що у вас були б різні проекти, що зберігаються в одній таблиці, яка мала б там власну вагу.

Було б краще вказати Завдання, яке відбувається після нього (трохи схоже на список посилань).

Це насправді просто мозковий відвал. Просто цікавилося, як ти будеш реалізовувати щось подібне.

Відповіді:


6
  1. Схоже, ви шукаєте чергу з пріоритетом. Вам, ймовірно, не слід перечислювати номери пріоритетів для завдань, просто слід обчислити фіксовану величину для них. Якщо ви хочете, щоб завдання E було важливішим, зменшіть його значення.
  2. Ви по суті говорите про відносини. B має бути важливішим, ніж A. E має бути найважливішим завданням тощо. Це звучить як структура дерева, і ви можете зберігати це в RDBMS з батьківськими посиланнями.

5

Якщо ви використовуєте подвійні номери з плаваючою комою для позначення пріоритету, вам не потрібно повторно замовляти:

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 = A.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

Якщо ви хочете вставити D між E і B, просто встановіть його пріоритет у 1,75. Враховуючи приблизно 18 десяткових цифр у кількості з плаваючою комою (1,75 - це дійсно 1,7500000000000000), ви повинні мати найгірший випадок із 53 послідовних вставок раніше:

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

І перш ніж хтось скаржиться на накладні витрати на використання подвійних та цілих чисел, його лише кілька апаратних інструкцій, порівняно з обробкою та накладними вводами / виводами для переупорядкування списку в базі даних, що було б на кілька порядків більше.


1
Мені подобається такий підхід, але він повинен бути: E.priority = A.priority + ((B.priority - A.priority) / 2) та A.priority + ((B.priority - A.priority) / 2) = B.priority
Марсель Пансе

Дякуємо, що вказали на це - відповідь відповідним чином змінено
Джеймс Андерсон,

1

Ми зробили це дуже те, про що ви говорите. Ми зробили це за допомогою однієї збереженої процедури, яка упорядкувала список елементів. Кожен елемент у списку мав унікальний ідентифікатор та номер порядку сортування.

Наприклад:

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

Збережена процедура, яка упорядковує елементи, приймає два вхідні параметри:

@TaskId int,
@NewSortOrder int

Ми використовували таблицю темп для зберігання елементів у новому порядку:

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

Для введення їх у новий порядок ми використали три вибрані оператори:

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

Потім ми оновили базову таблицю (tblTasks) новим порядком сортування, який є фактично стовпцем ідентичності RowId таблиці темп:

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

Це працює як чемпіон кожного разу.


0

Я це ще не продумав ..... Але чому б просто не дозволити децимальні знаки, щоб ви могли складати речі між іншими, не оновлюючи все?

Ви можете скосити щось від 1 до 2 зі значенням 1,5.

Я також уникав мінімуму та максимальних значень. Дозвольте цифрам зводитись до мінусів, якщо вони мають пріоритет перед тим, що є 0.

Ви можете подумати, що пріоритет "відображення людини" відокремлений від внутрішніх пріоритетів "впорядкування", щоб уникнути відображення відміткових десяткових знаків та негативних значень.


Не використовуйте десяткові знаки. Використовуйте рядки, числові або алфавітні. Тоді ви завжди можете вставити нове значення між двома старими, принаймні, поки не досягнете межі довжини рядка.
кевін клайн

0

Дуже розумно реалізувати пов'язаний список та його операції в RDBMS. Просто замініть масив та посилання на маніпуляції на SQL-запити. Однак я не впевнений, чи справді це найефективніший шлях, оскільки для простої операції знадобиться багато запитів SQL

Для таблиці завдань ви додаєте стовпчик "next_task" та "prev_task", які є зовнішніми ключами до стовпця id цієї ж таблиці (припустимо, що "-1" еквівалентний NULL)

Повернути завдання з найвищим_priority () : SQL-запит, який повертає завдання з prev_task = -1

E є найважливішим завданням : SQL-запит, який змінює next_task E на ID завдання з найвищим пріоритетом. І змінює prev_task від E на -1 ...

Для таких та інших операцій, як поставлення E перед A або друк упорядкованого списку завдань, знадобиться набагато більше SQL запитів, які мають бути атомними (якщо ви не в змозі оптимізувати). Це хороша вправа, але, можливо, не найефективніший спосіб її виконання.


0

Іншим підходом до пріоритетної проблеми було б визначити, який пункт важливіший за пункт. У програмі HR, це було б так, як сказати, хто керівник працівника.

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

Одним із простих способів було б почати щось подібне:

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

Потім, щоб перемістити "Завдання E" між Завданням A і Завданням Б, скажімо, ви просто встановили пріоритет "Завдання Е" на щось на півдорозі між Завданням A і Задачею В (тобто "150" у цьому випадку).

Звичайно, якщо ви постійно переставляєте пріоритети, з часом ви зіткнетеся з проблемою, при якій у двох суміжних завдань немає «прогалини» для вставки нових записів. Але коли це станеться, ви можете просто "скинути" всі пріоритети за один перехід до 100, 200, 300 тощо.


1
Це насправді те саме, що моя відповідь, тільки починаючи з більших цілих чисел, а не тісно згрупованих десяткових знаків. :)
jojo

-1

Я не гуру бази даних, тому я вирішив це самим логічним способом, який я міг у Access 2010. У мене є поле "Пріоритет", яке є числовим полем. Тоді у мене подія для цього поля.

Подія - це подія після оновлення для поля "Пріоритет", що запускає запит оновлення "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]));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.