Danh sách ưu tiên của các tác vụ được lưu trữ trong cơ sở dữ liệu


10

Tôi đang cố gắng nghĩ ra cách tốt nhất để làm như sau:

Tôi có một danh sách các nhiệm vụ được lưu trữ trong cơ sở dữ liệu. Một nhiệm vụ có một ưu tiên được giao cho nó. Bạn có thể thay đổi mức độ ưu tiên của một nhiệm vụ để sắp xếp lại thứ tự chúng sẽ được thực hiện.

Tôi đang nghĩ về một cái gì đó rất giống với Pivotal Tracker.

Vì vậy, hãy tưởng tượng chúng ta đã có những điều sau đây:

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

Chúng tôi quyết định rằng E bây giờ là nhiệm vụ quan trọng nhất

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

Tôi cần cập nhật tất cả 5 nhiệm vụ để ưu tiên cho họ.

Nếu nhiệm vụ B trở nên quan trọng hơn thì AI sẽ có

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

Tôi chỉ cần cập nhật Nhiệm vụ B và A.

Những cách nào sẽ đi về cấu trúc này trong DB? Tôi tưởng tượng rằng bạn sẽ có một dự án differnt được lưu trữ trong cùng một bảng có trọng số riêng.

Sẽ tốt hơn nếu chỉ ra một Nhiệm vụ diễn ra sau nó (hơi giống như một danh sách liên kết).

Đây chỉ là một bãi rác thực sự. Chỉ tự hỏi làm thế nào bạn sẽ đi về thực hiện một cái gì đó như thế này.

Câu trả lời:


5
  1. Có vẻ như bạn đang tìm kiếm một hàng đợi ưu tiên. Có lẽ bạn không nên tính lại các số ưu tiên cho các nhiệm vụ, bạn chỉ nên tính một giá trị cố định cho chúng. Nếu bạn muốn nhiệm vụ E quan trọng hơn, hãy giảm giá trị của nó.
  2. Bạn chủ yếu nói về quan hệ. B nên quan trọng hơn A. E nên là nhiệm vụ quan trọng nhất, v.v. Nghe có vẻ giống cấu trúc cây và bạn có thể lưu trữ nó trong RDBMS với các liên kết cha.

4

Nếu bạn sử dụng số dấu phẩy động kép để biểu thị mức độ ưu tiên, bạn không cần phải đặt hàng lại:

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

Nếu bạn muốn đặt nhiệm vụ E giữa A và B thì: -

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

Vì vậy, bây giờ bạn có:

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

Nếu bạn muốn chèn D giữa E và B thì chỉ cần đặt mức ưu tiên của nó thành 1,75. Cho khoảng 18 chữ số thập phân trong một số dấu phẩy động (1,75 thực sự là 1,7500000000000000), bạn sẽ gặp trường hợp xấu nhất là 53 lần chèn liên tiếp trước đó:

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

Và trước khi bất cứ ai phàn nàn về chi phí sử dụng tăng gấp đôi so với số nguyên, đó chỉ là một vài hướng dẫn về phần cứng, so với chi phí xử lý và I / O của việc sắp xếp lại danh sách trong cơ sở dữ liệu sẽ lớn hơn nhiều lần.


1
Tôi thích cách tiếp cận này, nhưng nó phải là: E.p Warriority = A.p Warriority + ((B.p Warriority - A.p Warriority) / 2) và A.p Warriority + ((B.p Warriority - A.p Warriority) / 2) = B.p Warriority
Marcel Panse 30/11/18

1

Chúng tôi đã làm điều này rất bạn đang nói về. Chúng tôi đã làm điều này bằng cách sử dụng một thủ tục được lưu trữ sắp xếp lại danh sách các mục. Mỗi mục trong danh sách có một id duy nhất và số thứ tự sắp xếp.

Ví dụ:

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

Quy trình được lưu trữ sắp xếp lại các mục có hai tham số đầu vào:

@TaskId int,
@NewSortOrder int

Chúng tôi đã sử dụng bảng tạm thời để lưu trữ các mục theo thứ tự mới:

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

Chúng tôi đã sử dụng ba câu lệnh chọn để đưa chúng vào thứ tự mới:

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

Sau đó, chúng tôi đã cập nhật bảng cơ sở (tblT Nhiệm vụ) với thứ tự sắp xếp mới thực sự là cột nhận dạng RowId của bảng tạm thời:

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

Điều này hoạt động như một nhà vô địch mọi lúc.


0

Tôi chưa nghĩ đến điều này ..... Nhưng tại sao không chỉ cho phép số thập phân để bạn có thể nhét mọi thứ vào giữa những người khác mà không cập nhật mọi thứ?

Bạn có thể squish một cái gì đó từ 1 đến 2 với giá trị 1,5.

