Entwerfen einer Datenbank für eine Videospiel-Unternehmensdomäne mit mehreren Viele-zu-Viele-Beziehungen


16

Ich bin relativ neu im Datenbankdesign und habe beschlossen, eine eigene hypothetische Datenbank für die Praxis zu erstellen. Es fällt mir jedoch schwer, es zu modellieren und zu normalisieren, da ich schätze, dass es zahlreiche Viele-zu-Viele-Beziehungen (M: N) gibt.

Allgemeine Beschreibung des Szenarios

In der Datenbank sollen Daten zu verschiedenen Personen gespeichert werden , die an der Zelda-Serie gearbeitet haben. Ich möchte die Konsole (n) verfolgen , auf denen ein Spiel gespielt werden kann (n) , Mitarbeiter , die an der Spieleentwicklung teilgenommen haben, die Jobs , die der Mitarbeiter hatte (viele Mitarbeiter haben an verschiedenen Jobs über mehrere Spiele hinweg gearbeitet ) usw.

Geschäftsregeln

  • Mehrere Mitarbeiter können an mehreren Spielen arbeiten .
  • Mehrere Spiele können sich auf derselben Konsole befinden .
  • Mehrere Konsolen können eine Plattform für dasselbe Spiel sein .
  • Mehrere Mitarbeiter können denselben Job haben .
  • Ein Mitarbeiter kann mehrere Jobs haben .
  • Ein Spiel kann mehrere Mitarbeiter haben .
  • Ein Spiel kann mehrere Arten von Jobs in seiner Entwicklung haben
  • An mehrere Spiele kann derselbe Auftragstyp angehängt werden.
  • An einer Konsole können mehrere Personen arbeiten.
  • Eine Person kann an mehreren Konsolen arbeiten .

Attributnamen und Beispielwerte

  • Name des Mitarbeiters , der in aufgeteilt werden kann Erste und Letzte (zum Beispiel „John“ und „Doe“)
  • Spieltitel (zum Beispiel „Ocarina of Time“)
  • Berufsbezeichnung (zum Beispiel „Level Design“, „Director“, „Composure“, „Level Designer“, „Programmer“, „Localization“ usw.).
  • Konsolenname (zum Beispiel "Game Boy Advance")

Die Angelegenheit

Bisher scheint es, egal was ich entwerfe, überall Datenredundanzen und M: N-Beziehungen zwischen den interessierenden Entitätstypen zu geben. Ich bin jedoch der Meinung, dass Datenbankdesigner ständig auf diese Art von Problem stoßen müssen, daher muss es eine Lösung geben.


Hinweis : Ich kann die Daten zum Füllen der Tabelle gut finden. Das Problem besteht darin, sie in einer Datenbank mit Tabellen in normalisierter Form zu organisieren.


Antworten:


18

Ja, die Identifizierung von vielen-zu-vielen (M: N für Kürze) Assoziationen oder Beziehungen ist eine Situation, mit der ein Datenbankfachmann häufig konfrontiert ist, wenn er ein konzeptionelles Schema entwirft. Assoziationen dieser Kardinalitätsverhältnisse treten in Geschäftsumgebungen sehr unterschiedlicher Art auf und führen, wenn sie auf der logischen Ebene beispielsweise mittels einer SQL-DDL-Anordnung richtig dargestellt werden , nicht zu schädlichen Redundanzen.

Auf diese Weise sollte das Ziel einer Datenbankmodellierungsübung darin bestehen, die relevanten Merkmale des interessierenden Geschäftskontexts mit hoher Genauigkeit widerzuspiegeln. Wenn Sie also richtig erkennen, dass es zahlreiche M: N-Assoziationen gibt, müssen Sie diese in (a) dem konzeptionellen Schema und auch in (b) den entsprechenden Deklarationen auf logischer Ebene ausdrücken, unabhängig von der Anzahl der Verbindungen andere - Arten von Kardinalitätsverhältnissen müssen angesprochen werden.

Geschäftsregeln

Sie haben eine gut kontextualisierte Frage gestellt und außerdem klargestellt, dass die Datenbank, an der Sie arbeiten, rein hypothetisch ist. Dies ist ein wichtiger Punkt, da ich der Meinung bin, dass ein Geschäftsszenario aus der „realen Welt“ wie das betrachtete viel umfangreicher wäre und würde daher komplexere Informationsanforderungen implizieren.

