2012-05-04 4 views
1

데이터 소스에는 약. 5000 기록. orderby newid()으로 데이터를 임의로 주문할 수 있음을 알고 있습니다. 그러나 정렬 할 데이터는 페이징해야합니다. 이는 페이지 n이 이전 페이지 (n-1, n-2 등)의 레코드를 포함 할 수 없음을 의미합니다. 이제 나는 데이터베이스 또는 메모리에서의 순서 (5000 개의 레코드가 메모리 캐시에 저장할 수있을만큼 작기 때문에)를 취할 수있는 2 가지 방법이 있다고 생각한다.데이터베이스 또는 메모리에 무작위로 결과 세트를 정렬 할 위치는?

옵션 1 (db로 정렬)의 경우 데이터를 페이징해야하기 때문에 가능한지 확실하지 않습니다. 그렇다면 어떻게 할 수 있습니까? 옵션 2의 경우 메모리에 데이터를 정렬하기 위해 좋은 알고리즘이 있습니까 (성능이 좋고 임의적 인 분류기가 있습니까)? 이 시나리오에서 메모리 나 데이터베이스로 주문하는 이유는 무엇입니까?

+0

무작위 화의 범위는 무엇입니까? 단일 사용자가 페이지를 넘길 때 일관되게 임의의 순서로 목록을 보길 원합니다. 다른 사용자는 그것을 다르게 본다? 목록을 다시 방문하는 단일 사용자는 매일 그것을 어떻게 보나요? – HABO

+0

페이징 및 주문은 프리젠 테이션 레이어 작업입니다. 나는 app에 투표합니다. – 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