Progettazione di un database per un dominio aziendale di videogiochi con relazioni multiple multiple


16

Sono relativamente nuovo nella progettazione di database e ho deciso di creare il mio database ipotetico per la pratica. Tuttavia, ho problemi a modellarlo e normalizzarlo, poiché stima che ci siano numerose relazioni molti-a-molti (M: N).

Descrizione generale dello scenario

Il database ha lo scopo di conservare i dati su varie persone che hanno lavorato alla serie Zelda. Voglio tenere traccia delle Console su cui è possibile giocare un Gioco , i Dipendenti che hanno avuto una parte nello sviluppo dei Giochi , i Lavori che il Dipendente ha avuto (molti Dipendenti hanno lavorato su diversi Lavori in più Giochi ), ecc.

Regole di business

  • Più dipendenti possono lavorare su più giochi .
  • Più giochi possono essere sulla stessa console .
  • Più console possono essere una piattaforma per lo stesso gioco .
  • Più dipendenti possono avere lo stesso lavoro .
  • Un dipendente può avere più lavori .
  • Un gioco può avere più dipendenti .
  • Un gioco può avere più tipi di lavori nel suo sviluppo
  • Più giochi possono avere lo stesso tipo di lavoro associato.
  • Una console può avere più persone che ci lavorano.
  • Una persona può lavorare su più console .

Nomi degli attributi e valori di esempio

  • Nome del dipendente , che può essere suddiviso in Nome e Cognome (ad esempio "John" e "Daina")
  • Titolo del gioco (ad esempio "Ocarina of Time")
  • Titolo di lavoro (ad esempio "Level Design", "Director", "Composure", "Level Designer", "Programmer", "Localization", ecc.).
  • Nome console (ad esempio "Game Boy Advance")

Il problema

Finora, sembra non importa ciò che progetto ci sono ridondanze di dati e relazioni M: N tra i tipi di entità di interesse ovunque. Tuttavia, ritengo che i progettisti di database debbano sempre incontrare questo tipo di problema, quindi deve esserci una soluzione.


Nota : sono in grado di trovare i dati per riempire la tabella, il problema è organizzarli in un database con tabelle in una forma normalizzata.


1
I commenti vengono spostati in una chat room come richiesto.
Paul White Ripristina Monica

Risposte:


18

Sì, l'identificazione di associazioni o relazioni molti-a-molti (M: N per brevità) è una situazione che un professionista del database affronta abbastanza comunemente durante la stesura di uno schema concettuale. Le associazioni di detti rapporti di cardinalità si verificano in ambienti aziendali di natura molto diversa e, se adeguatamente rappresentate a livello logico mediante, ad esempio, un accordo SQL-DDL, non introducono ridondanze dannose.

In questo modo, l'obiettivo di un esercizio di modellizzazione di una banca dati dovrebbe essere quello di rispecchiare le caratteristiche pertinenti del contesto aziendale di interesse con elevata precisione ; pertanto, se si identifica correttamente che esistono numerose associazioni M: N, è necessario esprimerle in (a) lo schema concettuale e anche in (b) le rispettive dichiarazioni a livello logico, indipendentemente da quante connessioni di ciò - o qualsiasi altro: devono essere affrontati i tipi di rapporti di cardinalità.

Regole di business

Hai fornito una domanda ben contestualizzata e hai anche chiarito che il database su cui stai lavorando è puramente ipotetico, il che è un punto importante poiché ritengo che uno scenario commerciale del "mondo reale" come quello in esame sarebbe molto più ampio e, quindi, implicherebbe requisiti informativi più complessi.

