2009-09-02 7 views
1

私のアプリケーションでは、ユーザーは利用可能な日付を定義することができます。つまりユーザーjoeは彼が利用可能であると定義することができます。
- 毎週月曜日、水曜日と日曜日の15:00から17:00の間、1.09.2009から15.11.2009までです。 - 〜2.09.2009〜12:00〜14:00 など...周期的な日付のテーブルデザイン

将来の日付は最大1年とすることができます。

ユーザーは、定義された日付を追加、編集、削除することができます。

他のユーザーが利用可能なユーザーを検索する場合があります。 - 利用可能なすべてのユーザーを検索します。8.09.2009 at 15:30

問題は、循環日付の作成と編集と効率的な検索を可能にするSQLテーブルの設計方法です。

私はpostgresqlを使用していますが、ガイドラインを探しています。たぶん誰かが同じような問題を経験しているのでしょうか?あなたは、データベース内のユーザーの可用性を保存し、データベース自体に複雑なロジックを持つのではなく、状況を確認するには、プログラミング言語を使用したいと思うでしょう事前

答えて

1

私は前に、このようなデータを扱ってきたとき、私はバイ日スケジューリングとブロックスケジューリングを収容するために次のような「ルール」的なアプローチを取った:

CREATE TABLE availability_rules (
    id SERIAL UNIQUE, 
    user_id NOT NULL REFERENCES users(id), 
    day_of_week INTEGER CONSTRAINT valid_day_of_week CHECK (day_of_week BETWEEN 0 and 6) 
    start_time TIME, 
    start_date DATE, 
    end_time TIME, 
    end_date DATE 
); 

注:あなたがする必要があるだろうしルールテーブルに制約を追加して、end_date + end_time> = start_date + start_timeなどを確認してください。

次に、user_id、date、start_time、およびend_timeを使用して正規化されたスケジュールを生成するために、 。 8.4を使用すると、これは新しいgenerate_series datetime機能で簡単に実行できます。 (http://www.postgresql.org/docs/current/static/functions-srf.html)8.3以前であれば、同じことをする関数を書くのは簡単です。

+0

constrainstsは間違いなく良い考えです。私の現在のアプローチではgenerate_seriesを使用していますが、レコードが膨大になると効率が悪く、インデックスは使用されません。 – mlomnicki

+0

あなたは大丈夫だと思います。しかし、最大限のパフォーマンスを得るために、ビューをキャッシュされた可用性テーブルに具体化し、すべてを一度に更新するのではなく、変更されたルールと方法に基づいてトリガーを使用して選択的に挿入または更新します。次に、マテリアライズド・ビューに対して問合せを実行して、ルールを個別に維持しながら可用性を得ることができます。 そのルートに行く前に、パフォーマンスを測定するために、ビューに対してEXPLAIN ANALYZEを実行する必要があります。 –

+0

これは間違いなく最良の提案です。しかし、キャッシュされたアベイラビリティテーブルについては何も見つかりませんでした。どのようにポストグルでそれを処理するには?私にリンクや基本的なガイドラインを教えてください。 – mlomnicki

0

感謝。 ORMツールを使用すると、これが簡単になります。

ユーザーのアベイラビリティは、日時のペアのリストで構成されます。あなたは、日時に基づいて検索を3列(ユーザを識別するために単一のID COLを想定)

availability_start, availability_end, user_id 

と可用性を格納することになる

+0

数百万のレコードがあります。私はアプリケーションレベルでやっていくのが遅すぎるのではないかと心配しています。 – mlomnicki

1

オプション1

は次に

ようなものであろう
select 
    user_id 
from 
    availability 
where 
    desired_datetime > availability_start 
and 
    desired_datetime < availability_end 

提供したい機能に応じて過去の日付を削除することができます。明らかに、人々の周期的な日付定義に基づいて日付を格納するための未来への距離を決定する必要があります。それは常にその日のために週回の個々の日を選択するのと同じくらい簡単である場合

オプション2

。周期的な日付を保存することができます

user_id, day_of_week, availability_time_start, availability_time_end 

開始日と終了日には日付の構成要素が不要です。さておき、私たちはthis(Javaの)を使用する作業などの定期的な日付パターンを作成を支援するライブラリが存在するとして、曜日と時間に基づいて検索する

select 
    user_id 
from 
    availability 
where 
    desired_day_of_week = day_of_week 
and 
    desired_time > availability_time_start 
and 
    desired_time < availability_time_end 

よう

ものになるだろうあなたに適した言語でRFC 2445の実装が存在する可能性があります。

このようなものを使用すると、実際の日付は保存されませんが、問題の実際に役立たない定期的なパターンの詳細だけが保存されます。これらの詳細は、単に反復定義から値を取り出し、db 1フィールドから1カラムに永続化するだけで保存します。

また、定義された一定時間の日付/時刻を保存し、繰り返し定義の変更時にこれらを再計算することもできますが、これは明らかに人のスケジュールの数や将来はデータを保存したいと考えています。

+0

最大日付についての説明を追加しました。限り、私はRFC2445をエクスポートカレンダーのためにのみ使用されることがわかっている限り。私はdbにicalendar形式を格納する方法を想像することはできませんし、それを検索します。私は単純なアイディアが好きですが、それは単純すぎると思います。周期的な日付の保存と編集はどうですか? – mlomnicki

+0

私はオプション2を追加しました。これは助けになるかもしれません。単にRFC 2445の定義をそのまま維持する方法についての簡単な言及があります。 – Robin

0

何を行う可能性は次のようなデザインを持つテーブルを持っている:どちらでしょう

Availability 
    - userId, Foreign key to user table 
    - startDate, datetime 
    - endDate, datetime 
    - startTime, datetime 
    - endTime, datetime 
    - monday, bit 
    - tuesday, bit 
    - wednesday, bit 
    - thursday, bit 
    - friday, bit 
    - saturday, bit 
    - sunday, bit 

今、あなたは、次の(MSSQLのyntax)と、特定の平日に利用可能かどうかを確認することができます

SELECT * FROM User u WHERE EXISTS(
    SELECT 1 FROM Availability WHERE userId = u.id AND 
    @startDate >= startDate AND @endDate <= endDate AND 
    @startTime >= startTime AND @endTime <= endTime AND 
    (monday = 1 OR tuesday = 1) 
) 

@startTimeと@endTimeの間の月曜日または火曜日に@startDateと@endDateの間で利用可能なすべてのユーザーを提供します。

+0

これは非常に興味深いアイデアです、今すぐチェックします – mlomnicki

関連する問題