Как создать структуру типа очереди в SQL Server - PullRequest
0 голосов
/ 11 декабря 2018

Есть ли хороший способ создать структуру, похожую на очередь, в SQL Server?

Требования:

  1. Когда я вставляю строки, я хочу, чтобы они были по умолчанию в нижней частиочередь
  2. Когда я выбираю строки, я хочу легко получить верхнюю часть очереди
  3. Вот сложный вопрос: я хочу легко перемещать что-то вверх по очереди, ипереориентировать все остальное.Пример: переместите элемент 5 на номер 1, затем 1-4 станет 2-5

Простой столбец идентификации будет работать для требований 1 и 2, но как мне обработать 3?

Решение

В итоге я реализовал решение от @ roger-wolf Одно отличие: я использовал триггер, а не хранимую процедуру для перенумерации.Вот мой код триггера:

CREATE TRIGGER [dbo].[TR_Queue]
    ON [dbo].[Queue]
    AFTER INSERT, DELETE, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    -- Get the current max value in priority
    DECLARE @maxPriority INT = COALESCE((SELECT MAX([priority]) FROM [dbo].[Queue]), 0);

    WITH newValues AS (
        -- Renumber by priority, starting at 1
        SELECT [queueID]
            ,ROW_NUMBER() OVER(ORDER BY [priority] ASC) AS [priority]
        FROM (
            -- Pretend all nulls are greater than previous max priority
            SELECT [queueID]
                ,COALESCE([priority], @maxPriority+1) AS [priority]
            FROM [dbo].[Queue]
        ) AS tbl
    )
    UPDATE q
    SET q.[priority] = newValues.[priority]
    FROM [dbo].[Queue] AS qroger-wolf
    INNER JOIN newValues
        ON q.[queueID] = newValues.[queueID]
END

Это хорошо работает для меня, поскольку очередь всегда относительно мала и редко обновляется, поэтому мне не нужно работать с производительностью триггера.

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

У меня было похожее требование в прошлом проекте, что я делал (и это работало):

  1. Добавить столбец update_at_utc типа datetime2
  2. При вставке,set update_at_utc = GETDATEUTC()
  3. При получении упорядочить по update_at_utc
  4. При перемещении строки в очереди, например, между строками 3 и 4, просто взять среднее значение update_at_utc этих строки используйте его для установки update_at_utc перемещаемой строки.

Примечание 1. Точка 4 предполагает, что частота вставок и перемещения строк вверх / вниз по очереди такова, что тип datetime2 имеетдостаточное разрешение.Например, если вы вставляете 2 строки на расстоянии 1 миллисекунды, а затем пытаетесь переместить 1000 строк между этими 2 строками, разрешение datetime2 будет недостаточным (https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetime2-transact-sql?view=sql-server-2017). В этом случае перемещение строк вверх / вниз по очередидолжно быть более сложным; при перемещении строки N местами вниз вниз:

  1. Помните update_at_utc строки N местами ниже вниз
  2. Для всех строк между текущей и новой позицией: присвойте update_at_utc строки предыдущей строке update_at_utc
  3. Присвойте update_at_utc строки, которая будет перемещена, к дате, запомненной в пункте 1 выше.

Примечание 2: Iпредлагайте даты UTC вместо локальных, чтобы избежать проблем при переходе на летнее время.

0 голосов
/ 11 декабря 2018

Вы можете добавить столбец Priority типа DateTime, и когда вы устанавливаете строку в качестве приоритетной строки, вы устанавливаете текущую дату-время в столбце Priority, а затем используете ее как часть вашего order by критерии?

0 голосов
/ 11 декабря 2018

Используйте столбец float для расстановки приоритетов и подход, аналогичный деревьям Celko:

  • Если у вас есть предметы с приоритетами 1, 2 и 3, а последний должен стать вторым, рассчитайтесреднее число между его новыми соседями, 1,5 в этом примере;
  • Если другой должен стать вторым, его приоритет будет 1,25.Это может продолжаться довольно долго;
  • При отображении элементов в очереди по их приоритету используйте row_number() вместо значений с плавающей точкой в ​​пользовательском интерфейсе;
  • Если элементы становятся слишком близко друг к другу (скажем, 1e-10 или меньше), иметь хранимую процедуру, готовую перенумеровать их в целые числа.

Единственный недостаток, который я вижу здесь, состоит в том, что становится труднее найти N-й элемент в серединеочередь, когда она не первая и не последняя.Если вам это не нужно, подход должен сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...