Ho deciso di (1) apportare alcune modifiche ed espansioni alle regole aziendali che hai fornito al fine di (2) produrre uno schema concettuale più descrittivo - anche se ancora piuttosto ipotetico -. Ecco alcune delle formulazioni che ho messo insieme:

  • Una parte 1 è una persona o un'organizzazione
  • Una Parte è classificata per esattamente un PartyType
  • Un PartyType classifica zero-uno-o-molti partiti
  • Un'organizzazione sviluppa zero-uno-o-molti prodotti
  • Un prodotto è un sistema o un gioco
  • Un prodotto è classificato esattamente per un ProductType
  • Un sistema è catalogato da esattamente un SystemType
  • Una partita può essere giocata tramite uno-a-molti sistemi
  • Un sistema viene utilizzato per giocare a uno-a-molti giochi
  • Un gioco è classificato per zero-uno-o-molti generi
  • Un genere classifica zero-uno-o-molti giochi
  • Un prodotto ha origine da uno a molti lavori
  • Un lavoro è adempiuto da zero-uno-o-molte persone , che svolgono il ruolo di collaboratori
  • UN persona è un collaboratore di zero-uno-o-molti Lavoro

1 Parte è un termine usato in contesti legali quando si fa riferimento a un individuo o un gruppo di individui che compongono una singola entità, quindi questa denominazione è adatta a rappresentare Persone e Organizzazioni .


Diagramma IDEF1X

Successivamente, ho creato il diagramma IDEF1X 2 mostrato in Figura 1 (assicurati di fare clic sul collegamento per vederlo in una risoluzione più elevata), consolidando in un unico dispositivo grafico le regole aziendali presentate sopra (insieme ad alcune altre che sembrano rilevanti):

Figura 1 - Diagramma IDEF1X di Gae Jobs video


2 Integration Definition for Information Modeling ( IDEF1X ) è una tecnica di modellazione dei dati altamente raccomandabile che è stata stabilita come standard nel dicembre 1993 dal National Institute of Standards and Technology degli Stati Uniti (NIST) . Si basa su (a) il primo materiale teorico creato dall'unico creatore del modello relazionale, cioè il Dr. EF Codd; su (b) la visione entità-relazione dei dati, sviluppata dal Dr. PP Chen ; e anche su (c) la tecnica di progettazione del database logico, creata da Robert G. Brown.


Come puoi vedere, ho rappresentato solo tre associazioni M: N per mezzo dei corrispondenti tipi di entità associativa , ovvero:

  • Collaboratore
  • SystemGame
  • GameGenre

Tra gli altri aspetti, ci sono due distinte strutture di sottotipo-sottotipo , in cui:

  • La persona e l' organizzazione sono sottotipi di entità reciprocamente esclusivi di Party , il loro sottotipo di entità

  • Il prodotto è il supertipo di Sistema e Gioco , che a loro volta sono sottotipi reciprocamente esclusivi

Nel caso in cui non si abbia familiarità con le associazioni di sottotipi e sottotipi, è possibile trovare aiuto, ad esempio le mie risposte alle domande intitolate:

Layout logico SQL-DDL illustrativo

Successivamente, dobbiamo assicurarci che, a livello logico:

  • Ogni tipo di entità è rappresentato da una singola tabella di base
  • Ogni singola proprietà del tipo di entità applicabile è indicata da una colonna specifica
  • Un tipo di dati esatto è fissato per ogni colonna al fine di garantire che tutti i valori in esso contenuti appartengano a un insieme particolare e ben definito, sia esso INT, DATETIME, CHAR, ecc. (Ovviamente, quando si utilizza, ad esempio, Firebird o PostgreSQL , potresti voler utilizzare i DOMAIN più potenti)
  • Più vincoli sono configurati (in modo dichiarativo) al fine di garantire che le asserzioni sotto forma di righe conservate in tutte le tabelle siano conformi alle regole aziendali determinate a livello concettuale

Quindi ho dichiarato la seguente disposizione DDL basata sul diagramma IDEF1X precedentemente mostrato:

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

È opportuno sottolineare che ci sono dichiarazioni di vincoli compositi PRIMARY KEY su più tabelle, che rappresentano la gerarchia delle connessioni che si svolgono tra i tipi di entità concettuali, disposizione che può essere molto utile rispetto al recupero dei dati quando, ad esempio, si esprime SELECT operazioni che includono clausole JOIN per ottenere derivate tabelle .

