Наилучшая практика для отношений, используемых несколькими таблицами - PullRequest
2 голосов
/ 13 октября 2009

Я продолжаю сталкиваться с этой проблемой проектирования, и я пока не доволен своим решением. Проблема заключается в следующем:

У меня есть два или более объекта, таких как Люди и Собаки, и они оба связаны с таблицей Notes, в которой хранится поле сообщения и некоторые метаданные о сообщении, например, автор.

1) Первый вариант - не применять внешний ключ. Таким образом, я могу хранить FK, например, peopleId или dogId (независимо от того, что это), в том же общем поле FK, что и fkId. Затем я бы сохранил tableId в другом столбце - можно надеяться получить идентификатор таблицы из метаданных RDMS, но вы также можете получить грязный хак и явно создать таблицу, полную таблиц, которые вам придется обновлять вручную. , Это действительно небрежно, и я просто упомяну это для полноты.

2) Клонируйте таблицу Notes для каждой таблицы, которая нуждается в ней, например PeopleNotes, DogNotes, CatNotes и т. Д. Это создает довольно серьезную проблему нормализации.

Что другие люди сделали в подобных ситуациях?

Ответы [ 5 ]

6 голосов
/ 13 октября 2009

Если это ваши «модельные» таблицы:

dog Table:
id | name | ...
1  | Rex
2  | Fido

people Table:
id | name | ...
1  | Bob
2  | Alice

notes Table:
id | text | ...
1  | A nice dog.
2  | A bad dog.
3  | A nice person.

Вы можете хранить отношения в отдельных таблицах:

dog_note Table:
dog_id | note_id
1      | 1
2      | 2

note_people Table:
person_id | note_id
1         | 3
2         | 3

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

2 голосов
/ 13 октября 2009

Как насчет двух новых таблиц - Dog2Notes и People2Notes? Собаки, Люди и Заметки - все записи с Ключами, которые связаны друг с другом. Собаки и люди могут иметь более одной заметки, и заметками можно поделиться.

Если у Собак и Людей может быть только ОДНА нота, добавьте NOteID в каждую из этих таблиц?

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

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

dog Table:
id | name | masterId
1  | Rex  |  1
2  | Fido |  4

people Table:
id | name | masterId
1  | Bob  |  2
2  | Alice|  3

masterId
id
1  
2  
3  
4  

notes
id | note       | masterId
1  | "Hi"       | 3
2  | "Good day" | 2

Это облегчит масштабируемость, потому что если вам нужно добавить новый тип сущности (например, cat), вам не нужно добавлять другую таблицу (cat_note), это особенно полезно, если вы добавляете новый тип заметки (например, book) ) потому что тогда вам нужно будет добавить новые таблицы для всех типов ваших сущностей (person_book, dog_book и т. д.). Наконец, вы можете напрямую связать любую таблицу сущностей с таблицей заметок.

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

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

0 голосов
/ 13 октября 2009

это действительно зависит от того, как вы запрашиваете ваши данные, но как насчет чего-то подобного, предполагается, что существует несколько заметок на человека / собаку:

PeopleTable

PeopleID
NoteID
.....

DogTable

DogID
NoteID
...

NoteTable

NoteID

NoteDetailTable

NoteDetailID
NoteID
NoteText
...
0 голосов
/ 13 октября 2009

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

...