この質問が将来の読者に役立つようにするために、私は一般的なデータモデルを使用して、私が直面している問題を説明します。
データモデルは3つのエンティティで構成され、A
、B
、C
のラベルが付けられます。物事をシンプルに保つために、すべての属性はint
タイプになります。
エンティティA
には次の属性があります:D
、E
およびX
;
エンティティB
には次の属性があります:D
、E
およびY
;
エンティティC
には次の属性があります:D
およびZ
;
すべてのエンティティが共通の属性D
を共有しているため、私はtype/subtype設計を適用することにしました。
重要:エンティティは相互に排他的です!これは、エンティティがA、B、またはCのいずれかであることを意味します。
エンティティA
およびB
には、もう1つの共通属性E
がありますが、この属性はエンティティC
には存在しません。
上記の特性を使用して、可能であればデザインをさらに最適化します。
正直なところ、これを行う方法も、どこから始めればよいかわからないので、この投稿。
Martin Fowlerによると、テーブル継承の問題には3つのアプローチがあります。
これらを出発点として、各アプローチの長所と短所を探すことができます。その要点は、allアプローチには大きな欠点があり、noneには圧倒的な利点があります。 オブジェクトリレーショナルインピーダンスミスマッチ として知られるこの問題は、まだ解決策を見つけることができません。
個人的に、悪いリレーショナル設計がもたらす可能性のある問題のタイプは、悪いタイプから発生する問題の種類よりもはるかに深刻であることがわかりました 設計。データベースの設計が悪いと、クエリが遅くなり、更新の異常、データサイズの急増、デッドロック、応答のないアプリ、数十から数百ギガバイトのデータが誤った形式で沈み込みます。不正な型の設計は、ランタイムではなくcodeの保守と更新を困難にします。したがって、私の本では、正しいリレーショナル設計がすべてのOO型の純度を何度も繰り返し上回っています。
あなたの仕様の私の解釈によると、2つの異なる(ただしconnected) supertype-subtype 構造を実装するメソッドを見つけたいと思っています。
前述のタスクを達成するためのアプローチを公開するために、問題のシナリオに、Foo
およびBar
と呼ばれる2つの従来のhypotheticalエンティティタイプを追加します。
次に、論理モデルの作成に役立ついくつかのステートメントを示します。
A Foo is either one Bar or one C
A Foo is categorized by one FooType
A Bar is either one A or one C
A Bar is classified by one BarType
そして、結果のIDEF1X [1] 論理モデルを 図1 に示します(そして、 = DropboxからPDF としてダウンロードすることもできます):
フーとバーの追加
モデルをより見栄えよくするためにFoo
とBar
を追加しませんでしたが、より表現力を高めるためです。次の理由により、これらは重要であると思います。
A
とB
はE
という名前の属性を共有するため、この機能はが異なる(ただし関連する)種類のサブエンティティタイプであることを示しますコンセプト、イベント、person、Measurementなど。これは、Bar
スーパーエンティティタイプを使用して表しています。これは、Foo
のサブエンティティタイプであり、D
属性を上部に保持しています。階層。
C
は、議論中の残りのエンティティタイプ(つまり、D
)と1つの属性のみを共有するため、この側面ほのめかしは、別の種類のサブエンティティタイプコンセプト、event、person、Measurementなどなので、この状況をFoo
スーパーエンティティタイプのおかげで描きました。
ただし、これらは単なる仮定であり、リレーショナルデータベースは特定のビジネスコンテキストのセマンティクスを正確に反映することを目的としているため、すべての対象物を特定して分類する必要があります。特定のドメイン。正確に、より多くの意味を捉えることができます。
設計段階での重要な要素
すべての用語を別にしておくと、排他的なスーパータイプとサブタイプのクラスターは通常の関係であることを認識しておくと非常に便利です。次のように状況を説明します。
したがって、これらの場合には、1対1(1:1)の対応(またはカーディナリティ)があります。
以前の投稿からわかるように、discriminator属性(列、実装されている場合)は、この性質のAssociationを作成するときに最も重要な役割を果たします。スーパータイプはconnectedです。 (i)スーパータイプから(ii)サブタイプへのPRIMARY KEYの移行も重要な意味を持っています。
次に、上記の論理モデルに基づくDDL構造を記述しました。
CREATE TABLE FooType -- Look-up table.
(
FooTypeCode CHAR(2) NOT NULL,
Description CHAR(90) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_FooType PRIMARY KEY (FooTypeCode),
CONSTRAINT AK_FooType_Description UNIQUE (Description)
);
CREATE TABLE Foo -- Supertype
(
FooId INT NOT NULL, -- This PK migrates (1) to ‘Bar’ as ‘BarId’, (2) to ‘A’ as ‘AId’, (3) to ‘B’ as ‘BId’, and (4) to ‘C’ as ‘CId’.
FooTypeCode CHAR(2) NOT NULL, -- Discriminator column.
D INT NOT NULL, -- Column that applies to ‘Bar’ (and therefore to ‘A’ and ‘B’) and ‘C’.
CreatedDateTime DATETIME NOT NULL,
CONSTRAINT PK_Foo PRIMARY KEY (FooId),
CONSTRAINT FK_from_Foo_to_FooType FOREIGN KEY (FooTypeCode)
REFERENCES FooType (FooTypeCode)
);
CREATE TABLE BarType -- Look-up table.
(
BarTypeCode CHAR(1) NOT NULL,
Description CHAR(90) NOT NULL,
CONSTRAINT PK_BarType PRIMARY KEY (BarTypeCode),
CONSTRAINT AK_BarType_Description UNIQUE (Description)
);
CREATE TABLE Bar -- Subtype of ‘Foo’.
(
BarId INT NOT NULL, -- PK and FK.
BarTypeCode CHAR(1) NOT NULL, -- Discriminator column.
E INT NOT NULL, -- Column that applies to ‘A’ and ‘B’.
CONSTRAINT PK_Bar PRIMARY KEY (BarId),
CONSTRAINT FK_from_Bar_to_Foo FOREIGN KEY (BarId)
REFERENCES Foo (FooId),
CONSTRAINT FK_from_Bar_to_BarType FOREIGN KEY (BarTypeCode)
REFERENCES BarType (BarTypeCode)
);
CREATE TABLE A -- Subtype of ‘Bar’.
(
AId INT NOT NULL, -- PK and FK.
X INT NOT NULL, -- Particular column.
CONSTRAINT PK_A PRIMARY KEY (AId),
CONSTRAINT FK_from_A_to_Bar FOREIGN KEY (AId)
REFERENCES Bar (BarId)
);
CREATE TABLE B -- (1) Subtype of ‘Bar’ and (2) supertype of ‘A’ and ‘B’.
(
BId INT NOT NULL, -- PK and FK.
Y INT NOT NULL, -- Particular column.
CONSTRAINT PK_B PRIMARY KEY (BId),
CONSTRAINT FK_from_B_to_Bar FOREIGN KEY (BId)
REFERENCES Bar (BarId)
);
CREATE TABLE C -- Subtype of ‘Foo’.
(
CId INT NOT NULL, -- PK and FK.
Z INT NOT NULL, -- Particular column.
CONSTRAINT PK_C PRIMARY KEY (CId),
CONSTRAINT FK_from_C_to_Foo FOREIGN KEY (FooId)
REFERENCES Foo (FooId)
);
この構造を使用すると、ベーステーブル(または relations )でのNULLマークの格納を回避できます。これにより、データベースが不明確になります。
データベースを実装したら、(a)各排他的スーパータイプ行が対応するサブタイプの対応する行によって常に補完されていることを確認し、次に(b)そのような_を保証する必要があります。subtype行は、スーパータイプdiscriminator列に含まれる値と互換性があります。したがって、データベースでこれらの条件が確実に満たされるようにするために、ACID TRANSACTIONS
を使用すると非常に便利です。
データベースの論理的な健全性、自己表現、正確さをあきらめてはいけません。これらは、データベースをより強固にする要素です。
以前に投稿された2つの回答には、データベースとそのアプリケーションプログラムを設計、作成、および管理する際に考慮する価値のある適切なポイントがすでに含まれています。
さまざまなスーパータイプ-サブタイプgroupsの列を結合するビューを設定できるため、必要なJOIN句を毎回作成することなく、手元のデータを取得できます。このようにして、目的のビュー(派生リレーションまたは table )から直接簡単に選択できます。
ご覧のように、「テッド」コッドは間違いなく天才でした。彼が遺贈したツールは非常に強力でエレガントであり、もちろんお互いによく統合されています。
スーパータイプとサブタイプの関係を含む広範なデータベースを分析する場合は、 extraordinary @PerformanceDBA によって提案された次のスタックオーバーフローの質問に対する回答の価値があります。
[O] ne table or many for many different but interacting events? 、nestedサブタイプで構成されます。
1.情報モデリングの統合定義( IDEF1X )は、 standard 1993年12月、米国国立標準技術研究所( [〜#〜] nist [〜#〜] )。 (a) E. F. Codd博士が作成した初期の理論的資料にしっかりと基づいています。 (b)Entity-Relationship データのビュー- Dr。P. P. Chen によって作成されました。また、(c)には、Robert G. Brownによって作成された論理データベース設計手法も含まれています。 IDEF1Xが一次論理によって形式化されたことは注目に値します。