2009-06-20 2 views
0

데이터베이스에 ThingsInACircle이라는 테이블이 있습니다. ThingThingsInACircle에 추가 될 때마다 자동으로 증가되는 ThingId이 추가됩니다.주어진 ID와 동일한 id + offset 사이에서 행을 반환하려고 시도합니다. 데이터를 검색하는 방법을 결정하기 위해 대부분의 로직을 사용해야합니까? : BLL 또는 DAL

이 표의 Things을 원으로 상상해보십시오.
SELECT Thing FROM ThingsInACircle WHERE ThingId = 10
SELECT Thing FROM ThingsInACircle WHERE ThingId = 11 옆에 있습니다. 또한
...
SELECT Thing FROM ThingsInACircle WHERE ThingId = min(ThingId) 내가 말할 수 있어야합니다
SELECT Thing FROM ThingsInACircle WHERE ThingId = max(ThingId)

옆에 : 주어진 ThingId와 오프셋이 ThingsInACircle가 ThingId에서에 이르기까지의 모든 레코드를 반환 (ThingId + 오프셋) (오프셋은 음수 일 수 있음). 그래서

가 설정된 예를 들어 이것을 취

여기

우리 ThingIds 목록 : 1 2 3 4 5 6 7 8 9

I 모든 ThingIds 원한다면 여기서 @ThingId = 2 @ThingId = 8 @offset는 = 3, 다음이 어디에 나는 모든 ThingIds를 원하는 경우, 2 3 4 5

그러나 : 및 @offset = 3, 문제

SELECT ThingId FROM ThingsInACircle WHERE 
ThingId BETWEEN @ThingId AND (@ThingId + @offset) 

없다 그것은 반환 문제

기능은 반환해야합니다 : 7 8 9 1

그래서 여기 내 딜레마, 내 데이터 액세스 레이어(선택 최소, 최대를 더 복잡한 저장 프로 시저를 사용하는 쿼리를 포함하고 사용한다 &이면 초과했는지 여부를 확인하십시오.)을 사용하여 레코드를 원으로 링크 된 것으로 간주하기 위해 검색 할 레코드를 정확히 결정합니까?

또는 비즈니스 로직 계층는 사용자가 ID +가 최소 또는 최대 다음 사용 간단한 DAL 방법은 그것을 반환 할 필요가 무엇을 달성하기를 초과 오프셋 요청 여부를 결정해야한다?

이것은 단지 의견 일뿐입니다. 저는 방금 microsofts tutorial에 따라 3 일 전에 3 층 구조에 대해 배우기 시작했습니다. 그래서 사람들이 DAL과 BLL을 어떻게 형성해야한다고 생각하는지 알고 싶습니다. DAL이 간단해야하고 BLL이 모든 검증을해야한다면. .. 또는 다른 길 ... 또는 내가 함께 놓친 것.

+0

7에서 4 사이를 선택하면 반드시 7 8 9 1 2 3 4를 반환 할 필요는 없지만 MIN (ThingID)이 1 일 필요는 없다는 것을 고려하면 ThingID가 해당 범위에있는 레코드 만 반환하면됩니다. 그 사이에있는 모든 ID가 있다는 보장이 아닙니까? – Raj

답변

1
SELECT ThingId FROM ThingsInACircle 
WHERE 
    ThingId BETWEEN @ThingId AND (@ThingId + @offset) 
    OR 
    ThingID BETWEEN 1 AND (@ThingID + @Offset - @MaxID) 

@MaxID는 최대 물건 ID (원의 끝)입니다. 당신이 오버 플로우에 오프셋이없는 경우

일반적인 경우는 다음과 같습니다

두 가지 사례를 가지고있다. 이것은 두 번째로 완전히 다루어집니다.

두 번째 경우는 오버플로가 있고 경계 위에 오프셋을 적용해야하는 경우입니다. 이 경우 첫 번째 BETWEEN이 처리하는 @ThingID - @ThingID + @offset과 두 번째 BETWEEN이 처리하는 1 - ((@ThingID + @offset) - @MaxID) 범위가 있습니다.

오프셋이 @MaxID보다 높으면 모든 @ThingID를 고려해야하며이 경우도 두 번째로 적용됩니다.

+0

좋지 않음 - 1이 thingid의 최소값이라는 보장이 없다. maxid는 쿼리의 매개 변수도 아닙니다. –

0

일반적으로 RDBMS를 다루는 경우 DAL 이외의 다른 곳에서는 다루기가 더 쉽습니다. 다른 종류의 컬렉션 추상화 (배열, 컬렉션, 사전 등)는 사용하기가 더 쉽습니다.

0

대개의 경우 (비즈니스 환경에서) 비즈니스 로직으로 시작하는 것이 좋습니다 (즉, 서클의 마지막 항목이 첫 번째 항목 옆에 있음).

적어도 두 가지 쿼리를 수행해야합니다.

int maxThingId = // select max(thingId) 'maxThingId' from ThingsInACircle 
int minThingId = // select min(thingId) in the same query 

그래서 두 번째 쿼리가 정상적으로 될 것입니다 : 첫 번째는 thingIDs의 당신의 범위를 얻을 수

int lowerBound = requestedThingId; 
int upperBound = lowerBound + offset; 

다음의 경우, 세 번째 : 매개 변수가로 미리 계산 된

select thingId 
from ThingsInACircle 
where thingId > @lowerBound and thingId < @upperBound 

필요한 :

if(upperBound > maxThingId) { 
    upperBound -= maxThingId - minThingId; 
    // third query: 
    // select thingId from ThingsInACircle where thingId < @upperBound 
} 

성능 문제가 발생하거나 데이터 무결성 문제가있는 경우이 논리를 DAL로 옮길 수 있습니다.

+0

일반적으로 MIN (thingid)도 필요합니다. –

+0

좋은 지적. 임의 코드 ID에서 시작하는 범위를 수용하기 위해 의사 코드를 편집했습니다. –