複数の多対多の関係を持つビデオゲームビジネスドメイン用のデータベースの設計


16

私はデータベース設計が比較的新しいので、練習用に独自の仮想データベースを作成することにしました。ただし、多くの多対多(M:N)の関係があると考えているため、モデリングと正規化に問題があります。

一般的なシナリオの説明

このデータベースは、ゼルダシリーズで働いたさまざまな人々に関するデータを保持することを目的としています。私はのトラック維持したいコンソール(S)というゲームがで再生することができ、従業員に参加を持っていたゲーム開発をジョブズ従業員は、(多くの持っていた従業員が異なる上で働いていたジョブズ複数にわたるゲームなど、)

ビジネスルール

  • 複数の従業員が複数のゲームで作業できます。
  • 同じコンソール上に複数のゲームを配置できます。
  • 複数のコンソールを同じゲームのプラットフォームにすることができます。
  • 複数の従業員が同じジョブを持つことができます。
  • アン従業員は複数持つことができますジョブを
  • A ゲームは複数持つことができる従業員を
  • ゲームは、複数の種類持つことができるジョブのそれの発展に
  • 複数のゲームに同じタイプのジョブを添付できます。
  • A コンソールは複数持つことができます人々はそれに取り組んで。
  • A 人は複数で作業することができますコンソール

属性名とサンプル値

  • FirstLastに分割できる従業員名(「John」と「Doe」など)
  • ゲームのタイトル(たとえば、「Ocarina of Time」)
  • 役職(たとえば、「レベル設計」、「ディレクター」、「構成」、「レベル設計者」、「プログラマー」、「ローカリゼーション」など)。
  • コンソール名(「Game Boy Advance」など)

問題

これまでのところ、データの冗長性と、関心のあるエンティティタイプ間のM:N関係が至る所にあるように設計されているようです。しかし、データベース設計者は常にこの種の問題に遭遇しなければならないので、解決策が必要だと感じています。


:テーブルを満たすデータを見つけることはできますが、問題は、正規化された形式のテーブルを持つデータベースにデータを整理することです。


回答:


18

はい、多対多(簡略化のために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ダイアグラムを作成し(リンクをクリックしてより高い解像度で表示するようにしてください)、上記のビジネスルールを(関連すると思われる他のいくつかの)単一のグラフィックデバイスに統合しました。

図1-ビデオGaeジョブIDEF1Xの図


2 情報モデリングの統合定義IDEF1X)は、1993年12月に米国国立標準技術研究所(NIST)によって標準として確立された、非常に推奨されるデータモデリング手法です。(a)リレーショナルモデルの唯一の創始者であるEF Codd博士によって作成された初期の理論資料に基づいています。(b)PP Chen博士によって開発されたデータのエンティティ関係ビュー。また、(c)Robert G. Brownによって作成された論理データベース設計手法についても。


ご覧のとおり、対応する関連エンティティタイプとして、3つのM:N関連のみを示しました。

  • 協力者
  • SystemGame
  • GameGenre

とりわけ、2つの異なるスーパータイプサブタイプ構造があります。

  • PersonOrganizationは、Partyの相互に排他的なエンティティサブタイプであり、エンティティのスーパータイプです

  • 製品SystemGameのスーパータイプであり、相互に排他的なサブタイプです

スーパータイプとサブタイプの関連付けに精通していない場合は、次のような質問に対する私の答えなど、助けが見つかるかもしれません。

例示的な論理SQL-DDLレイアウト

続いて、論理レベルで次のことを確認する必要があります。

  • 各エンティティタイプは個別のベーステーブルで表されます
  • 適用可能なエンティティタイプの各プロパティは、特定の列で示されます
  • INT、DATETIME、CHARなど、含まれるすべてのが特定の明確に定義されたセットに属することを保証するために、各の正確なデータ型が固定されます(もちろん、FirebirdPostgreSQLなどを使用する場合、より強力なドメインを使用したい場合があります)
  • すべてのテーブルに保持される形式のアサーションが概念レベルで決定されたビジネスルールに準拠することを保証するために、複数の制約が(宣言的に)構成されます

そこで、前に示した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年の両方のランニング、。

正規化

正規化は、基本的に次のことを意味する論理レベルの手順です。

  1. データ操作と制約が使用するデータサブ言語(SQLなど)で処理しやすくなるように、最初の正規形を介して非アトミック列を削除します。

  2. 更新の異常を回避するために、連続する標準形式によって特定のテーブルの列間の望ましくない依存関係を取り除きます。

当然、問題の表と列が持つ意味を考慮する必要があります。

正規化は、科学に基づいたテストであり、設計者が安定した論理レベルの配置を定めて、そのアイテムが通常のフォームのすべてに準拠しているかどうかを判断すると、関連する要素に適用されるテストとして考えるのが好きです。次に、必要に応じて、設計者は適切な修正措置を講じます。

冗長性

リレーショナルモデルでは、列に含まれる値の重複は許容されるだけでなく予想されるものですが、重複する行は禁止されています。その限りでは、私が見る限り、以前に公開された論理レイアウトに含まれるすべてのテーブルで重複行およびその他の種類の有害な冗長性が防止されています。おそらく、この点に関する懸念を明確にしたいと思います。

とにかく、確かに、(a)通常のフォームのdintによって独自の上記構造を評価して、要件を満たしているかどうかを定義し、(b)必要に応じて変更することができます。

関連資料

  • 記事のこのシリーズ、私は簡単なMについてのいくつかの審議を提示:2つのインスタンスを相互に関係付けることができますN協会異なるエンティティタイプを。
  • この他方私が接続する方法を説明した「部品表」又は「パーツ爆発」構築物の発生処理するアプローチを提案する別個のインスタンスが同じエンティティの種類。

三元協会

コメント(今削除された回答に投稿された)を介して持ち上がった別の重要な側面があります:

ブリッジを作成しようとするたびに、そのブリッジの要素にも多対多がありますが、許可されていない、または少なくとも落胆している印象を受けています。

その状況は、あなたの懸念の1つが概念的な三者協会に関係していることを示しているようです。基本的に、この種の関連付けは、(1)関係が存在する場合に発生します(2)他の2つの関係、つまり「関係間の関係」—典型的な状況。関係はそれ自体がエンティティであるため—。

これらの取り決めは、適切に管理されていれば、有害な冗長性ももたらしません。そして、はい、そのような関係が「実世界」のエンティティタイプ間に存在することを特定する特定のユースケースがある場合、(i)モデル化し、(ii)論理レベルで正確に宣言する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.