Должна ли таблица базы данных, которая содержит два столбца, которые являются внешними ключами, иметь третий столбец, который является первичным ключом? - PullRequest
11 голосов
/ 21 июня 2010

Полагаю, нет, поскольку внешние ключи являются первичными ключами в своих собственных таблицах, поэтому они будут уникальными.

Подробнее

Я использую MySQL, а в следующих трех таблицах используется механизм InnoDB.

=======================    =======================
| galleries           |    | images              |
|---------------------|    |---------------------|
| PK | gallery_id     |    | PK | image_id       |
|    | name           |    |    | title          |
|    | description    |    |    | description    |
|    | max_images     |    |    | filename       |
|    | enabled        |    |    | enabled        |
=======================    =======================

========================
| galleries_images     |
|----------------------|
| FK | gallery_id      |
| FK | image_id        |  <----- Should I add a PK to this table?
========================

Эпилог

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

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

============================
| galleries_images         |
|--------------------------|
| PK, FK | image_id        |
| FK     | gallery_id      | 
|        | order_num       |
============================

Еще раз спасибо!

Эпилог II

Спасибо тем из вас, кто указал, что мне даже не нужен этот стол. Я не предоставил самую полную информацию для начала. В итоге я вообще отбросил таблицу galleries_images и просто добавил gallery_id в качестве внешнего ключа к таблице images. Как бы то ни было, я все же узнал больше, чем думал, и благодарен за помощь.

Ответы [ 6 ]

10 голосов
/ 21 июня 2010

Теоретически, если комбинация двух внешних ключей (FK) уникальна в таблице, или если комбинация двух FK плюс некоторый другой столбец уникальна, то в таблице есть составной первичный ключ и нет Строго необходимо ввести еще один ключ в качестве суррогатного первичного ключа. Тем не менее, нередко бывает, что люди добавляют дополнительный ключ. Частично это зависит от того, для чего еще будут использоваться данные в таблице с составным первичным ключом. Если он описывает что-то, что само будет иметь строки из других таблиц, связанных с ним, то, возможно, имеет смысл ввести простой PK.

Кажется, что для некоторых программ требуются простые PK, хотя для реляционной модели данных это не так.

6 голосов
/ 21 июня 2010

Все таблицы должны иметь первичный ключ.

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

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

Редактировать

После обновления вашего вопроса я просто сделаю составной первичный ключ для gallery_id, image_id.Я не вижу никакой пользы от добавления нового столбца.

5 голосов
/ 21 июня 2010

Ответ обычно "да".Типом таблицы, которую вы описываете, является таблица ассоциаций , в которой хранятся ассоциации.Поскольку эти записи интересны сами по себе, и, возможно, вы захотите просмотреть их позже, они должны иметь значимую идентичность.

Например, возможно, у вас есть таблица players и matchups стол для вашей теннисной лиги.matchups может содержать не более чем внешние ключи двух игроков, которые играли друг против друга;это ассоциация между двумя игроками.

Но позже вы можете записать другую информацию, относящуюся к этой ассоциации: время матча, счет игры и так далее.И, конечно же, как только вы захотите провести более одного матча между одними и теми же игроками, вам нужно будет различать каждый матч.Таким образом, вы захотите дать каждому matchup свою собственную идентификацию в форме первичного ключа.

Обновление:

========================
| galleries_images     |
|----------------------|
| FK | gallery_id      |
| FK | image_id        |  <----- Should I add a PK to this table?
========================

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

2 голосов
/ 23 июня 2010

Этот ответ связан с его вопросом: я знаю, должна быть новая тема, но неважно.Пожалуйста, не понизьте просто за это.

Например, вы можете создать таблицу Order_image_lock (идентификатор галереи (первичный ключ), start_time).

Создание 3 методов / sprocs: GetLock, CheckLock, DropLock.

Когда вы хотите изменить порядок портфеля, вы вызываете GetLock, который вставляет (gallary_id, sysdate).

Если это работает, вы можете продолжить.Если это не сработает на ПК, кто-то еще переупорядочивает, поднять исключение.

Когда вы будете готовы к переупорядочению, вызовите CheckLock, чтобы увидеть, сохраняется ли ваша блокировка (вы поймете, почему), если она у вас есть, обновите переупорядоченные значения, если нет, перейдите к GetLock.

Когда вы закончите, DropLock удаляет запись.

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

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

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

2 голосов
/ 21 июня 2010

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

1 голос
/ 21 июня 2010

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

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

...