2011-01-25 22 views
4

現在、複数のエンティティが営業時間に関連付けられているアプリケーションを開発中です。営業時間は複数日に及ぶか、1日以内に含まれることがあります。営業時間データベース設計

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

または

開封月曜日は06:00、月曜日は15:00を閉じます。

また、エンティティは1日に複数の営業時間を設定することができます。 これまでのところ、私が見つけた最高のデザインは、以下のもので構成されるオープニングアワーを定義することです:

StartDay、StartTime、EndDay、EndTime

この設計では、必要な柔軟性がすべて得られます。ただし、データの整合性が問題になります。私は(データベース内の)スパンの重複を許さない解決策を見つけることができないようです。

あなたの考えをお伝えください。

EDIT:データベースは、Microsoft SQL Server 2008 R2の

+1

どのデータベースシステムを使用していますか?これは、私たちが解決策(制約、トリガー、計算フィールドなどを介して)に関して提供できるものを定義するのに役立ちます。 –

答えて

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 
+1

挿入または更新が実行された後にトリガが起動されるため、何らかの形で変更をロールバックする必要があります。ちょうどあなたが記述するように。挿入された正しい行を削除することはできないようですが、アップデートをロールバックする方法もありません。 – DEHAAS

+0

ロールバックステートメントを追加しました –

+0

これはかなり素晴らしい解決策です。並行処理の問題で間違ったタイミングでトリガが実行されないことを保証できますか? – DEHAAS

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 
+0

私はこの解決法についても考えました。ただし、1つの営業時間定義のタイムスパンが重複する問題は解決されますが、エンティティが複数の営業時間定義を持つ場合でも問題は残ります。 – DEHAAS

0

テーブルが1つの列TimeOfChangeBetweenOpeningAndClosing?

さらに深刻なことに、私はおそらく、すべてを表すための単一のデータベース構造を思いつくことについてあまり心配しないだろう。結局は、再発、予定されたクロージャーなどのシステムが必要になるだろう。それらを評価して閉鎖/開業時間を調べる。

+0

どのようにデルタ値を保存するだけで重複が防止されますか? –

+0

基準日を出発点にする必要がありますが、これは悪い解決策ではありません。私がここで見ている最大の問題は、1つの期間を調整するには、補償するために両側の2つを調整する必要があるということです。 – Kendrick

+0

+1箱の外で思考し、大きな絵に質問を向ける。 –

0

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

+0

これは当然の解決策になります。しかし、私は、そのような解決策がすべて可能であれば、一貫性のないデータが不可能であることを確実にすることを望んでいます。 – DEHAAS

0

これは良い解決策のようですが、カスタム検証機能を作成する必要があります。組み込みのデータベース検証(つまり、ユニーク、x未満など)は、ここではそれをカットしません。重複するスパンがないように、レコードをデータベースに挿入するたびに、既存のレコードを選択して比較する必要があります。

+0

この種の検証をデータベース内に記述することは可能ですか、それをアプリケーションレベルのビジネスロジックに組み込む必要がありますか? – DEHAAS

+0

あなたは、@ Russell Steenが何を提案したかなど、データベースレベルで記述することができます。 – Kendrick

0

最初に論理、2つのスパンが重複します1の値は、他方の開始/終了の間にある。 date1、time1、date2、time2ではなく、datetimesを結合した方がずっと簡単です。したがって、重複を見つけるためのクエリは次のようになります。

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

これをトリガーに入れて、一致するものが見つかるとエラーをスローすることができます。挿入時に強力なトリガフレームワーク

を推定

1

あり、同様の問題を論じてhereオーバーSimpleTalkのウェブサイト上のジョー・セルコの記事は、だ、と複雑なソリューション場合のプレゼントは、エレガントです。これはおそらくあなたの状況に当てはまります。