Sì, (i) ogni associazione M: N e (ii) tutti i tipi di entità associati sono indicati da (iii) la tabella corrispondente nella struttura logica DDL, quindi presta particolare attenzione ai vincoli PRIMARY e FOREIGN KEY (e al note che ho lasciato come commenti) delle tabelle che rappresentano questi elementi concettuali, perché aiutano a garantire che le connessioni tra le righe pertinenti soddisfino i rapporti di cardinalità applicabili.

L'uso di chiavi composite è stato introdotto dal Dr. EF Codd sin dalle origini del paradigma relazionale, come dimostrato negli esempi che ha incluso nel suo saggio seminale del 1970 intitolato Un modello relazionale per grandi banche dati condivise (che, appunto, presenta anche il metodo più elegante per gestire le associazioni M: N concettuali).

Ho installato un violino db e un violino SQL , entrambi in esecuzione su Microsoft SQL Server 2014, in modo che la struttura possa essere testata "in azione".

Normalizzazione

La normalizzazione è una procedura a livello logico che implica, sostanzialmente parlando:

  1. Eliminare le colonne non atomiche tramite la prima forma normale in modo che la manipolazione e la limitazione dei dati siano molto più facili da gestire dal linguaggio secondario dei dati (ad esempio, SQL).

  2. Sbarazzarsi di dipendenze indesiderate tra le colonne di una tabella specifica in virtù delle successive forme normali per evitare anomalie di aggiornamento .

Naturalmente, si deve tener conto del significato portato dalle tabelle e dalle colonne in questione.

Mi piace pensare alla normalizzazione come a un test fondato sulla scienza che un designer applica agli elementi pertinenti una volta che ha delineato una disposizione stabile a livello logico per determinare se i suoi articoli sono conformi a ciascuna delle forme normali o meno. Quindi, se necessario, il progettista adotta le misure correttive appropriate.

Ridondanza

Nel modello relazionale, mentre la duplicazione dei valori contenuti nelle colonne non è solo accettabile ma prevista , le righe duplicate sono vietate . A tal fine, per quanto posso vedere, le righe duplicate e altri tipi di ridondanze dannose sono prevenute in tutte le tabelle comprese nel layout logico esposto prima, forse ti piacerebbe chiarire la tua preoccupazione al riguardo.

Ad ogni modo, puoi certamente (a) valutare da solo la tua struttura a forza delle forme normali per definire se soddisfa i requisiti e (b) modificarlo se necessario.

Risorse correlate

  • In questa serie di post vi presento alcune deliberazioni su un'associazione M: N semplice che può mettere in relazione le istanze di due diversi tipi di entità.
  • In quest'altro propongo un approccio per gestire un'occorrenza del costrutto “Distinta materiali” o “Esplosione di parti”, in cui descrivo come collegare istanze distinte dello stesso tipo di entità.

Associazioni ternarie

C'è un altro aspetto importante che hai sollevato tramite i commenti (pubblicato in una risposta ora cancellata):

Ogni volta che provo a creare un ponte, gli elementi di quel ponte hanno anche un numero Molti a molti, ho l'impressione che non sia permesso o almeno scoraggiato.

Tale circostanza sembra indicare che una delle tue preoccupazioni ha a che fare con le associazioni ternarie concettuali . Fondamentalmente, questo tipo di associazioni nasce quando esiste (1) una relazione che coinvolge (2) altre due relazioni, in altre parole "una relazione tra relazioni", anche una situazione tipica, poiché una relazione è un'entità a sé stante -.

Questi accordi, se opportunamente gestiti, non comportano neppure esuberi dannosi. E sì, se esiste un certo caso d'uso in cui si identifica che tali relazioni si presentano tra i tipi di entità del "mondo reale", è necessario (i) modellare e (ii) dichiararle con precisione a livello logico.

  • Ecco una domanda e una risposta se analizziamo un dominio di discorso sulle indagini , che include un esempio di associazione ternaria.
  • In questa ottima risposta , @Ypercube presenta un diagramma e la rispettiva struttura DDL per un'interessante relazione a forma di diamante , che è molto simile a questa classe di scenari.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.