Справка по моделированию данных - добавить ли другую таблицу, изменить использование существующей таблицы или что-то еще? - PullRequest
2 голосов
/ 02 июня 2010

Предположим, у меня есть следующие таблицы и отношения:

Person
- Id (PK)
- Name

Человек может иметь 0 или более домашних животных:

Pet
- Id (PK)
- PersonId (FK)
- Name

Человек может иметь 0 или более атрибутов (например, возраст, рост, вес):

PersonAttribute
_ Id (PK)
- PersonId (FK)
- Name
- Value

ПРОБЛЕМА: Мне тоже нужно представлять атрибуты питомца. Как выясняется, эти атрибуты домашних животных в большинстве случаев идентичны атрибутам человека (например, животное может иметь возраст, рост и вес). Как мне представить атрибуты питомца?

  1. Создать ли таблицу PetAttribute?

    PetAttribute

    • Id (PK)
    • PetId (FK)
    • Имя
    • Значение
  2. Менять ли PersonAttribute на GenericAttribute и иметь ли в нем 2 внешних ключа - один для подключения к Person, другой для подключения к Pet?

    GenericAttribute

    • Id (PK)
    • PersonId (FK)
    • PetId (FK)
    • Имя
    • Value

    ПРИМЕЧАНИЕ: если PersonId установлен, то PetId не установлен. Если PetId установлен, PersonId не установлен.

  3. Что-то еще?

Ответы [ 3 ]

3 голосов
/ 02 июня 2010

На самом деле вы должны удалить таблицу PersonAttribute и просто добавить столбцы (возраст, рост, вес и т. Д.) В таблицу Person.

Добавьте похожие столбцы в таблицу питомцев. Это позволяет избежать распространенной ошибки новичка, называемой «Таблица значений атрибутов сущности». См., Например, « Пять простых ошибок проектирования баз данных, которых следует избегать ».

Единственный раз, когда вы должны поместить «атрибут», например, вес, в отдельную таблицу, это когда владелец может иметь более одного этого точного атрибута. Тогда таблица должна быть конкретной, «WeightHistory», если это список весов во времени и т. Д.

1 голос
/ 02 июня 2010

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

2 кажется плохой идеей, так как неудобно применятьцелостность с такого рода настройками.

для 3, могли бы вы иметь таблицу ссылок в середине для группы атрибутов, которая содержит идентификатор группы и идентификаторы отдельных GenericAttribute с, затему вас есть AttributeGroupId как собственность человека и домашнего животного?

Table AttributeGroup
- Id (PK)
- GenericAttributeId  (PK,FK)

Table GenericAttribute
- Id (PK)
- Name
- Value

Person
- Id (PK)
- Name
- AttributeGroupId

Pet
- Id (PK)
- Name
- AttributeGroupId

, поэтому AttributeGroupId идентифицирует коллекцию GenericAttribute экземпляров, которые связаны с Pet илиPerson.Это также означает, что если вам нужно приписать что-то еще в будущем, вам просто нужно добавить AttributeGroupId к этой вещи.

РЕДАКТИРОВАТЬ:

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

EDIT2:

Как у вас естьу вас может быть фиксированный набор атрибутов, которые могут иметь как питомец, так и человек:

Attributes
- Id (PK)
- Attribute1
- Attribute2
...
- AttributeN

Person
- Id (PK)
- Name
- AttributesId (FK)

Pet
- Id (PK)
- Name
- AttributesId (FK)

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

0 голосов
/ 03 июня 2010

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

Если бы это зависело от меня, я бы просто держал две таблицы раздельно, пока отсутствие таблицы для PersonOrPetAttribute не начало усложнять запросы.

Если вы видите это по-разному, то вам, вероятно, следует выполнить поиск в Google по «Обобщению специализации реляционного моделирования». В этом разделе вы найдете несколько хороших статей по моделированию шаблона gen-spec с помощью таблиц. Статьи расскажут вам больше о том, как это сделать, чем я собираюсь описать в этом ответе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...