0

私のデータベースには、 というテーブルがありますThingsInACircleThingaが に追加されるたびに、自動インクリメントThingsInACircleされる a が追加されます。ThingId

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 とオフセットについて、ThingId から (ThingId + オフセット) までの ThingsInACircle 内のすべてのレコードを返します (オフセットは負の場合があります)。

したがって、これを設定例として取り上げます。

ThingId のリストは次のとおりです: 1 2 3 4 5 6 7 8 9

@ThingId = 2 および @offset = 3 のすべての ThingId が必要な場合、問題はありません。

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

2 3 4 5 が返されます。

しかし、@ThingId = 8 で @offset = 3 のすべての ThingId が必要な場合は、問題があります。

関数は次を返す必要があります: 7 8 9 1

したがって、ここに私のジレンマがあります。データ アクセス レイヤーに、より複雑なストアド プロシージャ (最小値、最大値を選択し、if & else を使用して超過したかどうかを判断する)を使用して、処理するために取得するレコードを正確に決定するクエリが含まれている必要があります。円にリンクされているレコード?

または、ビジネス ロジック層は、ユーザーが最小値または最大値を超える ID + オフセットを要求したかどうかを判断し、単純な DAL メソッドを使用して返す必要があるものを達成する必要がありますか?

これは単なる意見の問題かもしれません。マイクロソフトのチュートリアルに従って、2 日前に 3 層構造について学び始めたばかりなので、一部の人々が DAL と BLL をどのように形成する必要があると考えているかを知りたいだけです。 ... またはその逆... または、私が一緒に逃した何か。

4

3 に答える 3

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

@MaxID はモノの最大 ID (円の終わり) です。

次の 2 つのケースがあります。

通常のケースは、オフセットにオーバーフローがない場合です。これは、2 番目の間で完全にカバーされます。

2 番目のケースは、オーバーフローがあり、境界を越えてオフセットを適用する必要がある場合です。この場合、範囲 @ThingID - @ThingID + @offset が最初の BETWEEN によって処理され、1 - ((@ThingID + @offset) - @MaxID) が 2 番目の BETWEEN によって処理されます。

オフセットが @MaxID よりも大きい場合は、すべての @ThingID を考慮する必要があり、このケースは 2 番目の間でもカバーされます。

于 2009-06-20T21:30:39.700 に答える
0

ほとんどの場合(そしてこの状況では)、ビジネス層のビジネスロジック(つまり、円の最後のものが最初のものの隣にある)から始めることをお勧めします。

これは、少なくとも2つのクエリを実行することを意味します。1つ目は、thingIDの範囲を取得します。

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

したがって、2番目のクエリは通常次のようになります。

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

ここで、パラメータは次のように事前に計算されています。

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

次に、必要に応じて3番目の:

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

パフォーマンスの問題が発生し始めた場合、またはデータの整合性などの問題が発生した場合でも、このロジックをDALに移動することを検討できます。

于 2009-06-20T22:11:03.237 に答える
0

特にRDBMSを扱っている場合は、通常、これらはDAL以外の場所で扱う方が簡単だと思います。他の種類のコレクションの抽象化 (配列、コレクション、辞書など) を使用する方が簡単です。

于 2009-06-20T21:57:45.167 に答える