Архитектура SQL: это оправданный случай, когда только одна таблица хранит несколько типов сущностей? (с использованием самостоятельного СОЕДИНЕНИЯ)

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

ВОПРОС: Могу ли я сделать это и при этом иметь «здоровую» архитектуру?

Пример следует

Предположим, два типа сущностей, корпорация и человек. Корпорация обычно принадлежит человеку, но иногда другая корпорация владеет корпорацией.

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

Если вы считаете, что владелец [родитель] корпорации [ребенок] может быть либо физическим лицом, либо корпорацией, вы можете начать видеть проблему в сохранении третьей нормальной формы и избегании избыточности.

В отличие от моего примера, если бы только люди могли владеть корпорациями, таблица связей владения была бы очень стандартной, со столбцами: OwnershipID (вроде необязательный), CorporationID, PersonID.

Вместо этого вам понадобится что-то вроде: OwnershipID, CorporationID, OwnerID, OwnerEntityType (corp or person). Не поймите меня неправильно, вы можете выполнить эту работу, но это будет неинтересно, мягко говоря.

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

Аналогично этой «проблеме» зарегистрированный агент также может быть корпорацией, такой как юридическая фирма, CPA или компания, занимающаяся регистрацией деловых документов, чтобы назвать некоторые типичные примеры. Точно так же, как агент-человек, агент-корпорация действительно не должна получать свою собственную запись как агент-сущность. Вместо этого ему необходимо вернуться к своему корпоративному существованию в таблице Corporation. [за исключением того, что я m, в конечном счете говоря, что не нужно иметь таблицу CorporationEntity]

Точно так же, как таблица ссылок, которая сопоставляет каждую корпорацию с ее владельцем (ами) любого типа, человека или корпорации, у вас может быть таблица ссылок агента из: AgentRepresentationID, CorporationID, AgentID , AgentType ... но опять же, было бы некрасиво (ИМО), когда вам нужно собрать вместе связанных агентов - некоторые из таблицы Person, некоторые из таблицы Corporation.

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

Таблица: EntityAll
Ключевые столбцы: EntityID, EntityType (или EntityTypeID, если вы настаиваете, перейдите по ссылке, чтобы получить описание), EntityName (есть проблемы с именами и различными типами ... вне темы к этому сообщению)

Таблица ссылок: Корпорация
Ключевые столбцы: OwnershipID (опять же, мой комментарий, что в этом нет необходимости), ChildEntityID (принадлежащий объект; для ясности он назван «Дочерний», я бы не стал его так называть) ParentEntityID (родительский объект)

Таблица ссылок: AgentRepresentation
Ключевые столбцы: AgentRepresentationID (... я не буду этого говорить), CorporationEntityID (представляемая корпоративная сущность), AgentEntityID (из таблицы сущностей, приравнивается к записи, которая является здесь агентом)

Хотя вы можете быть в порядке с моей архитектурой, вас должно немного беспокоить именование столбцов в таблицах ссылок. Это не дает мне покоя. Обычно имена второго и третьего столбцов в этих таблицах точно соответствуют именам столбцов, которые вы ПРИСОЕДИНЯЕТЕ в соответствующей таблице каждой сущности (ха-ха, но у каждой сущности нет соответствующей таблицы, поэтому вы можете '' t должны совпадать имена столбцов таблицы ссылок с именами исходных столбцов, потому что они ОДИНАКОВЫЕ). Технически это не имеет значения, но это нарушит ваши соглашения об именах, что имеет значение, но недостаточно, чтобы этого не делать.

Если я еще не довел его до дома, вот как вы все соберете. . Вы ПРИСОЕДИНЯЕТЕСЬ к таблице EntityAll самостоятельно, чтобы получить то, что вам нужно.

Перечислите все корпуса и их владельцев (в T-SQL):

SELECT Corp.EntityName as CorpName, Owner.EntityName as OwnerName
FROM EntityAll as Corp
JOIN CorporationOwnership as Link on (Corp.EntityID = Link.ChildEntityID)
JOIN EntityAll as Owner on (Link.ParentEntityID = Owner.EntityID)

Следовательно, вы бы сделали то же самое, чтобы вернуть агента, вместо владелец (и).

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

PS I недавно предоставил этот пример как ответ на старый вопрос о SO. Это старый вопрос, поэтому диалога не было. Хороший дизайн таблицы БД: одна таблица, в которой смешаны разные сущности, или отдельная таблица для каждой сущности

5
задан Community 23 May 2017 в 12:14
поделиться