Различия между INDEX, PRIMARY, UNIQUE, FULLTEXT в MySQL?

610

Каковы различия между PRIMARY, UNIQUE, INDEX и FULLTEXT при создании таблиц MySQL?

Как бы я их использовал?

Брайан Томпсетт - 汤 莱恩
источник
3
Также для всех, кто интересуется SPATIAL: stackoverflow.com/questions/2256364/…
Лев
Сравнение первичного и вторичного индексов в Python см. В этом сообщении stackoverflow.com/questions/59918440/secondary-index-in-python
Athanassios

Ответы:

674

Различия

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

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

    Ваша система баз данных может разрешить применение индекса UNIQUE к столбцам, которые допускают значения NULL, и в этом случае две строки могут быть идентичными, если они обе содержат значение NULL (обоснование здесь заключается в том, что NULL считается не равным себе). Однако в зависимости от вашего приложения это может оказаться нежелательным: если вы хотите предотвратить это, вам следует запретить значения NULL в соответствующих столбцах.

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

    Некоторые системы баз данных (например, InnoDB MySQL) будут хранить записи таблицы на диске в том порядке, в котором они появляются в индексе PRIMARY.

  • Индексы FULLTEXT отличаются от всего вышеперечисленного, и их поведение значительно отличается в разных системах баз данных. Индексы FULLTEXT полезны только для полнотекстового поиска, выполняемого с помощью предложения MATCH () / AGAINST (), в отличие от трех вышеупомянутых, которые обычно реализуются внутренне с использованием b-деревьев (позволяющих выбирать, сортировать или диапазоны, начиная с самого левого столбца) или хеш-таблицы (с возможностью выбора, начиная с самого левого столбца).

    Если другие типы индексов являются универсальными, индекс FULLTEXT является специализированным, поскольку он служит узкой цели: он используется только для функции «полнотекстового поиска».

сходства

  • Все эти индексы могут содержать более одного столбца.

  • За исключением FULLTEXT, порядок столбцов является существенным: для индекса, который будет полезен в запросе, запрос должен использовать столбцы из индекса, начиная слева - он не может использовать только вторую, третью или четвертую часть index, если только он не использует предыдущие столбцы в индексе для соответствия статическим значениям. (Чтобы индекс FULLTEXT был полезен для запроса, запрос должен использовать все столбцы индекса.)

thomasrutter
источник
2
Означает ли это, что индекс FULLTEXT практически бесполезен и занимает много места, если вы не используете MATCH () / AGAINST () в своих запросах?
user1397417
5
Да. Он также используется только для баз данных MyISAM на MySQL, но не для InnoDB. Другие серверы баз данных могут иметь эквивалентные функции, которые могут работать по-другому.
Томасруттер
msgstr "это не должно использоваться ни в каких столбцах, которые допускают значения NULL" -> Это должно быть "нельзя использовать". Первичные ключи обязательно NOT NULL. MySQL сообщит, show columnsчто не-NULL уникальный ключ является первичным ключом, если не определены другие первичные ключи.
Гордон Линофф
1
Обоснование здесь состоит в том, что NULL считается не равным самому себе. Lol, я не забуду этого
Hos Mercury
2
@thomasrutter MySQL, поддерживающий FULLTEXT в InnoDB с версии 5.6
Марек Скиба,
151

Все это виды показателей.

primary: должен быть уникальным, это индекс, (скорее всего) физический индекс, может быть только один для таблицы.

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

index: если он не является основным или уникальным, он не ограничивает значения, вставленные в таблицу, но позволяет более эффективно их искать.

fulltext: более специализированная форма индексации, позволяющая осуществлять полнотекстовый поиск. Думайте об этом как о (по сути) создании «индекса» для каждого «слова» в указанном столбце.

tpdi
источник
32
Первичные могут быть составными, то есть многоключевыми, в MySQL (и многих других БД). Они просто особый индекс. Уникальный не является на самом деле индексом, это ограничение (которое требует, чтобы индекс применялся в разумные сроки, поэтому его создаем).
MBCook
19

Я чувствую, что это было хорошо покрыто, возможно, за исключением следующего:

  • Простой KEY/ INDEX(или иначе называемый SECONDARY INDEX) действительно увеличивает производительность, если селективность достаточна. В связи с этим обычная рекомендация состоит в том, что если количество записей в наборе результатов, к которым применяется индекс, превышает 20% от общего количества записей родительской таблицы, то индекс будет неэффективным. На практике каждая архитектура будет отличаться, но идея по-прежнему верна.

  • Вторичные индексы (и это очень специфично для mysql) не должны рассматриваться как полностью отдельные и отличные объекты от первичного ключа. Фактически, оба должны использоваться совместно и, как только эта информация станет известна, предоставить дополнительный инструмент для администратора баз данных mysql: в Mysql индексы встраивают первичный ключ. Это приводит к значительному повышению производительности, особенно при умном построении неявных индексов покрытия, таких как описанные там.

  • Если вы чувствуете, что ваши данные должны быть UNIQUE, используйте уникальный индекс. Вы можете подумать, что это необязательно (например, работа с ним на уровне приложения) и что подойдет обычный индекс, но на самом деле он дает гарантию для Mysql, что каждая строка уникальна, что, кстати, обеспечивает выигрыш в производительности.

  • Вы можете использовать FULLTEXT(или иначе называть SEARCH INDEX) с Innodb (в MySQL 5.6.4 и выше) и Myisam Engines

  • Вы можете использовать только FULLTEXTна CHAR, VARCHARи TEXTтипы столбцов
  • FULLTEXTИндекс включает в себя гораздо больше, чем просто создание индекса. Создана куча системных таблиц, совершенно отдельная система кэширования и применены некоторые конкретные правила и оптимизации. См. Http://dev.mysql.com/doc/refman/5.7/en/fulltext-restrictions.html и http://dev.mysql.com/doc/refman/5.7/en/innodb-fulltext-index.html.
Sebas
источник