Diseño de una base de datos para un dominio comercial de videojuegos con múltiples relaciones de muchos a muchos


16

Soy relativamente nuevo en el diseño de bases de datos, y decidí hacer mi propia base de datos hipotética para practicar. Sin embargo, tengo problemas para modelarlo y normalizarlo, ya que considero que existen numerosas relaciones de muchos a muchos (M: N).

Descripción general del escenario

La base de datos está destinada a retener datos sobre varias personas que han trabajado en la serie Zelda. Quiero hacer un seguimiento de las consolas en las que se puede jugar un juego , los empleados que han participado en el desarrollo de los juegos , los trabajos que tuvo el empleado (muchos empleados trabajaron en diferentes trabajos en varios juegos ), etc.

Reglas del negocio

  • Múltiples empleados pueden trabajar en múltiples juegos .
  • Varios juegos pueden estar en la misma consola .
  • Las consolas múltiples pueden ser una plataforma para el mismo juego .
  • Múltiples empleados pueden tener el mismo trabajo .
  • Un empleado puede tener múltiples trabajos .
  • Un juego puede tener múltiples empleados .
  • Un juego puede tener múltiples tipos de trabajos en su desarrollo
  • Varios juegos pueden tener el mismo tipo de trabajo adjunto.
  • Una consola puede tener varias personas trabajando en ella.
  • Una persona puede trabajar en múltiples consolas .

Nombres de atributos y valores de muestra

  • Nombre del empleado , que se puede dividir en Primera y Ultima (por ejemplo “Juan” y “Doe”)
  • Título del juego (por ejemplo, "Ocarina of Time")
  • Título del puesto (por ejemplo, "Diseño de niveles", "Director", "Compostura", "Diseñador de niveles", "Programador", "Localización", etc.).
  • Nombre de la consola (por ejemplo, "Game Boy Advance")

La cuestión

Hasta ahora, parece que no importa lo que diseñe, hay redundancias de datos y relaciones M: N entre los tipos de entidades de interés en todas partes. Sin embargo, creo que los diseñadores de bases de datos deben encontrarse con este tipo de problema todo el tiempo, por lo que debe haber una solución.


Nota : Soy capaz de encontrar los datos para llenar la tabla, el problema es organizarla en una base de datos con tablas en forma normalizada.


1
Los comentarios se movieron a una sala de chat según lo solicitado.
Paul White reinstala a Monica

Respuestas:


18

Sí, la identificación de asociaciones o relaciones de muchos a muchos (M: N para abreviar) es una situación que un profesional de bases de datos enfrenta con bastante frecuencia al diseñar un esquema conceptual. Las asociaciones de dichas proporciones de cardinalidad se producen en entornos empresariales de naturaleza muy diferente, y cuando se representan adecuadamente en el nivel lógico por medio de, por ejemplo, una disposición SQL-DDL, no introducen redundancias perjudiciales.

De esta manera, el objetivo de un ejercicio de modelado de bases de datos debe ser reflejar las características relevantes del contexto de negocios de interés con alta precisión ; por lo tanto, si identifica correctamente que existen numerosas asociaciones M: N, debe expresarlas en (a) el esquema conceptual y también en (b) las respectivas declaraciones de nivel lógico, sin importar cuántas conexiones de eso, o cualquier otro tipo de tasas de cardinalidad deben ser abordadas.

Reglas del negocio

Ha proporcionado una pregunta bien contextualizada y también ha aclarado que la base de datos en la que está trabajando es puramente hipotética, lo cual es un punto importante ya que considero que un escenario de negocios del "mundo real" como el que se está considerando sería mucho más extenso y, por lo tanto, implicaría requisitos informativos más complejos.

Decidí (1) hacer algunas modificaciones y expansiones a las reglas de negocios que usted ha provisto para (2) producir un esquema conceptual más descriptivo, aunque todavía bastante hipotético. Estas son algunas de las formulaciones que preparé:

  • Una Parte 1 es una Persona o una Organización
  • Una fiesta se clasifica exactamente por un PartyType
  • Un PartyType clasifica cero-uno-o-muchos partidos
  • Una organización desarrolla cero uno o muchos productos
  • Un producto es un sistema o un juego
  • Un producto se clasifica exactamente por un tipo de producto
  • Un sistema está catalogado exactamente por un tipo de sistema
  • Un juego se puede jugar a través de sistemas uno a muchos
  • Un sistema se utiliza para reproducir uno-a-muchos juegos
  • Un juego está clasificado por cero-uno o muchos géneros
  • Un género clasifica los juegos de cero uno o muchos
  • Un producto origina trabajos de uno a muchos
  • Un trabajo se cumple por cero-una o muchas personas , que desempeñan el papel de colaboradores
  • Una persona es un colaborador en trabajos de cero uno o muchos

1 Parte es un término utilizado en contextos legales cuando se refiere a un individuo o un grupo de individuos que componen una sola entidad, por lo que esta denominación es adecuada para representar a personas y organizaciones .


Diagrama IDEF1X

Posteriormente, creé el diagrama IDEF1X 2 que se muestra en la Figura 1 (asegúrese de hacer clic en el enlace para verlo en una resolución más alta), consolidando en un solo dispositivo gráfico las reglas comerciales presentadas anteriormente (junto con algunas otras que parecen relevantes):

Figura 1 - Diagrama IDEF1X de Video Gae Jobs


2 La definición de integración para el modelado de información ( IDEF1X ) es una técnica de modelado de datos altamente recomendable que fue establecida como estándar en diciembre de 1993 por el Instituto Nacional de Estándares y Tecnología de los Estados Unidos (NIST). Se basa en (a) el material teórico inicial escrito por el único autor del modelo relacional, es decir, el Dr. EF Codd; en (b) la vista de datos entidad-relación , desarrollada por el Dr. PP Chen ; y también en (c) la Técnica de diseño de base de datos lógica, creada por Robert G. Brown.


Como puede ver, he representado solo tres asociaciones M: N a través de los tipos de entidad asociativa correspondientes , es decir:

  • Colaborador
  • SystemGame
  • GameGenre

Entre otros aspectos, hay dos estructuras distintas de supertipo-subtipo , donde:

  • Persona y Organización son subtipos de entidad mutuamente excluyentes de Parte , su supertipo de entidad

  • El producto es el supertipo de Sistema y Juego , que a su vez son subtipos mutuamente excluyentes

En caso de que no esté familiarizado con las asociaciones de supertipo-subtipo, puede encontrar ayuda, por ejemplo, mis respuestas a las preguntas tituladas:

Diseño ilustrativo de SQL-DDL lógico

Sucesivamente, debemos asegurarnos de que, a nivel lógico:

  • Cada tipo de entidad está representado por una tabla base individual
  • Cada propiedad individual del tipo de entidad aplicable se denota por una columna particular
  • Se fija un tipo de datos exacto para cada columna para garantizar que todos los valores que contiene pertenecen a un conjunto particular y bien definido, ya sea INT, DATETIME, CHAR, etc. (por supuesto, cuando se usa, por ejemplo, Firebird o PostgreSQL , es posible que desee emplear los DOMINIOS más potentes)
  • Se configuran múltiples restricciones (declarativamente) para garantizar que las aserciones en forma de filas retenidas en todas las tablas cumplan con las reglas de negocio determinadas a nivel conceptual

Así que declaró la siguiente disposición DDL basada en el diagrama IDEF1X mostrado anteriormente:

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 oportuno enfatizar que existen declaraciones de restricciones PRIMARY KEY compuestas en varias tablas, que representan la jerarquía de conexiones que tienen lugar entre los tipos de entidades conceptuales, disposición que puede ser muy beneficiosa con respecto a la recuperación de datos cuando, por ejemplo, se expresa SELECT operaciones que incluyen cláusulas JOIN para obtener tablas derivadas .

Sí, (i) cada asociación M: N y (ii) cada uno de los tipos de entidad asociados se denota por (iii) la tabla correspondiente en la estructura lógica DDL, por lo tanto, preste especial atención a las restricciones PRIMARY y FOREIGN KEY (y la notas que dejé como comentarios) de las tablas que representan estos elementos conceptuales, porque ayudan a garantizar que las conexiones entre las filas relevantes cumplan con las proporciones de cardinalidad aplicables.

El Dr. EF Codd introdujo el uso de claves compuestas desde el origen mismo del paradigma relacional, como se demostró en los ejemplos que incluyó en su artículo seminal de 1970 titulado Un modelo relacional para grandes bancos de datos compartidos (que, precisamente, también presenta el método más elegante para manejar asociaciones conceptuales M: N).

Puse un db <> fiddle y un SQL Fiddle , ambos ejecutándose en Microsoft SQL Server 2014, para que la estructura se pueda probar "en acción".

Normalización

La normalización es un procedimiento de nivel lógico que implica, básicamente hablando:

  1. Eliminando columnas no atómicas a través de la primera forma normal para que la manipulación de datos y la constricción sean mucho más fáciles de manejar mediante el sublenguaje de datos de uso (por ejemplo, SQL).

  2. Deshacerse de las dependencias indeseables entre las columnas de una tabla específica en virtud de las formas normales sucesivas para evitar anomalías de actualización .

Naturalmente, uno tiene que tener en cuenta el significado que tienen las tablas y las columnas en cuestión.

Me gusta pensar en la normalización como una prueba fundada en la ciencia que un diseñador aplica a los elementos pertinentes una vez que ha delineado una disposición estable de nivel lógico para determinar si sus elementos cumplen con cada una de las formas normales o no. Luego, si es necesario, el diseñador toma las medidas correctivas apropiadas.

Redundancia

En el modelo relacional, aunque la duplicación de valores contenidos en columnas no solo es aceptable sino esperada , las filas duplicadas están prohibidas . En esa medida, hasta donde puedo ver, se evitan filas duplicadas y otros tipos de redundancias dañinas en todas las tablas comprendidas en el diseño lógico expuesto anteriormente, tal vez le gustaría aclarar su preocupación a este respecto.

De todos modos, ciertamente puede (a) evaluar su propia estructura a fuerza de las formas normales para definir si cumple con los requisitos y (b) modificarla si es necesario.

Recursos Relacionados

  • En esta serie de mensajes presento algunas deliberaciones sobre un M sencillo: asociación N que puede interrelacionar los casos de dos diferentes tipos de entidad.
  • En este otro , propongo un enfoque para manejar una ocurrencia de la construcción "Lista de materiales" o "Explosión de piezas", en la que describo cómo conectar instancias distintas del mismo tipo de entidad.

Asociaciones ternarias

Hay otro aspecto importante que mencionó a través de comentarios (publicado en una respuesta ahora eliminada):

Cada vez que intento hacer un puente, los elementos en ese puente también tienen un Muchos a Muchos, tengo la impresión de que no está permitido o al menos desalentado.

Esa circunstancia parece indicar que una de sus preocupaciones tiene que ver con asociaciones ternarias conceptuales . Básicamente hablando, este tipo de asociaciones se produce cuando existe (1) una relación que involucra (2) otras dos relaciones, en otras palabras, "una relación entre relaciones", una situación típica también, ya que una relación es una entidad en sí misma -.

Estas disposiciones, cuando se gestionan adecuadamente, tampoco generan redundancias perjudiciales. Y, sí, si hay un cierto caso de uso en el que identifica que tales relaciones se presentan entre los tipos de entidades del "mundo real", debe (i) modelar y (ii) declararlas con precisión en el nivel lógico.

  • Aquí hay una pregunta y respuesta donde analizamos un dominio del discurso sobre las encuestas , que incluye un ejemplo de asociación ternaria.
  • En esta muy buena respuesta , @Ypercube presenta un diagrama y la estructura DDL respectiva para una interesante relación en forma de diamante , que es muy similar a esta clase de escenarios.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.