よく見かけるデザインパターンですが、名前がありません。設計者がこのパターンを何と呼んでいるか、また賢明なDB 設計でどのようにアプローチしているかを知りたいです。
簡単な例として、学生が学年(1 ~ 8) を持っているとします。学生のグレード レベルが 7 または 8 の場合、優等生の可能性があります。では、このビット フラグが特定の学年レベルの生徒にのみ適用されることを知っている生徒に対して、このビット フラグを追跡するにはどうすればよいでしょうか。
よく見かけるデザインパターンですが、名前がありません。設計者がこのパターンを何と呼んでいるか、また賢明なDB 設計でどのようにアプローチしているかを知りたいです。
簡単な例として、学生が学年(1 ~ 8) を持っているとします。学生のグレード レベルが 7 または 8 の場合、優等生の可能性があります。では、このビット フラグが特定の学年レベルの生徒にのみ適用されることを知っている生徒に対して、このビット フラグを追跡するにはどうすればよいでしょうか。
これをデータの依存関係と呼びます。すべてのデータ依存関係を直接、またはリレーショナル分解で簡単にモデル化できるわけではありません。これは、チェック制約を使用して非常に簡単に処理できます。
CREATE TABLE Students (
id SERIAL PRIMARY KEY, -- for example, something else in reality
grade INTEGER NOT NULL,
honors BOOLEAN,
CONSTRAINT ensure_honors_grade
CHECK((honors IS NULL AND grade < 7) OR
(honors IS NOT NULL AND grade >= 7))
);
別の解決策として、次の 2 つのテーブルを使用することもできます。
CREATE TABLE Students (
id SERIAL PRIMARY KEY,
grade INTEGER NOT NULL,
CONSTRAINT id_grade_unique UNIQUE (id, grade) -- needed for FK constraint below
);
CREATE TABLE Honors (
student_id INTEGER NOT NULL,
grade INTEGER NOT NULL,
honors BOOLEAN NOT NULL,
CONSTRAINT student_fk FOREIGN KEY (student_id, grade) REFERENCES Students(id, grade),
CONSTRAINT valid_grade CHECK(grade >= 7)
);
この代替設計は、学年と優等旗があるかどうかとの関係についてより明示的であり、7 年生から 8 年生の生徒をさらに区別する余地を残しています (テーブル名は改善する必要があります)。優等生ブール値の 1 つのプロパティしかない場合、これはおそらくやり過ぎです。@BrankoDimitrijevic が言及しているように、これはHonors
グレードが 7 または 8 であるという理由だけで行の存在を強制するものではなく、そうでなければ必要のないインデックスにもお金を払っています。したがって、トレードオフがあります。可能な設計はこれら 2 つだけではありません。Branko は、トリガーの使用も提案しています。
オブジェクト指向の設計に関しては、@Ryan は正しいですが、適切なリレーショナル データベース設計のために、一般に、継承パターンを特定しようとして問題にアプローチすることはありません。それがOOの視点です。アクセス パターンとコードがどのようにデータを取得するかを考慮することは常に重要ですが、リレーショナル データベースの設計では、最初にデータベースの正規化と柔軟性を追求し、2 番目にコードを追求します。コードベースがデータを取得していて、アクセスするコードにどんなにバグがあっても、データが常に有効であることを確認したい場合。
クラス モデルとその使用方法を考慮する必要があります。Honors
のブール値フラグとして表示されStudent
ますか? のようなif (grade > 6) Student.honor = true
?
一般に、これは継承マッピングのケースと考えることができます。Student
親クラスであり、サブクラスが であることを確認してくださいHonorStudent
。リレーショナル データベースで継承をマップするには、複数の方法があります。
基本クラスとサブクラスのすべての属性が存在するため、すべてを単一のテーブルにマップできますが、それらの一部は NULL または空に設定されます。たとえば、HonorStudent に属性 X がある場合、Student をテーブルにマッピングするときに属性 X を NULL に設定します。
もう 1 つのケースは、具体的なクラスごとにテーブルを持つことです。したがって、Student と HonorStudent 用に個別のテーブルが作成されます。
独自の属性を持つ Student と HonorStudent のテーブルを作成することもできます。サブクラスには、継承された属性以外の属性のように、サブクラスが持つ (または追加する) 属性を持つテーブルのみがあります。継承された属性は親テーブルにマップされ、一意の ID でリンクされます。
これがあなたが探していた答えかどうかはわかりませんが、それが私がそれを見る方法です。