4

現在、複数のエンティティが営業時間を関連付けるアプリケーションを開発しています。営業時間は複数日にわたる場合もあれば、1 日内に含まれる場合もあります。

元。月曜日は 6:00 に開店し、金曜日は 18:00 に閉店します。

または

月曜日は 06:00 に開店し、月曜日は 15:00 に閉店します。

また、エンティティには、1 日に複数の営業時間のセットがある場合があります。これまでのところ、私が見つけた最良の設計は、営業時間を次のように定義することです。

StartDay、StartTime、EndDay、および EndTime。

この設計により、必要なすべての柔軟性が実現されます。ただし、データの整合性が問題になります。(データベース内で)スパンの重複を禁止するソリューションが見つからないようです。

あなたの考えを共有してください。

編集: データベースは Microsoft SQL Server 2008 R2 です

4

7 に答える 7

2

StartDay と StartTime を保存することを検討してください。ただし、開いている時間数の値を用意してください。これにより、クロージング日時がオープニングよりも後であることが保証されます。

OpenDate -- day of week? e.g. 1 for Monday
OpenTime -- time of day. e.g. 08:00
DurationInHours -- in hours or mins. e.g.   15.5
于 2011-01-25T17:58:34.160 に答える
1

堅牢なトリガー フレームワークの想定

挿入/更新時に、新しい開始日または終了日が既存の範囲内にあるかどうかを確認します。その場合は、変更をロールバックします。

CREATE TRIGGER [dbo].[mytable_iutrig] on [mytable] FOR INSERT, UPDATE AS

IF (SELECT COUNT(*)
FROM inserted, mytable
WHERE (inserted.startdate < mytable.enddate 
          AND inserted.startdate > mytable.startdate)
      OR (inserted.enddate < mytable.enddate 
          AND inserted.enddate > mytable.startdate)) > 0 
BEGIN
    RAISERROR --error number
    ROLLBACK TRANSACTION
END
于 2011-01-25T18:15:07.743 に答える
1

SimpleTalk の Web サイト (こちら)に Joe Celko による記事があり、同様の問題について説明しており、複雑な場合でも洗練されたソリューションを提示しています。これはおそらくあなたの状況に当てはまります。

于 2011-01-25T18:52:10.680 に答える
1

重複する期間の検出と防止は、アプリケーション レベルで行う必要があります。もちろん、データベースでトリガーを使用することもできますが、私の意見では、これはデータベースの問題ではありません。思いついた構造は問題ありませんが、アプリケーション ロジックでオーバーラップを処理する必要があります。

于 2011-01-25T17:59:54.150 に答える
0

これは良い解決策のように見えますが、カスタム検証関数を作成する必要があります。組み込みのデータベース検証 (一意、x 未満など) は、ここでは役に立ちません。スパンが重複しないようにするには、レコードをデータベースに挿入するたびに、既存のレコードを選択して比較する必要があります...

于 2011-01-25T18:00:15.880 に答える
0

TimeOfChangeBetweenOpeningAndClosing の列が 1 つのテーブルですか?

もっと深刻なことに、すべてを表現するための単一のデータベース構造を考え出すことについては、おそらくあまり心配しないでしょう。最終的には、繰り返し、計画的な閉鎖などを含むシステムが必要になるでしょう。それらを表すオブジェクトを永続化し、それらを評価して見つけます閉店/開店時間外。

于 2011-01-25T17:59:39.960 に答える
0

最初のロジックは、一方の開始値が他方の開始/終了の間にある場合、2 つのスパンがオーバーラップします。これは、date1,time1 と date2,time2 の代わりに datetime を組み合わせた方がはるかに簡単です。したがって、オーバーラップを見つけるためのクエリは次のようになります。

select openingId
  from opening o1
  join opening o2 on o1.startDateTime 
             between o2.startDateTime
                 AND o2.endDateTime

これをトリガーに入れて、一致が見つかった場合にエラーをスローできます。

于 2011-01-25T18:12:39.397 に答える