Відмінності між 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 посилається на індекс, де всі рядки індексу повинні бути унікальними. Тобто один і той же рядок може не мати однакових значень не-NULL для всіх стовпців цього індексу, як і інший рядок. Окрім того, що вони використовуються для швидкого досягнення певних діапазонів записів, UNIQUE індекси можуть використовуватися для забезпечення обмежень щодо даних, оскільки система бази даних не дозволяє порушувати правило про окремі значення під час вставки або оновлення даних.

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

  • PRIMARY діє точно як індекс UNIQUE, за винятком того, що він завжди називається "PRIMARY", і на столі може бути лише один (і завжди повинен бути один; хоча деякі системи баз даних не застосовують цього). PRIMARY index призначений як основний засіб для унікального визначення будь-якого рядка таблиці, тому на відміну від UNIQUE він не повинен використовуватися в жодних стовпцях, які дозволяють значення NULL. Ваш первинний індекс повинен містити найменшу кількість стовпців, достатню для однозначної ідентифікації рядка. Часто це лише один стовпець, який містить унікальне автоматичне збільшення номера, але якщо є щось інше, що може однозначно ідентифікувати рядок, наприклад, "код країни" у списку країн, ви можете використовувати це замість цього.

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

  • Індекси FULLTEXT відрізняються від усіх вищезазначених, і їх поведінка суттєво відрізняється між системами баз даних. Індекси FULLTEXT корисні лише для повного пошуку тексту, виконаного за допомогою пункту MATCH () / ПРОТИ (на відміну від вищезгаданих трьох), які зазвичай реалізуються внутрішньо за допомогою b-дерев (дозволяючи вибирати, сортувати або діапазони, починаючи з самого лівого стовпця) або хеш-таблиці (що дозволяє вибирати починаючи з самої лівої колонки).

    Якщо інші типи індексів мають загальне призначення, індекс FULLTEXT є спеціалізованим, оскільки він служить вузькому призначенню: він використовується лише для функції "повнотекстового пошуку".

Подібність

  • Усі ці індекси можуть містити в них більше одного стовпця.

  • За винятком FULLTEXT, порядок стовпців є вагомим: щоб індекс був корисним у запиті, запит повинен використовувати стовпці з індексу, починаючи зліва - він не може використовувати лише другу, третю чи четверту частину індекс, якщо він також не використовує попередні стовпці в індексі для відповідності статичним значенням. (Щоб індекс FULLTEXT був корисним для запиту, запит повинен використовувати всі стовпці індексу.)


2
це означає, що індекс FULLTEXT по суті є марним і займає талію місця, якщо ви не використовуєте MATCH () / ПРОТИ () у своїх запитах?
user1397417

5
Так. Він також використовується лише для баз даних MyISAM на MySQL, а не InnoDB. Інші сервери баз даних можуть мати еквівалентні функції, які можуть працювати по-різному.
thomasrutter

"його не слід використовувати в жодному стовпчику, в якому допускаються значення NULL" -> Це має бути "не можна використовувати". Первинні ключі обов’язково NOT NULL. MySQL повідомить, show columnsщо унікальний ключ NULL є первинним ключем, якщо немає інших первинних ключів.
Гордон Лінофф

1
Обґрунтування тут полягає в тому, що NULL вважається рівним собі. Lol, я цього не забуду
Hos Mercury

2
@thomasrutter MySQL, що підтримує FULLTEXT в InnoDB, версія 5.6
Марек Скіба,

151

Все це - види індексів.

первинний: повинен бути унікальним, є індексом, є (ймовірно) фізичним індексом, може бути лише один на таблицю.

унікальний: як мовиться. У вас не може бути більше одного ряду з кортежем цього значення. Зауважте, що оскільки унікальний ключ може мати більше, ніж один стовпець, це не обов'язково означає, що кожен окремий стовпець в індексі є унікальним, але кожна комбінація значень у цих стовпцях є унікальною.

індекс: якщо він не є основним або унікальним, він не обмежує значення, вставлені в таблицю, але дозволяє переглядати їх більш ефективно.

fulltext: більш спеціалізована форма індексації, яка дозволяє здійснювати повний пошук тексту. Подумайте про це як (по суті) створення "індексу" для кожного "слова" у вказаному стовпці.


32
Primarys можуть бути складовими, тобто багатокладовими, у MySQL (та багатьох інших БД). Вони просто спеціальний індекс. Унікальний насправді не є індексом, це обмеженням (який вимагає виконання індексу за розумну кількість часу, таким чином створює його).
MBCook

19

Я відчуваю, що це було добре висвітлено, можливо, за винятком наступного:

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

  • Вторинні індекси (і це дуже характерно для mysql) не слід розглядати як повністю відокремлені та різні об'єкти від первинного ключа. Насправді обидва повинні використовуватися спільно і, коли ця інформація буде відома, надають додатковий інструмент для DQL mysql: в Mysql індекси вставляють первинний ключ. Це призводить до значних поліпшень продуктивності, зокрема, при вмілій побудові неявних покриваючих індексів, таких як описані там

  • Якщо вам здається, що ваші дані мають бути UNIQUE, використовуйте унікальний індекс. Ви можете подумати, що це необов’язково (наприклад, це опрацювати на рівні програми) і що нормальний індекс зробить, але він фактично являє собою гарантію для Mysql, що кожен рядок є унікальним, що, до речі, забезпечує перевагу від продуктивності.

  • Ви можете користуватися FULLTEXT(або називатися іншим чином SEARCH INDEX) лише з Innodb (In 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.