Где разместить первичный ключ - PullRequest
3 голосов
/ 22 февраля 2009

Насколько мне известно, SQL Server 2008 будет разрешать только один кластеризованный индекс на таблицу. Ради этого вопроса, скажем, у меня есть список отправленных пользователями историй, который содержит следующие столбцы.

ID (int, первичный ключ)
Название (nvarchar)
Url (nvarchar)
UniqueName (nvarchar) Это URL-слаг (бла-бла-бла)
CategoryID (int, FK для таблицы категорий)

В большинстве случаев истории никогда не будут запрашиваться по ID. Большинство запросов будет выполняться либо по CategoryID, либо по UniqueName.

Я новичок в индексировании, поэтому я предположил, что было бы лучше разместить 2 некластеризованных индекса в этой таблице. Один на UniqueName и один на CategoryID. После некоторого чтения об индексах кажется, что иметь кластерный индекс на UniqueName было бы очень полезно. Учитывая, что UniqueName является ... уникальным, было бы выгодно поместить первичный ключ в UniuqeName и избавиться от поля идентификатора? Что касается CategoryID, я предполагаю, что некластеризованный индекс будет работать нормально.

Спасибо.

Ответы [ 5 ]

3 голосов
/ 22 февраля 2009

Во-первых, вы можете поместить кластерный индекс на уникальное имя, оно не обязательно должно быть в поле id. Если вы мало или совсем не присоединяетесь к этой таблице, вы можете избавиться от идентификатора. В любом случае я бы поместил уникальный индекс в поле уникального имени (при этом вы можете обнаружить, что он не настолько уникален, как вы думали, что это будет!).

Если вы много присоединяетесь, я бы оставил поле id, оно меньше и более эффективно для присоединения.

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

1 голос
/ 22 февраля 2009

Как правило, всегда лучше индексировать таблицу по ключу идентификации и использовать его в качестве кластеризованного индекса. Здесь есть простое правило

Не используйте значимый столбец в качестве основного индекса

Причина этого заключается в том, что обычно использование PK в значимом столбце приводит к проблемам с обслуживанием. Это эмпирическое правило, поэтому его можно переопределить в таких условиях, но обычно лучше работать с предполагаемой позиции по умолчанию для каждой таблицы, индексированной (кластеризованным) бессмысленным столбцом идентификаторов. Это имеет тенденцию быть более эффективным для объединений, и, как правило, это дизайн по умолчанию, который принимает большинство администраторов баз данных, поэтому он не поднимает брови и не создает проблем, потому что их система не такая, как может предположить следующий администратор баз данных. Бессмысленные PK неизменно более гибки и могут легче адаптироваться к изменяющимся обстоятельствам, чем в противном случае

Когда переопределить правило? Только если вы предполагаете проблемы с производительностью. Для большинства баз данных с разумной нагрузкой на современное аппаратное обеспечение с соответствующей индексацией у вас не возникнет никаких проблем, если вы не выжмете из них последнюю миллисекунду производительности путем кластеризации оптимального индекса. Циклы DBA и Programmer намного дороже, чем циклы CPU, и если вы выберете лишнюю миллисекунду или около того из своих запросов, приняв другую стратегию, то это просто не стоит. Однако, если вы смотрите на таблицу с приближением к миллиону строк, это другой вопрос. Это очень сильно зависит от обстоятельств, но в целом, если я проектирую базу данных с таблицами менее 100 000 строк, я буду сильно склоняться к проектированию для гибкости, простоты написания стабильных запросов и в соответствии с принципами, которые может ожидать любой другой дизайнер. Более миллиона строк, то я проектирую для производительности. Между 100 000 и миллионами это вопрос суждения.

1 голос
/ 22 февраля 2009

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

Как уже упоминалось, поскольку таблица физически отсортирована в соответствии с ключом кластеризованного индекса, это ситуация Highlander: может быть только одна!

Кластерные индексы в основном полезны для ситуаций, таких как:

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

Я подумал, что они были особенно бесполезны для ситуаций, когда у вас есть системы транзакций большого объема с очень частыми вставками, когда последовательный ключ является кластеризованным столбцом. Вы получите набор процессов, которые все пытаются вставить в одно и то же физическое местоположение («горячая точка»). Оказывается, как было прокомментировано здесь перед этим редактированием, я, к сожалению, устарел и показываю свой возраст. См. этот пост на тему Кимберли Триппа , в котором все сказано гораздо лучше.

Последовательные числовые столбцы «ID», как правило, не являются хорошими столбцами-кандидатами. Имена могут быть хорошими, даты также - если тщательно обдумать.

1 голос
/ 22 февраля 2009

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

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

1 голос
/ 22 февраля 2009

Просто по привычке я всегда создаю поле идентификатора «ID», как у вас в качестве ПК. Это делает вещи последовательными. Если все «главные» таблицы имеют поле с именем «ID», которое является INT Identity, то всегда очевидно, что такое PK. Кроме того, если мне нужно создать мостовую сущность, я буду хранить два (или более) столбца типа INT вместо типа nvarchar (). Поэтому в вашем примере я бы оставил идентификатор в качестве PK и создал бы уникальный индекс для UniqueName.

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