Первичный ключ / кластерный ключ для таблиц соединений - PullRequest
7 голосов
/ 09 марта 2010

Допустим, у нас есть таблица Product, таблица Order и (таблица соединений) ProductOrder.

ProductOrder будет иметь ProductID и OrderID.
В большинстве наших систем эти таблицы также имеют столбец автономного номера с именем ID.

Как лучше всего размещать первичный ключ (и, следовательно, кластерный ключ)?

  • Должен ли я сохранить первичный ключ поля ID и создать некластеризованный индекс для пары внешнего ключа (ProductID и OrderID)

  • Или я должен поставить первичный ключ пары внешних ключей (ProductID и OrderID) и поместить некластеризованный индекс в столбец идентификатора (если даже необходимо)

  • Или ... (умное замечание одного из вас:))

Ответы [ 4 ]

5 голосов
/ 09 марта 2010

Я знаю, что эти слова могут заставить вас съежиться, но "это зависит".

Скорее всего, вы хотите, чтобы заказ основывался на ProductID и / или OrderId, а не на столбце autonumber (суррогат), так как autonumber не имеет естественного значения в вашей базе данных. Возможно, вы хотите упорядочить таблицу соединений по тому же полю, что и родительская таблица.

  1. Сначала поймите, почему и как вы используете идентификатор суррогатного ключа на первом месте; это часто будет диктовать, как вы индексируете это. я Предположим, вы используете суррогатный ключ, потому что вы используете некоторые фреймворк, который хорошо работает с ключами одного столбца. Если нет конкретная причина проектирования, то для таблицы соединений, я бы упростил проблема и просто удалить идентификатор автонумера, если он не приносит другой выгода. Первичный ключ становится (ProductID, OrderID). Если не, Вы должны по крайней мере убедиться, что ваш индекс на (ProductID, Кортеж OrderID) уникален для сохранения целостности данных.

  2. Кластерные индексы хороши для последовательных сканирований / объединений, когда запрос требует результатов в том же порядке, в котором упорядочен индекс. Итак, посмотрите на ваши шаблоны доступа, выясните, по каким ключам вы будет делать последовательные, многорядные выборки / сканирования, и с помощью которого ключ, вы будете делать случайный, индивидуальный доступ к строке, и создать кластерный индекс по ключу, который вы будете сканировать чаще всего, а некластеризованный Индекс ключа для ключа, который вы будете использовать для произвольного доступа. Ты должен выберите один или другой, так как вы не можете кластеризовать оба.

ПРИМЕЧАНИЕ. Если у вас противоречивые требования, вам может помочь метод («трюк»). Если все столбцы в запросе найдены в индексе, то этот индекс является таблицей-кандидатом для механизма базы данных, который будет использоваться для удовлетворения требований запроса. Вы можете использовать этот факт для хранения данных в более чем одном порядке, даже если они конфликтуют друг с другом. Просто помните о плюсах и минусах добавления большего количества полей в индекс и принимайте осознанное решение после понимания характера и частоты запросов, которые будут обрабатываться.

3 голосов
/ 10 марта 2010

Правильный и единственный ответ:

  • Первичный ключ ('orderid' , 'productid')
  • Еще один индекс по ('productid' , 'orderid')
  • Любой может быть кластеризован, но PK по умолчанию

Потому что:

  • Вам не нужен индекс только для orderid или productid: оптимизатор будет использовать один из индексов
  • Скорее всего, вы будете использовать таблицу «обоими» способами
  • Вам не нужен суррогатный ключ, потому что он у вас уже есть в связанных таблицах. Так что 3-ий столбец тратит впустую пространство.
1 голос
/ 09 марта 2010

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

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

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

0 голосов
/ 09 марта 2010

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

Причина, по которой я это делаю, заключается в том, что чем больше я нормализую свои данные, тем больше ключей я буду использовать в соединениях. Я закончил с проектами, идущими на глубину от шести до семи уровней, и если бы я использовал ключи, переходящие с одного уровня на другой, я мог бы потенциально получить n ^ 2 ключей в объединении.

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

У меня все просто.

...