1

現在、データベースのアイデアをいじっています。どのような方法でも展開されることはなく、むしろ学習体験です。

これは、私が通った大学の一連のクラスのチューター情報の収集と処理を簡素化することを目的としています。私は、学期ごとに少数のクラスの家庭教師を編成するオフィスでアルバイトをしていました。

いくつか質問がありますが、現在問題になっているのは、各チューターの空き状況をどのように保存できるかということです。現在、3 つのオプションを検討しており、技術的な観点からそれぞれの長所と短所についてフィードバックを求めています。

背景: チューター情報は「tutor」テーブルに保存され (tutorID はこれを参照します)、以前の可用性を呼び出せる必要があります。講師の空き状況は個別 (時間単位) で、学期を通じて一定です。

オプション1:

Table: Availability
+-----------+---------+-------+-------+---+---+---+----+---+
| avID (PK) | tutorID | year  |  sem  | M | T | W | Th | F |
|           |         | (int) | (int) |    (all strings)   |
+-----------+---------+-------+-------+---+---+---+----+---+

このテーブルでは、可用性が文字列に格納されます (08、09、10、13、14 は、午前 8 時、午前 9 時、午前 10 時、午後 1 時、および午後 2 時を表します)。

データは次の方法で再利用できます

SELECT * FROM Availability WHERE tutorID=0001 AND year=2013 AND sem=1

そして、誰が利用可能かを確認するには

SELECT * FROM Availability WHERE AND year=2013 AND sem=1 AND M LIKE '%08%'

オプション 2:

Table: Availability
+-----------+---------+-------+-------+--------------+
| avID (PK) | tutorID | year  |  sem  | availability |
|           |         | (int) | (int) |     (set)    |
+-----------+---------+-------+-------+--------------+

このレイアウトでは、可用性列は mysql に SET データ型として格納され、オプションは月から金曜までのすべての組み合わせと、8 から 4 までのすべての時間 (M08、M09... Th14、F16 など) です。これは、45 の許容値になります。これは私が現在傾いているものですが、SETデータ型についてはあまり知りません。

データは次の方法で再利用できます

SELECT * FROM Availability WHERE tutorID=0001 AND year=2013 AND sem=1

そして、誰が利用可能かを確認するには

SELECT * FROM Availability WHERE AND year=2013 AND sem=1 
                AND FIND_IN_SET('M09',availability) > 0

オプション 3:

Table: Availability
+-----------+---------+-------+-------+-------+-------+
| avID (PK) | tutorID | year  |  sem  |  day  | time  |
|           |         | (int) | (int) | (int) | (int) |
+-----------+---------+-------+-------+-------+-------+

このオプションでは、各チューターごとに毎年、各タイムスロットに 1 つの行があります。

データは次の方法で再利用できます

SELECT * FROM Availability WHERE year=2013 AND sem=2 AND tutorID=0001

可用性

SELECT * FROM Availability WHERE year=2013 AND sem=2 AND day=3 AND time=14

とにかく...すべてを読んでくれてありがとう。うまくいけば、誰かがこれに光を当てることができるでしょう。基本的にベストプラクティスタイプの質問になると思います。私が完全に見逃したものがない限り!!

4

1 に答える 1

3

リストされたオプションはどれも正規化されていません。基本的に正規化とは、リレーショナル データベース テクノロジの主なポイントと利点の 1 つであり、冗長な情報の格納を回避することです。

オプション1

要件については明確ではありませんでしたが、チューターは 1 日 1 時間以上利用できる可能性があると想定しています。1 日に複数のセッションをカバーするには複数の行が必要になるため、オプション 1 は扱いにくく、適合性が低くなります。他の列の値は行間で重複します。このような繰り返しは、正規化に違反することを意味します。

