Правильный способ структурировать таблицу «заметки» для нескольких наборов данных? - PullRequest
4 голосов
/ 04 февраля 2011

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

В моем приложении есть такие таблицы:
контакты
свойства
события

Я добавляю метод прикрепления примечания к элементам в приведенных выше таблицах.Мне бы хотелось, чтобы одна заметка могла ассоциироваться с контактом, свойством или событием (или их комбинацией).

В настоящее время моя таблица notes выглядит следующим образом:

noteID int
noteCreated datatime
noteContent text
userID int ( идентификатор пользователя, создавшего заметку )
contactID int
propertyID int
eventID int

Указанная часть выделена жирным шрифтом.Прямо сейчас, когда я создаю заметку для события , я просто вставляю заметку и также устанавливаю eventID .Если событие также относится к контакту , я также могу добавить contactID (будут установлены contactID и eventID).Хотя это работает, я думаю, что это неэффективно и не нормализовано должным образом.

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

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

noteID int
targetID int
targetType int

Буду признателен за большую помощь.Спасибо:)

Ответы [ 3 ]

3 голосов
/ 04 февраля 2011

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

Если это отношение «многие ко многим», например, у контакта может быть много заметок, то вам нужно создать отдельную таблицу, скажем contact_notes с двумя столбцами - contactID и noteID.

Не зацикливайтесь на том факте, что заметка может быть связана с несколькими сущностями. Это действительно никак не влияет на то, как вы его моделируете.

0 голосов
/ 04 февраля 2011

Что вы описываете ...

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

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

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

noteID int
targetID int
targetType int

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

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

ID int          'autonumber to provide a reliable and efficient unique key'
noteID int
contactID int   'allow nulls'
propertyID int  'allow nulls'
eventID int     'allow nulls'
0 голосов
/ 04 февраля 2011

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

noteID
noteCreated
noteContent 
userID
noteType (contact, property or event)
RelatedID

, тогда вы можете присоединиться, используя:

FROM Contacts C
INNER JOIN Notes N on C.ID = N.RelatedID and N.noteType = 'contact'

или

FROM Property P
INNER JOIN Notes N on P.ID = N.RelatedID and N.noteType = 'property'
...