web-dev-qa-db-ja.com

タイプ/サブタイプの設計パターン(相互に排他的なサブクラスの場合)の実装は正しいですか?

前書き

この質問が将来の読者に役立つように、私は一般的なデータモデルを使用して、直面している問題を説明します。

データモデルは2つのエンティティで構成され、AおよびBのラベルが付けられます。物事をシンプルに保つために、すべての属性はintタイプになります。

エンティティAには次の属性があります:DおよびX;エンティティBには次の属性があります:DおよびY;

問題

両方のエンティティが共通の属性Dを共有しているため、type/subtype設計を適用することにしました。

私の実装が正しいかどうかはわかりません。そのため、ここでデザインレビューをお願いしています。

私の実装

-- lookup table for discriminator column
CREATE TABLE ClassType
(
  ClassTypeID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
  Class_Description VARCHAR(50) NOT NULL
);

-- inserting types A and B from our example 
INSERT INTO ClassType (Class_Description)
VALUES ('A'), ('B');

-- creating base class table
CREATE TABLE BaseClass
(
  BaseClass_ID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
  ClassTypeID INT NOT NULL, -- FK to Type
  D int
);

ALTER TABLE BaseClass
ADD CONSTRAINT [FK_BaseClass_ClassType]
FOREIGN KEY (ClassTypeID)
REFERENCES ClassType (ClassTypeID);

-- we need this constraint in order for foreign keys in subclasses to work
ALTER TABLE BaseClass
ADD CONSTRAINT [FK_AltKey]
UNIQUE (BaseClass_ID, ClassTypeID);

-- creating subclasses:
CREATE TABLE SubclassA
(
  BaseClass_ID INT NOT NULL PRIMARY KEY,
  X int,
  ClassTypeID AS 1 PERSISTED -- calculated field, ensures integrity
);

ALTER TABLE SubclassA
ADD CONSTRAINT [FK_SubclassA_BaseClass]
FOREIGN KEY (BaseClass_ID, ClassTypeID)
REFERENCES BaseClass (BaseClass_ID, ClassTypeID);

CREATE TABLE SubclassB
(
  BaseClass_ID INT NOT NULL PRIMARY KEY,
  Y int,
  ClassTypeID AS 2 PERSISTED -- calculated field, ensures integrity
);

ALTER TABLE SubclassB
ADD CONSTRAINT [FK_SubclassB_BaseClass]
FOREIGN KEY (BaseClass_ID, ClassTypeID)
REFERENCES BaseClass (BaseClass_ID, ClassTypeID);

これは、SQL Server 2012でのデータベースダイアグラムの外観です。

Database Diagram

ご質問

  • 私の実装に間違いをしましたか?
  • (サブクラステーブル内の)クラスタイプを計算して永続化する以外に、INSERT/UPDATE/DELETE中の間違いを防ぐために他にできることはありますか?

はい、デザインは素晴らしく見えます。マイナーなメモ:

  • TINYINTINTの代わりに、ClassTypeIDを使用できます。またはCHAR(1)であり、_'A'_および_'B'_の代わりに_1_および_2_を使用することもできます。 4の代わりに1バイトは、保存することを意味します各行に3バイト、3つのテーブルすべて、およびClassTypeIDを含むすべてのインデックスに-ClassTypeIDがクラスター化の一部である場合、これらのテーブルのすべてのインデックスになりますキー。

  • ベーステーブルとサブタイプテーブルの両方の属性は_NOT NULL_になります。このデザインでは、なぜそれらをnull可能にしたいのかわかりません。

  • ベーステーブルのUNIQUE制約とそれを参照する2つの外部キーの両方が逆順_(ClassTypeID, BaseClass_ID)_で定義されている場合は、より良いかもしれません(しかし、徹底的なテストが必要です)。これは、索引付け/物理設計の提案であり、論理設計を変更するものではありません。この順序を使用して、クラスター化されたキーをベーステーブルに含めることも試してみました。

6
ypercubeᵀᴹ