2

以下は、私が直面している設計の質問に類似した(そして単純化された)例です。

生徒、クラス、成績があるとします。学生は多くの異なるクラスに参加することができます。各クラスには多くの異なる生徒がいます。そして、すべての(学生、クラス)ペアには1つの成績があります。

データベース(mysqlデータベース)を次のようにレイアウトする必要があります:

オプション1)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id)
grades table - (student_class_id, grade)

オプション2)

students table - (student_id, student_name)
classes table - (class_id, class_name)
grades table - (student_id, class_id, grade)

それとも他のものとして設計する必要がありますか?オプション2は現在は単純に見えますが、将来的には、各(student_id、class_id)ペアに関連する他の統計が必要になる可能性があります(この場合、オプション1は少し良いように見えますか?オプション1はまだ少し複雑に感じます)。

おすすめは何ですか?ありがとう。

4

5 に答える 5

3

私は個人的にオプション2に行きます。成績の複合主キーには何の問題もありません。データモデルに必要な情報を取得します。

オプション1では、students_classesは代理キーを持つ以外の目的を果たしません。

他の回答を見た後、編集します。

  • 2NF:グレード(非キー)は学生/クラス(キー)のみに依存します
  • 3NF:適用されません。非キーの依存関係に非キーはありません
  • BCNF:適用されません。候補キーは1つだけです。
于 2010-11-19T20:30:56.147 に答える
3

オプション3)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id, grade)

成績は学生クラスの属性です。

Gradeが本格的なエンティティになる可能性がない限り。その場合:

オプション4)

students table - (student_id, student_name)
classes table - (class_id, class_name)
students_classes table - (student_class_id, student_id, class_id)
grades table - (grade_id, grade, student_class_id)
于 2010-11-19T20:41:20.637 に答える
1

student_classオプション2は正しいですが、n :: n関数、またはエンティティとしての登録を反映して呼び出される必要があります。PK(student_id, class_id)です。

グレード(あなたが示したように)は、その複合キー(いずれかの要素ではなく)への1:1の依存関係であり、他には何も依存しないため、の属性ですstudent_class

したがってstudent_class、3NFにあります。

オプション1の場合のように、移動するすべてのものに盲目的Idに列を貼り付けることから始めなかった場合、データをよりよく理解できるため、正規化が向上します。それ(開始点としてのオプション1の列)は、が識別子Idであるという直感を妨げました。追加のインデックスを持つ(student_id, class_id)追加の列は必要ありませんでした。Id次に、評価に取り掛かるgradeと、そのPKへの依存性は明らかです。

Id列はデータベースのリレーショナル機能を損ないます。階層内に3つのテーブルがあり、上部と下部のテーブルからいくつかの列を取得する必要がある場合は、中央のテーブルを通過する必要があります。ばかげた列の代わりにリレーショナル識別子がある場合は、真ん中のテーブルを読まなくてはならないので、一番下のテーブルから一番上のテーブルに移動します。

「正規化された」データベースに非常に多くの結合があることは、半分しか真実ではありません。完全な真実は、データベースが正しく正規化されていないため、はい、必要以上に多くの結合を強いられるということです。同じテーブルを持つ真に正規化されたデータベースでは、コードに必要な結合ははるかに少なくなります。

これは、最近の課題の簡略化されたバージョンからの>大学のデータモデル<です。

>IDEF1X表記<記号の説明が必要な方のために。

  • 必要なサロゲートキーは1つだけであることに注意してください。

  • これは、代替案では、(LastName + FirstName + Initials_BirthDate + BithDate)がPerson PKであり、5つの子/孫テーブル(81バイト)でFKとして運ばれるため、これは意味がありません。

  • 識別子(実線)が子供と孫に引き継がれていることを理解できるかどうかを確認してください。彼らは持っており、意味を伝えます

  • 外部キーであり、すでに一意である完全に優れたPersonIdがある場合、TeacherId、StudentId、StaffIdの代理キーを追加するのはばかげています。(列には、その役割を識別するためにそのように名前が付けられています。)

  • すべてのビジネスルールはDDLで実装されました:FK制約。制約を確認してください。ルール。

  • 部屋には4列の複合キーがあります。オファリングには3列の複合キーがあります。2つを一緒にすると、二重予約がなくなります。

  • オファリングPKとスチューデントPKが一緒になって、登録用PKを形成します(この質問と同じです。PKは異なる列で構成されています。それだけです)。

于 2010-11-28T05:23:41.433 に答える
0

私は第3正規形のファンです。この形式では、Student、Class、Gradeの各テーブルがあり、それらをClassStudentやGradeClassなどの多対多のテーブルにリンクしています。

しかし、それはあなたが将来それをどのように維持したいかに依存します。最終的には、将来の拡張と保守性に帰着します。それが私が3NFを好む理由です。

編集

Axnの答えは私のものよりはるかに優れています。

于 2010-11-19T20:27:11.310 に答える
-1

それはすべて、本当に異なります。オプション1は、おそらくこのアプリケーションを実行するための最も堅牢な方法です。オプション2を使用すると、この反復でより早くそこに到達できる可能性があります。オプション2->1からの変更は、将来、それほど苦痛になりますか?その余分な柔軟性が必要になると確信していますか?

オプション1を選択することをお勧めします。クエリはそれほど複雑ではなく、ORM(ActiveRecord for Railsなど)を使用している場合、違いは実質的にnullです。

于 2010-11-19T20:27:47.690 に答える