Первичный ключ таблицы SQL-many-to-many

этот вопрос возникает после прочтения комментария в этом вопросе:

Дизайн Базы Данных

когда вы создаете таблицу "многие ко многим", следует ли создавать составной первичный ключ на двух столбцах внешнего ключа или создавать суррогатный первичный ключ" ID " с автоматическим приращением и просто помещать индексы на два столбца FK (и, возможно, уникальное ограничение)? Каковы последствия для производительности для вставки новых записей/повторной индексации в каждую кейс?

в основном, это:

PartDevice
----------
PartID (PK/FK)
DeviceID (PK/FK)

и так:

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)

комментатор говорит:

сделать два идентификатора PK означает, что таблица физически сортируется на диске в этом порядке. Так что если мы вставим (Часть1/Устройство1), (Часть1/Устройства2), (Часть 2 / Device3), затем (Часть 1 / Device3) базу придется сломать разделите таблицу и вставьте последнюю между позициями 2 и 3. Для многих записи, это становится очень проблематичным как он включает в себя перетасовку сотен, тысячи или миллионы записей каждый раз, когда добавляется. По контрасту, autoincrementing PK позволяет новому записи, которые будут прикреплены к концу.

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

5 ответов


С простым сопоставлением двух столбцов "многие ко многим" я не вижу никакого реального преимущества в наличии суррогатного ключа. Наличие первичного ключа на (col1,col2) гарантируется уникальным (при условии, что ваш col1 и col2 значения в ссылочных таблицах уникальны) и отдельный индекс на (col2,col1) поймает те случаи, когда противоположный порядок будет выполняться быстрее. Суррогат-пустая трата пространства.

вам не понадобятся индексы для отдельных столбцов, так как таблица должна использоваться только для соединения две таблицы вместе.

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

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

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


для таблиц ссылок не требуется суррогатный ключ.

один ПК на (col1, col2) и другой уникальный индекс на (col2, col1) - это все, что вам нужно

Если вы не используете ORM, который не может справиться и диктует ваш дизайн БД для вас...

Edit: я ответил То же самое здесь:SQL: вам нужен автоматический инкрементный первичный ключ для многих таблиц?


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

PartDevice
----------
ID (PK/auto-increment)
PartID (FK)
DeviceID (FK)
Other Details

легко вытащить "другие детали" с помощью PartDevice.ID как FK. Таким образом, необходимо использовать инкрементный первичный ключ.


самый короткий и самый прямой способ ответить на ваш вопрос-сказать, что будет влияние на производительность, если две таблицы, которые вы связываете, не имеют последовательных первичных ключей. Как вы заявили/процитировали, индекс таблицы ссылок либо фрагментируется, либо СУБД будет сложнее вставлять записи, если таблица ссылок не имеет собственного последовательного первичного ключа. Именно по этой причине большинство людей помещают последовательно увеличивающийся первичный ключ в таблицы ссылок.


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

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

Index или PK-лучший способ убедиться, что нет дубликатов. PK позволяет таким инструментам, как Microsoft Management Studio, выполнять некоторые работы (создавать представления) для вас