Связи с базой данных T-SQL ПК ФК То же имя? - PullRequest
0 голосов
/ 26 октября 2009

Сценарий

У меня есть 3 таблицы базы данных. Один для изображений, а два других - люди и места. Поскольку у каждого человека может быть много изображений, и у каждого места может быть много изображений, я хочу иметь ОДИНОЧНОЕ отношение между людьми и изображениями, а также местами и изображениями.

Вопрос

Должен ли внешний ключ называться тем же именем, что и первичный ключ? Или я могу назвать внешний ключ в таблице изображений чем-то общим, например, «PKTableID». Таким образом, мне нужна только одна таблица изображений.

Помощь с благодарностью.

С уважением,

EDIT:

Причина, по которой вы хотите иметь только одну таблицу изображений, заключается в том, что каждое изображение относится только к одной другой таблице. Кроме того, я использовал приведенный здесь пример двух таблиц, фактически база данных, которую я буду использовать, будет иметь 20 таблиц, поэтому я хотел знать, возможно ли по-прежнему использовать ОДИН СТОЛ ИЗОБРАЖЕНИЯ ДЛЯ 20 ОДНОМНОГИХ ОТНОШЕНИЙ

Ответы [ 5 ]

5 голосов
/ 26 октября 2009

EDIT

Если одно изображение когда-либо принадлежит только одной из двадцати таблиц, этот дизайн может работать:

People (PersonId, Name)
Places (PlaceId, Name)
Dogs (DogId, Breed)
Doors (DoorId, Height, Width)
Images (ImageId, ImageBinary, OwnerId, OwnerTable)

Где OwnerTable - это имя или код таблицы, которой принадлежит OwnerId.

Это сэкономит вам 20 FK в таблице изображений или 20 таблиц ассоциаций. Затем в соединениях вы должны указать OwnerTable в зависимости от таблицы, к которой вы присоединяетесь.

Вам потребуется использовать конвертируемые типы для идентификаторов (например, TINYINT, SMALLINT и INT), и, предпочтительно, один тип для всех (например, INT), и вам придется самостоятельно управлять ссылочной целостностью через триггеры или другие код.

/ EDIT

Вам нужно 5 таблиц, а не 3:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary)
ImagesPeople (ImageId, PersonId)
ImagesPlaces (ImageId, PlaceId)

Вы можете называть поля как хотите. People.Id, ImagesPeople.PersonId и т. Д.

Но то, что вы не можете сделать, это что-то вроде этого:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary, PlaceOrPersonId)

Ну, вы можете, но база данных не поможет вам навязать отношения или сказать, к какой таблице принадлежит FK. Как бы вы узнали? Есть хакерские обходные пути, такие как пошаговое увеличение идентификатора, добавление столбца типа к изображениям или использование идентификаторов GUID.

В качестве альтернативы:

Things (ThingId PK, Type)
People (ThingId PK/FK, Name, Age)
Places (ThingId PK/FK, Name, LatLon)
Images (ImageId PK, ImageBinary, ThingId FK)

Вы также можете сделать изображения "вещью". Иногда вы видите такие проекты. Это дает вам ссылочную целостность, но не исключительность типа. Вы можете иметь тот же ThingId в Люди, Места и Изображения, и база данных не будет заботиться. Вы должны были бы закодировать это правило самостоятельно.

Редактировать: по предложению Кайлона, сценарий 4:

People (PersonId, Name)
Places (PlaceId, Name)
PeopleImages (PeopleImageId, ImageBinary)
PlaceImages (PlaceImageId, ImageBinary)

Здесь изображения принадлежат исключительно одному человеку или месту. Аналогично версии 2, но с объявленными внешними ключами. Это может иметь некоторые преимущества в производительности по сравнению с 5 таблицами, поскольку требуется меньше соединений. Вы теряете «Изображение» как отдельную сущность, заменяемую «PeopleImage» и «PlaceImage».

1 голос
/ 26 октября 2009

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

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

1 голос
/ 26 октября 2009

Как отметил Питер, вам действительно нужны отношения многие ко многим, если только вы не хотите ограничить свои изображения только изображениями с одним человеком, хороший индекс мест будет отражать иерархическую природу названий мест (Монмартр, Париж, Франция = три возможных названия для одного места).

Теперь технически вы можете вызывать ваши индексы и таблицы как угодно, если они не являются зарезервированным словом и еще не были использованы, X, Y, Z12345 и WOBBLY - все допустимые имена для индекса.

На практике, однако, лучше всего следовать соглашению об именах, которое указывает, что хранится и для чего. Так что таблицы PEOPLE_X_IMAGES и PLACES_X_IMAGES были бы хорошей идеей в вашем случае. Вам не нужно ничего о людях или местах в реальной таблице изображений. Точно так же вам не нужно ничего об изображениях в таблицах PEOPLE и PLACES.

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

Как насчет

Person (PersonId PK, Name, ImageId FK)
Image (ImageId PK, Name)
Place (PlaceId PK, Name, ImageId FK)
0 голосов
/ 26 октября 2009

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

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