ユーザーが特定の日に出席を記録したかどうかを記録するデータを保存しています。重要でない日(休日、週末)があるため、それらも保存されます。
2つの要件は次のとおりです。
今のところ、データの保存方法について2つのオプションに直面しているようです。それぞれに独自の利点と欠点があります。
オプション1:2つのテーブル
テーブルcalendar
-カウントされない日数を追跡します
date | log |
-----------+-----|
2019-01-10 | DNL | // "Do Not Log" - holiday etc.
2019-01-12 | NB | // "Non-business day"
2019-01-13 | NB |
テーブルlogs
-成功した出席ログを追跡します
user_id | date |
--------+------------|
1 | 2019-01-08 |
1 | 2019-01-09 |
2 | 2019-01-09 |
// It's implied that user #2 missed their log on Jan. 8
利点:
課題:
オプション2:1つのテーブル(私が試したこと)
テーブルcalendar
-カウントするログとカウントしない日を追跡します
date | user_id | log |
2018-01-09 | 1 | 1 | // Counted, logged
2019-01-10 | 1 | DNL | // Not counted
2019-01-11 | 1 | NB | // Not counted
2019-01-09 | 2 | NULL | // Counted, missed log
利点:
課題:
log
== NULL
)。走査はオプション1より遅くなります。私の質問はこれです:オプション1を使用して、何らかの理由で失われたログの数をエンコードする方法はありますか、または両方の要件を満たすデータを格納する他の方法はありますか?オプション2を試してみましたが、スケーリングが非常に困難になりました。アドバイスを事前にありがとう。
両方のデザインを台無しにするいくつかのケースを以下に示します:教師は病気になります。労働組合はストライキを行っている。サーバーがダウンします。雪の日が起こります。
クラスは、シラバスの内容に関係なく発生します。したがって、未来がどうなるかを知っているふりをするのではなく、発生したイベントを記録するだけです。
イベント:
欠席=クラス日-出席
利点:設計では、紛らわしい誤解を招く説明のないヌルを使用する必要がありません。
必要なのはこれに沿ったものです:
Calendar {
DateId int not null;
Date datetime not null;
}
DoLogDay {
DateId int not null (foreign key to DateId column in Calendar);
LogDay bit not null;
}
UserLog {
DateId int not null (foreign key to DateId column in Calendar);
UserId int not null;
}
DateIdを導入する理由は、実際の日/月/年がスキーマで一度だけ指定されるためです。ユーザーの出席状況を記録するにはDateIdを調べる必要がありますが、アプリの起動時にDateIdと日付のマッピングをフェッチしてキャッシュできると思います。
また、DateIdsの使用は、DBのコード内の日付で発生する可能性のある奇妙さを取り除いたため、計算を行う必要があるときにインデックスに適した列があることを意味します(奇妙な動作があるとは言っていませんが、しかし、私は奇妙な問題がintよりも日付の可能性が高いと予想します)。
インデックスを使用すると、挿入が遅くなります(テーブルを更新するだけでなく、インデックスを更新する必要があります)が、この挿入時間の増加は問題にならない可能性があります。初期データベースを構築するときにインデックスを追加する必要はありません。確かに、インデックスの有無にかかわらずパフォーマンステストを行うことができます。インデックスビットをDateIdの「ボーナス」と考えてください。 DateIdは、「主要な」目的としての冗長な日付を取り除きます。