Tôi cũng sẽ tránh các giá trị tối thiểu và tối đa. Cho phép các con số chuyển sang phủ định nếu chúng được ưu tiên trước bất kỳ giá trị nào hiện tại là 0.

Bạn có thể xem xét có mức độ ưu tiên "hiển thị của con người" từ các ưu tiên "đặt hàng" bên trong để tránh hiển thị số thập phân và giá trị âm.


Đừng sử dụng số thập phân. Sử dụng chuỗi, số hoặc chữ cái. Sau đó, bạn luôn có thể chèn một giá trị mới giữa hai giá trị cũ, ít nhất là cho đến khi bạn đạt đến giới hạn độ dài chuỗi.
kevin cline

0

Thật hợp lý khi triển khai Danh sách được liên kết và các hoạt động của nó trong RDBMS. Chỉ cần thay thế các thao tác mảng và tham chiếu bằng các truy vấn SQL. Tuy nhiên, tôi không chắc liệu đây có thực sự là cách hiệu quả nhất hay không vì một số thao tác đơn giản sẽ yêu cầu nhiều truy vấn SQL

Đối với bảng tác vụ, bạn thêm một cột "next_task" và "tiền tố" là các khóa ngoại vào cột id của cùng một bảng (giả sử rằng "-1" tương đương với NULL)

Trả về tác vụ với cao nhất_p Warriority () : Truy vấn SQL trả về tác vụ với tiền tố = -1

E là nhiệm vụ quan trọng nhất : Truy vấn SQL thay đổi next_task của E thành ID của tác vụ với mức ưu tiên cao nhất. Và thay đổi thuận lợi của E thành -1 ...

Thao tác này và các hoạt động khác như đặt E trước A hoặc in danh sách các tác vụ được sắp xếp sẽ yêu cầu nhiều truy vấn SQL hơn, tất cả đều là nguyên tử (trừ khi bạn có thể tối ưu hóa). Đó là một bài tập tốt nhưng có lẽ không phải là cách hiệu quả nhất để làm nó.


0

Một cách tiếp cận khác cho vấn đề ưu tiên sẽ là chỉ định mục nào quan trọng hơn mục đó. Trong một ứng dụng nhân sự, điều này sẽ giống như nói người quản lý của nhân viên là ai.

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

Sau đó đọc http://blog.sqlauthority.com/2012/04/24/sql-server-int sinhtion- to- hierarchical- query-USE-a- recursive-cte-a-primer / để thực hiện một truy vấn ưu tiên cấp độ.

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

Tôi nghĩ rằng đây là một trải nghiệm người dùng đơn giản hơn trong việc thiết lập các ưu tiên, nhưng nó cho phép nhiều ưu tiên cùng cấp.


-1

Một cách đơn giản là bắt đầu với một cái gì đó như thế này:

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

Sau đó, để di chuyển "Nhiệm vụ E" giữa Nhiệm vụ A và Nhiệm vụ B, giả sử, bạn chỉ cần đặt mức độ ưu tiên của "Nhiệm vụ E" thành một nửa giữa Nhiệm vụ A và Nhiệm vụ B (nghĩa là "150" trong trường hợp này).

Tất nhiên, nếu bạn liên tục sắp xếp lại các ưu tiên, cuối cùng bạn sẽ gặp phải một vấn đề trong đó hai nhiệm vụ liền kề không có "khoảng cách" để chèn các mục mới. Nhưng khi điều đó xảy ra, bạn chỉ cần "đặt lại" tất cả các ưu tiên trong một lần quay lại 100, 200, 300, v.v.


1
Đây thực sự giống như câu trả lời của tôi, chỉ bắt đầu với số nguyên lớn hơn thay vì số thập phân được nhóm chặt chẽ. :)
jojo

-1

Tôi không phải là chuyên gia cơ sở dữ liệu, vì vậy tôi đã giải quyết theo cách hợp lý nhất có thể trong Access 2010. Tôi có trường "Ưu tiên" là trường số. Sau đó, tôi có một sự kiện cho lĩnh vực này.

Sự kiện này là một sự kiện cập nhật sau cho trường "Ưu tiên" kích hoạt Truy vấn cập nhật "qryP Warriority" để thêm 1 vào số ưu tiên của tất cả các bản ghi khác có mức ưu tiên lớn hơn hoặc bằng số ưu tiên vừa nhập.

Đây là mã VB sự kiện và SQL truy vấn cập nhật:

Mã ưu tiên sự kiện "Ưu tiên":

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

Cập nhật SQL truy vấn "qryP Warriority":

UPDATE YOURTABLENAME SET YOURTABLENAME.Priority = [Priority]+1
WHERE (((YOURTABLENAME.Priority)>=[Forms]![YOURFORMNAME]![Priority]));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.