はい、多対多(簡略化のためにM:N)の関連付けまたは関係の識別は、データベースプラクティショナーが概念スキーマをレイアウトするときに非常によく直面する状況です。上記のカーディナリティ比の関連付けは、非常に異なる性質のビジネス環境で発生します。たとえば、SQL-DDL構成などによって論理レベルで適切に表現された場合、有害な冗長性は生じません。
このように、データベースモデリング演習の目的は、関心のあるビジネスコンテキストの関連特性を高精度でミラー化することです。したがって、M:Nアソシエーションが多数あることを正しく識別した場合、それらの接続数に関係なく、(a)概念スキーマおよび(b)それぞれの論理レベル宣言でそれらを表現する必要があります。その他—一種のカーディナリティ比に対処する必要があります。
ビジネスルール
あなたはよく文脈化された質問を提供し、あなたが取り組んでいるデータベースは純粋に仮説的なものであることを明確にしました。これは重要なポイントです。したがって、より複雑な情報要件を意味します。
(1)あなたが提供したビジネスルールにいくつかの修正と拡張を加えて、(2)より説明的な概念スキーマを作成することを決定しました。ここに私がまとめたいくつかの定式化があります:
- A 党1はどちらかである個人または組織
- A 党は、正確に-1によって分類されPartyType
- A PartyTypeの分類は、ゼロ・ワン・オア・多くの締約国
- アン機関は、ゼロ・ワン・オア・多くの開発製品
- A 製品は、いずれかであるシステムやゲーム
- A 製品は、正確に-1によって分類されるでProductType
- A システムは、正確に-1でカタログ化されSYSTEMTYPE
- ゲームは 1対多を経由して再生することができるシステム
- A システムは、 1対多の再生に使用されたゲーム
- A ゲームは、ゼロ・ワン・オア・多くの人に分類されるジャンル
- A ジャンル分類は、ゼロ・ワン・オア・多くのゲームを
- 製品の発信一対多ジョブズ
- A ジョブは、ゼロ・ワン・オア・多くの人に満たされた人々遊んでいる、役割の協力者を
- A 人で共同研究ゼロ・ワン・オア・多くの中のジョブ
1 パーティは、単一のエンティティを構成する個人または個人のグループを指す場合に法的文脈で使用される用語であるため、この名称は人と組織を表すのに適しています。
IDEF1X図
その後、図1に示すIDEF1X 2ダイアグラムを作成し(リンクをクリックしてより高い解像度で表示するようにしてください)、上記のビジネスルールを(関連すると思われる他のいくつかの)単一のグラフィックデバイスに統合しました。
2 情報モデリングの統合定義(IDEF1X)は、1993年12月に米国国立標準技術研究所(NIST)によって標準として確立された、非常に推奨されるデータモデリング手法です。(a)リレーショナルモデルの唯一の創始者であるEF Codd博士によって作成された初期の理論資料に基づいています。(b)PP Chen博士によって開発されたデータのエンティティ関係ビュー。また、(c)Robert G. Brownによって作成された論理データベース設計手法についても。
ご覧のとおり、対応する関連エンティティタイプとして、3つのM:N関連のみを示しました。
とりわけ、2つの異なるスーパータイプサブタイプ構造があります。
スーパータイプとサブタイプの関連付けに精通していない場合は、次のような質問に対する私の答えなど、助けが見つかるかもしれません。
例示的な論理SQL-DDLレイアウト
続いて、論理レベルで次のことを確認する必要があります。
- 各エンティティタイプは個別のベーステーブルで表されます
- 適用可能なエンティティタイプの各プロパティは、特定の列で示されます
- INT、DATETIME、CHARなど、含まれるすべての値が特定の明確に定義されたセットに属することを保証するために、各列の正確なデータ型が固定されます(もちろん、FirebirdやPostgreSQLなどを使用する場合、より強力なドメインを使用したい場合があります)
- すべてのテーブルに保持される行形式のアサーションが概念レベルで決定されたビジネスルールに準拠することを保証するために、複数の制約が(宣言的に)構成されます
そこで、前に示したIDEF1Xダイアグラムに基づいて、次のDDL配置を宣言しました。
CREATE TABLE PartyType ( -- Stands for an independent entity type.
PartyTypeCode CHAR(1) NOT NULL, -- To retain 'P' or 'O'.
Name CHAR(30) NOT NULL, -- To keep 'Person' or 'Organization'.
--
CONSTRAINT PartyType_PK PRIMARY KEY (PartyTypeCode)
);
CREATE TABLE Party ( -- Represents an entity supertype.
PartyId INT NOT NULL,
PartyTypeCode CHAR(1) NOT NULL, -- To hold the value that indicates the type of the row denoting the complementary subtype occurrence: either 'P' for 'Person' or 'O' for 'Organization'.
CreatedDateTime TIMESTAMP NOT NULL,
--
CONSTRAINT Party_PK PRIMARY KEY (PartyId),
CONSTRAINT PartyToPartyType_FK FOREIGN KEY (PartyTypeCode)
REFERENCES PartyType (PartyTypeCode)
);
CREATE TABLE Person ( -- Denotes an entity subtype.
PersonId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
GenderCode CHAR(3) NOT NULL,
BirthDate DATE NOT NULL,
--
CONSTRAINT Person_PK PRIMARY KEY (PersonId),
CONSTRAINT Person_AK UNIQUE (FirstName, LastName, GenderCode, BirthDate), -- Composite ALTERNATE KEY.
CONSTRAINT PersonToParty_FK FOREIGN KEY (PersonId)
REFERENCES Party (PartyId)
);
CREATE TABLE Organization ( -- Stands for an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
Name CHAR(30) NOT NULL,
FoundingDate DATE NOT NULL,
--
CONSTRAINT Organization_PK PRIMARY KEY (OrganizationId),
CONSTRAINT Organization_AK UNIQUE (Name), -- Single-column ALTERNATE KEY.
CONSTRAINT OrganizationToParty_FK FOREIGN KEY (OrganizationId)
REFERENCES Party (PartyId)
);
CREATE TABLE ProductType ( -- Represents an independent entity type.
ProductTypeCode CHAR(1) NOT NULL, -- To enclose the values 'S' and 'G' in the corresponding rows.
Name CHAR(30) NOT NULL, -- To comprise the values 'System' and 'Person' in the respective rows.
--
CONSTRAINT ProductType_PK PRIMARY KEY (ProductTypeCode)
);
CREATE TABLE Product ( -- Denotes an entity supertype.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
ProductTypeCode CHAR(1) NOT NULL, -- To keep the value that indicates the type of the row denoting the complementary subtype occurrence: either 'S' for 'System' or 'G' for 'Game'.
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Product_PK PRIMARY KEY (OrganizationId, ProductNumber), -- Composite PRIMARY KEY.
CONSTRAINT ProductToOrganization_FK FOREIGN KEY (OrganizationId)
REFERENCES Organization (OrganizationId),
CONSTRAINT ProductToProductType_FK FOREIGN KEY (ProductTypeCode)
REFERENCES ProductType (ProductTypeCode)
);
CREATE TABLE SystemType ( -- Stands for an independent entity type.
SystemTypeCode CHAR(1) NOT NULL,
Name CHAR(30) NOT NULL,
--
CONSTRAINT SystemType_PK PRIMARY KEY (SystemTypeCode)
);
CREATE TABLE MySystem ( -- Represents a dependent entity type.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
SystemNumber INT NOT NULL,
SystemTypeCode CHAR(1) NOT NULL,
ParticularColumn CHAR(30) NOT NULL,
--
CONSTRAINT System_PK PRIMARY KEY (OrganizationId, SystemNumber),
CONSTRAINT SystemToProduct_FK FOREIGN KEY (OrganizationId, SystemNumber)
REFERENCES Product (OrganizationId, ProductNumber),
CONSTRAINT SystemToSystemType_FK FOREIGN KEY (SystemTypeCode)
REFERENCES SystemType (SystemTypeCode)
);
CREATE TABLE Game ( -- Denotes an entity subtype.
OrganizationId INT NOT NULL, -- To be constrained as (a) the PRIMARY KEY and (b) a FOREIGN KEY.
GameNumber INT NOT NULL,
SpecificColumn CHAR(30) NOT NULL,
--
CONSTRAINT Game_PK PRIMARY KEY (OrganizationId, GameNumber),
CONSTRAINT GameToProduct_FK FOREIGN KEY (OrganizationId, GameNumber)
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Genre ( -- Stands for an independent entity type.
GenreNumber INT NOT NULL,
Name CHAR(30) NOT NULL,
Description CHAR(90) NOT NULL,
--
CONSTRAINT Genre_PK PRIMARY KEY (GenreNumber),
CONSTRAINT Genre_AK1 UNIQUE (Name),
CONSTRAINT Genre_AK2 UNIQUE (Description)
);
CREATE TABLE SystemGame ( -- Represents an associative entity type or M:N association.
SystemOrganizationId INT NOT NULL,
SystemNumber INT NOT NULL,
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT SystemGame_PK PRIMARY KEY (SystemOrganizationId, SystemNumber, GameOrganizationId, GameNumber), -- Composite PRIMARY KEY.
CONSTRAINT SystemGameToSystem_FK FOREIGN KEY (SystemOrganizationId, SystemNumber) -- Multi-column FOREIGN KEY.
REFERENCES MySystem (OrganizationId, SystemNumber),
CONSTRAINT SystemGameToGame_FK FOREIGN KEY (SystemOrganizationId, GameNumber) -- Multi-column FOREIGN KEY.
REFERENCES Game (OrganizationId, GameNumber)
);
CREATE TABLE GameGenre ( -- Denotes an associative entity type or M:N association.
GameOrganizationId INT NOT NULL,
GameNumber INT NOT NULL,
GenreNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT GameGenre_PK PRIMARY KEY (GameOrganizationId, GameNumber, GenreNumber), -- Composite PRIMARY KEY.
CONSTRAINT GameGenreToGame_FK FOREIGN KEY (GameOrganizationId, GameNumber)
REFERENCES Game (OrganizationId, GameNumber), -- Multi-column FOREIGN KEY.
CONSTRAINT GameGenreToGenre_FK FOREIGN KEY (GenreNumber)
REFERENCES Genre (GenreNumber)
);
CREATE TABLE Job ( -- Stands for an associative entity type or M:N association.
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
Title CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Job_PK PRIMARY KEY (OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT Job_AK UNIQUE (Title), -- Single-column ALTERNATE KEY.
CONSTRAINT JobToProduct_FK FOREIGN KEY (OrganizationId, ProductNumber) -- Multi-column FOREIGN KEY.
REFERENCES Product (OrganizationId, ProductNumber)
);
CREATE TABLE Collaborator ( -- Represents an associative entity type or M:N association.
CollaboratorId INT NOT NULL,
OrganizationId INT NOT NULL,
ProductNumber INT NOT NULL,
JobNumber INT NOT NULL,
AssignedDateTime DATETIME NOT NULL,
--
CONSTRAINT Collaborator_PK PRIMARY KEY (CollaboratorId, OrganizationId, ProductNumber, JobNumber), -- Composite PRIMARY KEY.
CONSTRAINT CollaboratorToPerson_FK FOREIGN KEY (CollaboratorId)
REFERENCES Person (PersonId),
CONSTRAINT CollaboratorToJob_FK FOREIGN KEY (OrganizationId, ProductNumber, JobNumber) -- Multi-column FOREIGN KEY.
REFERENCES Job (OrganizationId, ProductNumber, JobNumber)
);
複数のテーブルにまたがる複合 PRIMARY KEY制約の宣言があることを強調するのは適切です。これは、概念的なエンティティタイプ間で発生する接続の階層を表します。派生テーブルを取得するためのJOIN句を含む操作。
はい、(i)すべてのM:Nアソシエーションおよび(ii)関連付けられたエンティティタイプのすべてが(iii)論理DDL構造内の対応するテーブルで示されているため、PRIMARYおよびFOREIGN KEY制約(およびこれらの概念的な要素を表すテーブルのコメントとして私が残したメモ)は、関連する行間の接続が適用可能なカーディナリティ比を満たすことを保証するのに役立つためです。
複合キーの使用は、によって導入された博士はEFコッド彼は題し彼の1970年の精液の論文に含ま例で示したように、リレーショナルパラダイムの非常に原点からの大規模な共有データバンクのためのAリレーショナル・モデル(正確には、また提示します、概念的なM:Nアソシエーションを処理する最もエレガントな方法)。
私は我慢する デシベル<>フィドルとSQLフィドル構造は、「アクションの」テストすることができるように、Microsoft SQL Serverの2014年の両方のランニング、。
正規化
正規化は、基本的に次のことを意味する論理レベルの手順です。
データ操作と制約が使用するデータサブ言語(SQLなど)で処理しやすくなるように、最初の正規形を介して非アトミック列を削除します。
更新の異常を回避するために、連続する標準形式によって特定のテーブルの列間の望ましくない依存関係を取り除きます。
当然、問題の表と列が持つ意味を考慮する必要があります。
正規化は、科学に基づいたテストであり、設計者が安定した論理レベルの配置を定めて、そのアイテムが通常のフォームのすべてに準拠しているかどうかを判断すると、関連する要素に適用されるテストとして考えるのが好きです。次に、必要に応じて、設計者は適切な修正措置を講じます。
冗長性
リレーショナルモデルでは、列に含まれる値の重複は許容されるだけでなく予想されるものですが、重複する行は禁止されています。その限りでは、私が見る限り、以前に公開された論理レイアウトに含まれるすべてのテーブルで重複行およびその他の種類の有害な冗長性が防止されています。おそらく、この点に関する懸念を明確にしたいと思います。
とにかく、確かに、(a)通常のフォームのdintによって独自の上記構造を評価して、要件を満たしているかどうかを定義し、(b)必要に応じて変更することができます。
関連資料
- 記事のこのシリーズ、私は簡単なMについてのいくつかの審議を提示:2つのインスタンスを相互に関係付けることができますN協会異なるエンティティタイプを。
- この他方私が接続する方法を説明した「部品表」又は「パーツ爆発」構築物の発生処理するアプローチを提案する別個のインスタンスが同じエンティティの種類。
三元協会
コメント(今削除された回答に投稿された)を介して持ち上がった別の重要な側面があります:
ブリッジを作成しようとするたびに、そのブリッジの要素にも多対多がありますが、許可されていない、または少なくとも落胆している印象を受けています。
その状況は、あなたの懸念の1つが概念的な三者協会に関係していることを示しているようです。基本的に、この種の関連付けは、(1)関係が存在する場合に発生します(2)他の2つの関係、つまり「関係間の関係」—典型的な状況。関係はそれ自体がエンティティであるため—。
これらの取り決めは、適切に管理されていれば、有害な冗長性ももたらしません。そして、はい、そのような関係が「実世界」のエンティティタイプ間に存在することを特定する特定のユースケースがある場合、(i)モデル化し、(ii)論理レベルで正確に宣言する必要があります。