데이터베이스에 저장된 작업의 우선 순위 목록


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 만 업데이트해야합니다.

DB에서 이것을 구성하는 방법은 무엇입니까? 같은 테이블에 다른 프로젝트가 저장되어 자체 무게를 가질 것이라고 생각합니다.

그 이후에 발생하는 작업 (링크 목록과 비슷 함)을 지적하는 것이 좋습니다.

이것은 단지 두뇌 덤프입니다. 이런 식으로 구현하는 방법에 대해 궁금해했습니다.

답변:


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

E와 B 사이에 D를 삽입하려면 우선 순위를 1.75로 설정하십시오. 부동 소수점 숫자 (1.75는 실제로 1.7500000000000000 임)에 약 18 개의 10 진수가 주어지면 다음에 53 개의 연속 삽입 중 최악의 경우가 있어야합니다.

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

그리고 누군가가 doubles vs. integers를 사용하는 오버 헤드에 대해 불평하기 전에 데이터베이스의 목록을 재정렬하는 처리 및 I / O 오버 헤드와 비교하여 몇 가지 하드웨어 명령과 비교하면 몇 가지 하드웨어 명령 만 있습니다.


1
나는이 접근법을 좋아하지만 E.priority = A.priority + ((B.priority-A.priority) / 2) 및 A.priority + ((B.priority-A.priority) / 2) = B.priority
Marcel Panse

지적 해 주셔서 감사합니다-이에 따라 수정 된 답변
James Anderson

1

우리는 당신이 말하는 바로 그 일을했습니다. 항목 목록을 재정렬 한 하나의 저장 프로 시저를 사용하여이를 수행했습니다. 목록의 각 항목에는 고유 한 ID와 정렬 순서 번호가있었습니다.

예를 들어 :

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

항목 순서를 변경 한 저장 프로 시저에는 두 가지 입력 매개 변수가 사용됩니다.

@TaskId int,
@NewSortOrder int

임시 테이블을 사용하여 항목을 새로운 순서로 저장했습니다.

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

세 가지 select 문을 사용하여 새로운 순서로 만들었습니다.

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

그런 다음 임시 테이블 의 RowId ID 열인 새로운 정렬 순서로 기본 테이블 (tblTasks)을 업데이트했습니다 .

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

이것은 매번 챔피언처럼 작동합니다.


0

나는 이것을 아직 생각하지 못했습니다 ..... 그러나 왜 소수를 허용하여 모든 것을 업데이트하지 않고 다른 사람들 사이에 물건을 넣을 수 있습니까?

값이 1.5 인 1에서 2 사이의 값을 쓸어 낼 수 있습니다.

나는 또한 최소값과 최대 값을 피할 것입니다. 현재 0보다 우선 순위가 높은 숫자가 음수로 롤링되도록 허용합니다.

"인간적 표시"우선 순위를 내부 "순서"우선 순위와 분리하여 잘못된 10 진수 및 음수 값을 표시하지 않도록 고려할 수 있습니다.


소수점을 사용하지 마십시오. 숫자 또는 알파벳 문자열을 사용하십시오. 그런 다음 최소한 문자열 길이 제한에 도달 할 때까지 항상 두 개의 이전 값 사이에 새 값을 삽입 할 수 있습니다.
케빈 클라인

0

RDBMS에서 연결 목록 및 해당 작업을 구현하는 것이 매우 합리적입니다. 배열 및 참조 조작을 SQL 쿼리로 바꾸십시오. 그러나 간단한 작업에 많은 SQL 쿼리가 필요하기 때문에 이것이 실제로 가장 효율적인 방법인지 확실하지 않습니다.

작업 테이블의 경우 외래 키인 "next_task"및 "prev_task"열을 동일한 테이블의 id 열에 추가합니다 ( "-1"이 NULL과 같다고 가정).

prev_task = -1 인 작업을 반환하는 가장 높은 우선 순위 () : SQL 쿼리로 작업을 반환합니다.

E는 가장 중요한 작업입니다 . SQL 쿼리는 E의 next_task를 가장 높은 우선 순위의 작업 ID로 변경합니다. 그리고 E의 prev_task를 -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

그런 다음 작업 A와 작업 B 사이에서 "작업 E"를 이동하려면 "작업 E"의 우선 순위를 작업 A와 작업 B 사이의 중간 정도 (이 경우 "150")로 설정하면됩니다.

물론 우선 순위를 지속적으로 재정렬하면 결국 두 개의 인접한 작업에 새 항목을 삽입 할 "갭"이없는 문제가 발생합니다. 그러나 이러한 상황이 발생하면 우선 순위를 모두 "100", 200, 300 등으로 "재설정"할 수 있습니다.


1
이것은 실제로 내 대답과 동일하며 밀접하게 그룹화 된 소수점 대신 더 큰 정수로 시작합니다. :)
jojo

-1

데이터베이스 전문가가 아니므로 Access 2010에서 할 수있는 가장 논리적 인 방법으로이 문제를 해결했습니다. 숫자 필드 인 "우선 순위"필드가 있습니다. 그런 다음이 필드에 대한 이벤트가 있습니다.

이 이벤트는 "Priority"필드에 대한 업데이트 후 이벤트로, 업데이트 쿼리 "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]));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.