2011-02-05 2 views
2

Я не уверен, как задать этот вопрос, так что я буду как можно яснее с примером.Схема: двусторонние отношения? какая таблица/организация должна иметь «предпочтение»?

В приложении, таком как 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 или для получения ProfilePicture профиля, но вставки и обновления немного неудобны.

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

ответ

6

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

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

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

EDIT: в ответ на комментарий.

1) Нет циклическая ссылка, потому что Profiles является родителем обоих дочерних таблиц, это не петля вокруг Профили

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

2) Первичный ключ Preferred Картина является ProfileID, это технически 1: 1 ребенок таблица профилей.

+0

Мне удалось создать круглые ссылки в Sql Server 2008 R2, но это было немного взломать (я не смог создать новый ProfilePicture и установить поле ProfileProfileId профиля во время одной и той же транзакции, например). – smalltowndev

+0

Итак, вы говорите, что третья таблица нарушает круговую ссылку, потому что таблица профиля больше не ссылается на таблицу ProfilePicture? И таблица PreferredPictures имела бы взаимно-однозначную связь с каждой таблицей Profiles и ProfilePictures?Каким будет первичный ключ таблицы PreferredPictures? (извините за столько вопросов!) – smalltowndev

+0

Это имеет смысл ... спасибо за информацию и искусство ascii! Я отвечу на ваш ответ, как только мне удастся получить 15 «репутацию» на этом сайте. – smalltowndev

1

Зачем вам нужно сохранить идентификатор ProfileID в таблице ProfilePicture?

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

< ProfileID -> ProfilePictureID

+0

Так что таблице ProfilePicture не нужно знать таблицу профилей? Он просто описал бы изображение, а третья таблица будет относить профили к ProfilePictures? Будет ли эта третья таблица также сохранять, какой профиль ProfilePicture «выбран», или это будет в другой таблице? – smalltowndev

+0

Возможно, у вас есть Picturestable в тишине ProfileID, поэтому вы сможете выбрать все изображения, относящиеся к профилю X, поскольку каждая игра принадлежит только одному профилю. кроме того, вам нужно знать, какой образ является выбранным профилем профиля, вы можете сделать это либо путем создания логического IsSelectedProfilePicture-Column, где вы установите true только тот, который выбран, или, лучше, вы делаете третью таблицу, в которой вы сохраняете только ссылку на профиля и изображения. – CloudyMarble

+0

+ для «3-й таблицы». – onedaywhen

1

Я работал с родом «круговой ссылка» на других проектах раньше.

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

Смежные вопросы