Схема: двусторонние отношения?какая таблица / сущность должна иметь «предпочтение»? - PullRequest
2 голосов
/ 06 февраля 2011

Я не уверен, как задать этот вопрос, поэтому я буду наглядно продемонстрировать пример.

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

Инстинктивно, я бы смоделировал это как:

Table: Profile
--------------
ProfileID
SelectedProfilePictureId //fk to ProfilePicture
Name, Age, Etc

Table: ProfilePicture
---------------------
ProfilePictureId
ProfileId //fk to Profile, indicating which Profile this picture belongs to
Url, DateTaken, Etc

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

Это плохая форма?Должна ли таблица Profile быть полностью независимой от таблицы ProfilePicture?Есть ли «правильный» способ смоделировать это в соответствии с теорией проектирования баз данных, или это до усмотрения программиста?

Ответы [ 3 ]

6 голосов
/ 06 февраля 2011

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

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

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

РЕДАКТИРОВАТЬ: в ответ на комментарий.

1) Циклическая ссылка отсутствует, поскольку Profiles является родительской для обеих дочерних таблиц, она не зацикливается на Profiles.

Profiles
   |  |
   |  +-----> PreferredPicture
   |  +----->
   |  |
  \|/ |
ProfilePictures

2) Первичным ключом предпочтительного изображения является ProfileId, технически это дочерняя таблица профилей 1: 1.

1 голос
/ 06 февраля 2011

Я работал с видом "циклической ссылки" в других проектах ранее.

, если Profile.SelectedProfilePictureId имеет значение Nullable, а ProfilePicture.ProfileId - обязательно, это нормально.только если вы сделаете оба fk обязательными, вы получите реальную круговую ссылку, что невозможно.

1 голос
/ 06 февраля 2011

зачем вам нужно хранить ProfileID в таблице ProfilePicture ??

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

ProfileID <-> ProfilePictureID

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