2012-05-04 11 views
1

データソースには、 5000レコード。 orderby newid()でランダムにデータを注文することが可能です。しかし、ソートされるデータはページされるべきです。つまり、ページnには前のページのレコード(n-1、n-2など)を含めることはできません。今私は2つの方法があると思います:データベース内での注文、またはメモリ内での注文(5000レコードはインメモリキャッシュに保持するのに十分小さいので)。ランダムに結果セットを注文する場所 - データベースまたはメモリ?

オプション1(dbでソート)では、データをページする必要があるかどうかはわかりません。もしそうなら、それは可能ですか?オプション2には、メモリ内のデータを注文するための良いアルゴリズムがありますか?このシナリオでは、メモリやデータベースで注文するのはどうですか?なぜですか?

+0

ランダム化の対象は何ですか?単一のユーザーが、ページングする際に一貫してランダムな順序でリストを参照するようにします。他のユーザーはそれを別の方法で見ますか?一人のユーザーがリストを見直して、日々それをどのように見ていますか? – HABO

+0

ページングと順序付けはプレゼンテーションレイヤの作業です。私はアプリで投票します。 – frankc

答えて

0

TSQLで擬似乱数を使用して、ランダム化された値の再現可能なリストを生成できます。

@Seedの計算からコメントデリミタを削除すると、新しい値がそれぞれ@LastLoginになるようにシーケンスが変化します。

-- Some user specific value that does not change. 
declare @UserId as Int = 42 
-- Some user specific value that changes as often as you want the order to change for a user. 
declare @LastLogin as DateTime = SysDateTime() 
-- Paging parameters. 
declare @PageSize as Int = 10 
declare @PageNumber as Int = 2 

select @UserId as Seed, @UserId + DatePart(ms, @LastLogin) as AlternativeSeed, @LastLogin as LastLogin 
declare @Seed as Int = @UserId -- + DatePart(ms, @LastLogin) 

; with Numbers (Number, PseudorandomNumber) as (
    -- Select the "first" row from your data. 
    select 1, Rand(@Seed) 
    union all 
    -- Add the "next" row from your data. 
    select Number + 1, Rand(1000000 * PseudorandomNumber) 
    from Numbers 
    where Number < 100 
), 
-- Add row numbers to the previous rowset to allow paging. 
NumbersWithRowNumber as (
    select *, Row_Number() over (order by PseudorandomNumber) as RowNumber 
    from Numbers 
) 
-- Select the requested page of data. 
select * 
    from NumbersWithRowNumber 
    where RowNumber between @PageSize * (@PageNumber - 1) + 1 and @PageSize * @PageNumber 
    order by RowNumber 
関連する問題