簡體   English   中英

如何在SQL Server中創建類似於結構的隊列

[英]How to create a queue like structure in SQL Server

有沒有在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

這對我來說效果很好,因為隊列總是相對較小且不經常更新,因此我不必處理觸發器的性能。

使用float列進行優先級排序,並使用類似於Celko樹的方法:

  • 如果您有優先級為1、2和3的項目,而最后一個需要排在第二位,則計算其新鄰居之間的平均值,在此示例中為1.5;
  • 如果另一個需要成為第二,則其優先級為1.25。 這可以持續一段時間。
  • 當按優先級顯示排隊的項目時,在UI中使用row_number()而不是float值;
  • 如果項目之間的距離太近(例如1e-10或更小),請准備一個存儲過程以將它們重新編號為整數。

我在這里看到的唯一缺陷是,當隊列中的第N個項目既不是第一個也不是最后一個時,要找到它要困難一些。 如果您不需要它,則該方法應該有效。

您可以添加類型為DateTimePriority列,然后將某行設置為優先級行時,在Priority列中設置當前日期時間,然后order by條件將其用作order by一部分?

我在過去的項目中有類似的要求,我做了什么(並且奏效了):

  1. 添加類型為datetime2 update_at_utc
  2. 插入時,設置update_at_utc = GETDATEUTC()
  3. 檢索時,請按update_at_utc排序
  4. 在隊列中移動一行時,例如在第3行和第4行之間移動時,只需取這些行的update_at_utc的平均值,然后使用它來設置要移動的行的update_at_utc

注1:第4點假設插入和上下移動隊列的頻率使得datetime2類型具有足夠的分辨率。 例如,如果您以1毫秒的間隔插入2行,然后嘗試在這2行之間移動1000行,則datetime2分辨率將不足( https://docs.microsoft.com/zh-cn/sql/t-sql / data-types / datetime2-transact-sql?view = sql-server-2017 )。 在這種情況下,行在隊列中的上/下移動將更加復雜。 當移動N行時,請降低位置:

  1. 請記住,第N行的update_at_utc位置較低
  2. 對於當前位置和新位置之間的所有行:將行的update_at_utc分配給上一行的update_at_utc
  3. 將要移動的行的update_at_utc分配到上面第1點中記住的日期。

注意2:我建議使用UTC日期而不是本地日期,以避免在夏令時期間出現問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM