Разработка базы данных для бизнес-сферы видеоигр с множеством взаимосвязей «многие ко многим»

16

Я относительно новичок в разработке баз данных, и я решил создать свою собственную гипотетическую базу данных для практики. Однако у меня возникли проблемы с моделированием и нормализацией, так как я считаю, что существует множество отношений «многие ко многим» (M: N).

Общее описание сценария

База данных предназначена для хранения данных о различных людях , которые работали над серией Zelda. Я хочу , чтобы следить за консоли (с) , что игра может быть воспроизведена на, сотрудниках , которые имели участие в играх развитии, Работа сотрудников были (многие сотрудники работали на разные рабочих местах на нескольких игр ) и т.д.

Бизнес правила

  • Несколько сотрудников могут работать в нескольких играх .
  • Несколько игр могут быть на одной консоли .
  • Несколько консолей могут быть платформой для одной и той же игры .
  • Несколько сотрудников могут иметь одну и ту же работу .
  • Сотрудник может иметь несколько рабочих мест .
  • Игра может иметь несколько сотрудников .
  • Игра может иметь несколько типов рабочих мест в его развитии
  • Несколько игр могут иметь один и тот же тип заданий .
  • Консоль может иметь несколько людей работают над этим.
  • Человек может работать на нескольких консолях .

Имена атрибутов и примеры значений

  • Имя сотрудника , который может быть разделен на First и Last (например , «Джон» и «Doe»)
  • Название игры (например, «Окарина времени»)
  • Название должности (например, «Дизайн уровней», «Директор», «Композиция», «Дизайнер уровней», «Программист», «Локализация» и т. Д.).
  • Имя консоли (например, «Game Boy Advance»)

Проблема

До сих пор кажется, что независимо от того, что я проектирую, существуют избыточность данных и отношения M: N между интересующими типами сущностей повсюду. Однако я чувствую, что разработчики баз данных должны постоянно сталкиваться с такой проблемой, поэтому должно быть решение.


Примечание : я хорошо могу найти данные для заполнения таблицы, проблема заключается в организации их в базу данных с таблицами в нормализованной форме.

dpolaristar
источник
1
Комментарии перемещены в чат по запросу.
Пол Уайт восстановил Монику

Ответы:

18

Да, идентификация ассоциаций или отношений «многие ко многим» (для краткости M: N) - это ситуация, с которой практикующий специалист по базам данных довольно часто сталкивается при разработке концептуальной схемы. Связи указанных коэффициентов кардинальности возникают в бизнес-средах очень различной природы, и при правильном представлении на логическом уровне посредством, например, соглашения SQL-DDL, они не вносят вредных избыточностей.

Таким образом, цель упражнения по моделированию базы данных должна заключаться в том, чтобы с высокой точностью отражать соответствующие характеристики интересующего бизнес-контекста ; следовательно, если вы правильно определили, что существует множество ассоциаций M: N, вы должны выразить их в (а) концептуальной схеме, а также в (б) соответствующих декларациях логического уровня, независимо от того, сколько соединений этого - или любого другой - вид коэффициентов кардинальности должны быть рассмотрены.

Бизнес правила

Вы поставили хорошо контекстуализированный вопрос, а также пояснили, что база данных, над которой вы работаете, является чисто гипотетической, что является важным моментом, поскольку я считаю, что бизнес-сценарий «реального мира», такой как рассматриваемый, будет гораздо более обширным и, следовательно, предполагает более сложные информационные требования.

Я решил (1) внести несколько модификаций и дополнений в предоставленные вами бизнес-правила, чтобы (2) создать более описательную концептуальную схему - хотя все еще довольно гипотетическую -. Вот некоторые из формулировок, которые я собрал:

  • Сторона 1 является либо лицо или организация
  • Партия классифицируется точно-один PartyType
  • PartyType классифицирует ноль-один-или-многие Стороны
  • Организация разрабатывает нулевые один или много- продукты
  • Продукт представляет собой либо системы или игры
  • Продукт классифицируется точно-один ProductType
  • Система каталогизирована ровно-одной SystemType
  • Игра может быть воспроизведена через один-ко-многим системам
  • Система используется для воспроизведения один-ко-многим Игр
  • Игра классифицируется нулевым одной или многим жанрам
  • Жанр классифицирует ноль-один-или-много игр
  • A Продукт берет свое начало один-ко-многим Джобсом
  • Работа выполняется на ноль-один-или-многих людей , , которые играют в роли в Коллабораторов
  • Лицо является Collaborator в нуль один или-много рабочих мест

1 Сторона - это термин, используемый в правовом контексте, когда он относится к какому-либо лицу или группе лиц, которые составляют единое целое, поэтому данный термин подходит для обозначения людей и организаций .


Диаграмма IDEF1X

Впоследствии я создал диаграмму IDEF1X 2 , показанную на рисунке 1 (не забудьте нажать на ссылку, чтобы увидеть ее в более высоком разрешении), консолидируя в одном графическом устройстве представленные выше бизнес-правила (наряду с некоторыми другими, которые кажутся актуальными):

Рисунок 1 - Диаграмма видео Gae Jobs IDEF1X


2 Определение интеграции для информационного моделирования ( IDEF1X ) - это очень рекомендуемый метод моделирования данных, который был установлен в качестве стандарта в декабре 1993 года Национальным институтом стандартов и технологий США (NIST). Он основан на (а) раннем теоретическом материале, автором которого является единственный создатель реляционной модели, то есть доктор Э. Ф. Кодд; (b) представление данных об отношениях между сущностями, разработанное доктором П.П. Ченом ; а также о (c) методике проектирования логических баз данных, созданной Робертом Г. Брауном.


Как вы можете видеть, я изобразил только три ассоциации M: N с помощью соответствующих типов ассоциативных сущностей , то есть:

  • коллаборационист
  • SystemGame
  • GameGenre

Среди других аспектов, есть две отличные структуры подтипа супертипа , где:

  • Персона и Организация являются взаимоисключающими подтипами сущностей Стороны , их подтипами

  • Продукт - это супертип System и Game , которые, в свою очередь, являются взаимоисключающими подтипами.

Если вы не знакомы с ассоциациями супертип-подтип, вы можете найти помощь, например, мои ответы на вопросы, озаглавленные:

Иллюстративная логическая компоновка SQL-DDL

Соответственно, мы должны убедиться, что на логическом уровне:

  • Каждый тип сущности представлен отдельной базовой таблицей
  • Каждое отдельное свойство применимого типа объекта обозначается конкретным столбцом
  • Точный тип данных фиксирован для каждого столбца , чтобы гарантировать, что все содержащиеся в нем значения принадлежат конкретному и четко определенному набору, будь то INT, DATETIME, CHAR и т. Д. (Конечно, при использовании, например, Firebird или PostgreSQL , вы могли бы использовать более мощные ДОМЕНЫ)
  • Несколько ограничений настраиваются (декларативно), чтобы гарантировать, что утверждения в виде строк, сохраняемых во всех таблицах, соответствуют бизнес-правилам, определенным на концептуальном уровне

Поэтому я объявил следующую схему DDL на основе ранее показанной диаграммы IDEF1X:

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 для нескольких таблиц, которые обозначают иерархию соединений, которые имеют место между концептуальными типами сущностей, расположение, которое может быть очень полезным в отношении извлечения данных, когда, например, выражается SELECT операции, включающие предложения JOIN для получения производных таблиц.

Да, (i) каждая ассоциация M: N и (ii) каждый из связанных типов объектов обозначается (iii) соответствующей таблицей в логической структуре DDL, поэтому обратите особое внимание на ограничения PRIMARY и FOREIGN KEY (и примечания, которые я оставил в качестве комментариев) таблиц, представляющих эти концептуальные элементы, поскольку они помогают гарантировать, что соединения между соответствующими строками соответствуют применимым коэффициентам кардинальности.

Использование составных ключей было введено д-ром Э.Ф. Коддом с самого начала реляционной парадигмы, что продемонстрировано на примерах, которые он включил в свою основополагающую работу 1970 года, озаглавленную «Реляционная модель для больших совместно используемых банков данных» (которая точно также представляет самый элегантный метод обработки концептуальных ассоциаций M: N).

Я установил db <> fiddle и SQL Fiddle , оба работающие на Microsoft SQL Server 2014, чтобы можно было проверить структуру «в действии».

нормализация

Нормализация - это процедура логического уровня, которая подразумевает, в основном, следующее:

  1. Устранение неатомарных столбцов через первую нормальную форму, так что манипулирование данными и их сжатие намного легче справиться с использованием подъязыка данных (например, SQL).

  2. Избавление от нежелательных зависимостей между столбцами определенной таблицы с помощью последовательных нормальных форм, чтобы избежать аномалий обновления .

Естественно, необходимо учитывать значение, которое несут рассматриваемая таблица (и) и колонка (и).

Мне нравится думать о нормализации как о тесте, основанном на науке, который дизайнер применяет к соответствующим элементам после того, как он определил стабильное расположение на логическом уровне, чтобы определить, соответствуют ли его элементы каждой из нормальных форм или нет. Затем, при необходимости, дизайнер принимает соответствующие корректирующие меры.

избыточность

В реляционной модели, хотя дублирование значений, содержащихся в столбцах, не только допустимо, но и ожидается , повторяющиеся строки запрещены . В этой степени, насколько я вижу, во всех таблицах, включенных в логическую структуру, представленную ранее, предотвращается дублирование строк и другие виды вредных избыточностей, возможно, вы хотели бы прояснить свою озабоченность в этом отношении.

В любом случае, вы, безусловно, можете (а) самостоятельно оценить указанную структуру с помощью обычных форм, чтобы определить, соответствует ли она требованиям, и (б) изменить ее при необходимости.

Связанные ресурсы

  • В этой серии публикаций я представлю некоторые соображения по поводу прямой ассоциации M: N, которая может связывать экземпляры двух разных типов сущностей.
  • В этом другом я предлагаю подход для обработки вхождения «ведомости материалов» или «взрыва деталей», в котором я описываю, как соединять отдельные экземпляры одного и того же типа сущности.

Троичные ассоциации

Есть еще один важный аспект, который вы затронули в комментариях (опубликованных в удаленном ответе):

Каждый раз, когда я пытаюсь создать мост, у элементов этого моста также есть «многие ко многим», у меня складывается впечатление, что это запрещено или, по крайней мере, не рекомендуется.

Это обстоятельство, похоже, указывает на то, что одна из ваших проблем связана с концептуальными троичными ассоциациями . В сущности, такого рода ассоциации возникают, когда существуют (1) отношения, включающие (2) два других отношения, иными словами «отношения между отношениями» - тоже типичная ситуация, поскольку отношения - это сущность сама по себе -.

Эти механизмы, при надлежащем управлении, также не приносят вредных увольнений. И, да, если есть определенный вариант использования, в котором вы указываете, что такие отношения представляются между типами сущностей «реального мира», вы должны (i) моделировать и (ii) объявлять их с точностью на логическом уровне.

  • Вот вопрос и ответ, где мы анализируем область дискурса об исследованиях , которая включает пример троичной ассоциации.
  • В этом очень хороший ответ , @Ypercube представляет собой схему и соответствующую структуру DDL для интересной форме алмаза отношений , которая очень похожа на этот класс сценариев.
MDCCL
источник