また、開始時刻のデータ型としてテキストを選択することは、おそらく最適ではありません。セッションが常に正時に開始される場合は、時間番号を扱っています。数値を扱う場合は、(原則として) 数値として格納します。セッションが常に正時に開始されるとは限らない場合は、時間の値を扱っています。同じ一般規則で、時間データ型として保存します。

year のデータ型として int を選択することは、おそらく明確ではありません。通常、学年度は「2013-2014」のようなものです。

オプション 2

オプション 2 では、複数のデータ ポイントを 1 つのフィールドに詰め込むことは、確実に正規化されていません。クエリは機能しますが、少なくとも 2 つの欠点があります。1 つはパフォーマンスです。通常、そのような複数値フィールドの検索は比較的遅くなります。しかし、より重要なことは、正規化に違反すると、ほとんどの場合、窮地に陥ることになります。これらの各タイム スロットに追加の値を結び付けたい場合はどうすればよいでしょうか。それはできません。なぜなら、これらのタイム スロットが一緒になってしまうと、各タイム スロットにアクセスできないからです。

オプション 3

オプション 3 では、正規化された計画に近づいています。しかし、複数のフィールドが一緒に繰り返されることに注意してください ( yearand sem)? 繰り返しますが、そのような重複は、正規化違反のフラグです。

一般化する

設計するときは、一般的に、考えを広げたり、一般化したりするのが良い習慣です。たとえば、セッションは常に正時に始まり、1 時間続くのでしょうか? ありそうもない。したがって、時間数ではなく Time 値を使用する方が賢明かもしれません。もう 1 つの例は、「学期」です。すべての学校が学期を使用しているわけではありません。したがって、「期間」に一般化して、学期に関連する仮定をしない方が賢明かもしれません。一方、過度に一般化しないでください。そうしないと、設計が無意味に混乱したり、分析麻痺に陥ったりする可能性があります。

ノーマライズ

正規化するには、「もの」、アクションを実行する可能性のあるもの、または他のものを「所有」するものを探します。これらをエンティティと呼びます。

tutorはすでに別のエンティティとして識別されています。良い。

私は別のものを見ます:(term学期)。その「年」と「セム」の繰り返しが手がかりです。このような繰り返しは、それらの値を別のテーブルに移動することで回避されます。そのテーブルは「用語」の実体のためのものです。別のテーブルが正しいというもう 1 つの手がかりは、タームの開始日と長さ (または終了日) などの他の情報を「ターム」テーブルに結び付けたいという考えです。このような追加データは、すべての「可用性」行で繰り返されるべきではありません。このようなデータは、テーブルの 1 つの行に 1 回格納する必要がありtermます。

私のデザイン

したがって、私の最初の設計はこの図のようになります。 多対多の関係にある 3 つのテーブル、Tutor、Availability、および Term の図

この関係は多対多です。各チューターは複数のタームで利用できる場合があり、各タームには複数のチューターがいる場合があります。多対多はリレーショナル設計の問題であり、常に3 番目の「ブリッジ」または「ジャンクション」テーブルで解決されます。多対多およびブリッジ テーブルは、ビジネス コンテキスト用に設計されたデータベースでは非常に一般的です。

ここで、それらの間のブリッジ テーブルは ですavailibility_。そのブリッジ テーブルは両方の子テーブルであり、それぞれの親の主キー (外部キー) を保持します。ヒント: 親 (ここでは青色) を子 (ここではオレンジ色) よりも垂直方向に高く配置すると、どちらかの側に親の「羽を上げた鳥の体」のパターンに気付くと、間に多対多の関係が存在することがわかります両親。


ちなみに正規化を破る場合もある。それを「非正規化」と呼びます。通常、目標はパフォーマンスに関連しています。ただし、非正規化は、他の経験豊富なデータベース設計者に相談した後にのみ行います。また、非常に正当な理由がある場合は、支払っている代償を明確に把握し、違反を完全に文書化して、後であなたの代わりになる可能性のある人々を教育してください。

于 2013-11-05T08:48:18.540 に答える