Ich habe beschlossen, (1) ein paar Änderungen und Erweiterungen an den von Ihnen bereitgestellten Geschäftsregeln vorzunehmen, um (2) ein aussagekräftigeres konzeptionelles Schema zu erstellen - auch wenn es immer noch eher hypothetisch ist -. Hier sind einige der Formulierungen, die ich zusammengestellt habe:

  • Eine Partei 1 ist entweder eine Person oder eine Organisation
  • Eine Party wird nach genau einem PartyType klassifiziert
  • Ein PartyType klassifiziert Null-Eins-oder-Viele- Parteien
  • Eine Organisation entwickelt Null-Eins-oder-Viele- Produkte
  • Ein Produkt ist entweder ein System oder ein Spiel
  • Ein Produkt wird nach genau einem ProductType klassifiziert
  • Ein System wird mit genau einem SystemType katalogisiert
  • Ein Spiel kann über Eins-zu-Viele- Systeme gespielt werden
  • Ein System wird verwendet, um Eins-zu-Viele- Spiele zu spielen
  • Ein Spiel wird nach einem oder mehreren Genres klassifiziert
  • Ein Genre klassifiziert Null-Eins-oder-Viele- Spiele
  • Ein Produkt entsteht aus Eins-zu-Viele- Jobs
  • Ein Job wird von Null-Eins-oder-Viele- Leuten erfüllt , die die Rolle der Kollaborateure spielen
  • Eine Person ist ein Mitarbeiter in Null-Eins-oder-Viele- Jobs

1 Partei ist ein Begriff, der im rechtlichen Kontext für eine Einzelperson oder eine Gruppe von Einzelpersonen verwendet wird, die eine Einheit bilden. Diese Bezeichnung eignet sich daher zur Darstellung von Personen und Organisationen .


IDEF1X-Diagramm

Anschließend habe ich das in Abbildung 1 gezeigte IDEF1X 2- Diagramm erstellt (stellen Sie sicher, dass Sie auf den Link klicken, um ihn in einer höheren Auflösung anzuzeigen) und die oben dargestellten Geschäftsregeln (zusammen mit einigen anderen, die relevant erscheinen) in einem einzigen grafischen Gerät konsolidiert:

Abbildung 1 - Video Gae Jobs IDEF1X-Diagramm


2 Integration Definition für Information Modeling ( IDEF1X ) ist eine sehr empfehlenswerte Datenmodellierungstechnik, die als etabliert wurde Standard im Dezember 1993 von den Vereinigten Staaten National Institute of Standards and Technology (NIST). Es basiert auf (a) dem frühen theoretischen Material, das vom alleinigen Urheber des relationalen Modells verfasst wurde, dh Dr. EF Codd; zu (b) der von Dr. PP Chen entwickelten Sicht auf die Beziehung zwischen Unternehmen und Daten ; und auch auf (c) der Logical Database Design Technique, erstellt von Robert G. Brown.


Wie Sie sehen, habe ich nur drei M: N-Assoziationen anhand der entsprechenden assoziativen Entitätstypen dargestellt :

  • Mitarbeiter
  • SystemGame
  • GameGenre

Unter anderem gibt es zwei unterschiedliche Supertyp-Subtyp- Strukturen, wobei:

  • Person und Organisation sind sich gegenseitig ausschließende Unternehmenssubtypen der Partei , deren Unternehmenssupertyp

  • Produkt ist der Supertyp von System und Spiel , die sich gegenseitig ausschließen

Falls Sie nicht mit Assoziationen von Supertypen und Subtypen vertraut sind, finden Sie möglicherweise Hilfe, z. B. meine Antworten auf die folgenden Fragen:

Beispielhaftes logisches SQL-DDL-Layout

Nacheinander müssen wir sicherstellen, dass auf der logischen Ebene:

  • Jeder Entitätstyp wird durch eine einzelne Basistabelle dargestellt
  • Jede einzelne Eigenschaft des entsprechenden Entitätstyps wird durch eine bestimmte Spalte gekennzeichnet
  • Für jede Spalte wird ein genauer Datentyp festgelegt , um sicherzustellen, dass alle darin enthaltenen Werte zu einer bestimmten und genau definierten Menge gehören, sei es INT, DATETIME, CHAR usw. (natürlich bei Verwendung von z. B. Firebird oder PostgreSQL , vielleicht möchten Sie die leistungsstärkeren DOMAINs einsetzen)
  • Mehrere Einschränkungen werden (deklarativ) konfiguriert, um sicherzustellen, dass die in allen Tabellen in Form von Zeilen gespeicherten Zusicherungen den auf konzeptioneller Ebene festgelegten Geschäftsregeln entsprechen

Daher habe ich die folgende DDL-Anordnung basierend auf dem zuvor gezeigten IDEF1X-Diagramm deklariert:

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)
);

Es ist angebracht zu betonen, dass es Deklarationen von zusammengesetzten PRIMARY KEY-Einschränkungen über mehrere Tabellen gibt, die für die Hierarchie von Verbindungen stehen, die zwischen konzeptuellen Entitätstypen stattfinden. Diese Anordnung kann in Bezug auf das Abrufen von Daten sehr vorteilhaft sein, wenn beispielsweise SELECT ausgedrückt wird Operationen, die JOIN-Klauseln enthalten, um abgeleitete Tabellen abzurufen.

Ja, (i) jede M: N-Zuordnung und (ii) jeder der zugeordneten Entitätstypen werden mit (iii) der entsprechenden Tabelle in der logischen DDL-Struktur bezeichnet. Achten Sie daher besonders auf die Einschränkungen PRIMARY und FOREIGN KEY (und Anmerkungen, die ich als Kommentare hinterlassen habe) von Tabellen, die diese konzeptionellen Elemente darstellen, da sie dazu beitragen, sicherzustellen, dass die Verbindungen zwischen den relevanten Zeilen den geltenden Kardinalitätsverhältnissen entsprechen.

Die Verwendung von Verbundschlüssel wurde von eingeführtem Dr. EF Codd aus dem sehr Ursprung des relationalen Paradigmas, wie in den Beispielen demonstrierte er in seinem 1970 Samt Papier mit dem Titel enthielt ein relationales Modell für großen Shared Data Banks (die gerade auch die präsentiert eleganteste Methode für den Umgang mit konzeptionellen M: N-Assoziationen).

Ich habe eine db <> -Fiddle und eine SQL-Fiddle erstellt , die beide unter Microsoft SQL Server 2014 ausgeführt werden, damit die Struktur "in Aktion" getestet werden kann.

Normalisierung

Normalisierung ist eine Prozedur auf logischer Ebene, die im Grunde genommen Folgendes impliziert:

  1. Eliminierung nicht-atomarer Spalten über die erste Normalform, damit Datenmanipulation und -verengung durch die Datenteilsprache der Verwendung (z. B. SQL) viel einfacher zu bewältigen sind.

  2. Beseitigung unerwünschter Abhängigkeiten zwischen den Spalten einer bestimmten Tabelle aufgrund der aufeinanderfolgenden normalen Formulare, um Aktualisierungsanomalien zu vermeiden .

Natürlich muss man die Bedeutung der betreffenden Tabelle (n) und Spalte (n) berücksichtigen .

Ich stelle mir Normalisierung gerne als einen wissenschaftlich fundierten Test vor , bei dem ein Designer auf die relevanten Elemente zurückgreift, sobald er eine stabile Anordnung auf logischer Ebene festgelegt hat, um festzustellen, ob seine Elemente mit jeder der normalen Formen übereinstimmen oder nicht. Bei Bedarf ergreift der Konstrukteur dann die entsprechenden Korrekturmaßnahmen.

Redundanz

Während im relationalen Modell das Duplizieren von Werten in Spalten nicht nur akzeptabel ist, sondern erwartet wird , sind doppelte Zeilen verboten . Insoweit, wie ich sehen kann, werden doppelte Zeilen und andere schädliche Redundanzen in allen Tabellen verhindert, die in dem zuvor offengelegten logischen Layout enthalten sind. Vielleicht möchten Sie Ihr Anliegen in dieser Hinsicht klarstellen.

Auf jeden Fall können Sie (a) die Struktur anhand der normalen Formulare selbst beurteilen, um festzustellen, ob sie den Anforderungen entspricht, und (b) sie erforderlichenfalls ändern.

Ähnliche Resourcen

  • In dieser Reihe von Beiträgen stelle ich einige Überlegungen zu einer einfachen M: N-Zuordnung vor, die die Instanzen zweier verschiedener Entitätstypen in Beziehung setzen kann .
  • In diesem anderen Teil schlage ich einen Ansatz vor, um mit dem Auftreten des Konstrukts „Stückliste“ oder „Teileexplosion“ umzugehen. Dabei beschreibe ich, wie verschiedene Instanzen desselben Entitätstyps verbunden werden.

Ternäre Assoziationen

Es gibt einen weiteren wichtigen Aspekt, den Sie über Kommentare angesprochen haben (gepostet in einer jetzt gelöschten Antwort):

Jedes Mal, wenn ich versuche, eine Brücke zu bauen, haben die Elemente in dieser Brücke auch ein Viele-zu-Viele-Verhältnis. Ich habe den Eindruck, dass dies nicht erlaubt oder zumindest entmutigt ist.

Dieser Umstand scheint darauf hinzudeuten, dass eines Ihrer Anliegen mit konzeptionellen ternären Assoziationen zu tun hat . Grundsätzlich kommt diese Art von Assoziationen zustande, wenn (1) eine Beziehung besteht, die (2) zwei andere Beziehungen umfasst, mit anderen Worten „eine Beziehung zwischen Beziehungen“ - auch eine typische Situation, da eine Beziehung eine eigenständige Einheit ist -.

Diese Vereinbarungen bringen bei angemessener Verwaltung auch keine schädlichen Entlassungen mit sich. Und ja, wenn es einen bestimmten Anwendungsfall gibt, in dem Sie feststellen, dass sich solche Beziehungen unter Entitätstypen der „realen Welt“ darstellen, müssen Sie diese (i) modellieren und (ii) auf logischer Ebene mit Genauigkeit deklarieren.

  • Hier ist eine Frage und Antwort , wo wir einen Diskursbereich über Umfragen analysieren , der ein Beispiel für eine ternäre Assoziation enthält.
  • In dieser sehr guten Antwort , @Ypercube stellt ein Diagramm und die entsprechende DDL - Struktur für eine interessante rautenförmige Beziehung , die zu dieser Klasse von Szenarien sehr ähnlich ist.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.