Différences entre INDEX, PRIMARY, UNIQUE, FULLTEXT dans MySQL?

610

Quelles sont les différences entre PRIMARY, UNIQUE, INDEX et FULLTEXT lors de la création de tables MySQL?

Comment pourrais-je les utiliser?

Brian Tompsett - 汤 莱恩
la source
3
Aussi pour toute personne curieuse de SPATIAL: stackoverflow.com/questions/2256364/…
Leo
Pour une comparaison d'un index primaire avec un index secondaire en Python, consultez cet article stackoverflow.com/questions/59918440/secondary-index-in-python
Athanassios

Réponses:

674

Différences

  • KEY ou INDEX fait référence à un index non unique normal. Des valeurs non distinctes pour l'index sont autorisées, donc l'index peut contenir des lignes avec des valeurs identiques dans toutes les colonnes de l'index. Ces index n'imposent aucune restriction à vos données, ils ne sont donc utilisés que pour l'accès - pour atteindre rapidement certaines plages d'enregistrements sans analyser tous les enregistrements.

  • UNIQUE fait référence à un index où toutes les lignes de l'index doivent être uniques. En d'autres termes, la même ligne peut ne pas avoir de valeurs non NULL identiques pour toutes les colonnes de cet index en tant qu'une autre ligne. En plus d'être utilisés pour atteindre rapidement certaines plages d'enregistrement, les index UNIQUE peuvent être utilisés pour appliquer des restrictions sur les données, car le système de base de données ne permet pas de rompre la règle des valeurs distinctes lors de l'insertion ou de la mise à jour des données.

    Votre système de base de données peut permettre qu'un index UNIQUE soit appliqué aux colonnes qui autorisent les valeurs NULL, auquel cas deux lignes peuvent être identiques si elles contiennent toutes les deux une valeur NULL (la raison ici est que NULL n'est pas considéré comme égal à lui-même). En fonction de votre application, cependant, vous pouvez trouver cela indésirable: si vous souhaitez éviter cela, vous devez interdire les valeurs NULL dans les colonnes appropriées.

  • PRIMARY agit exactement comme un index UNIQUE, sauf qu'il est toujours nommé 'PRIMARY', et qu'il ne peut y en avoir qu'un sur une table (et il devrait toujours y en avoir un; bien que certains systèmes de base de données ne l'imposent pas). Un index PRIMARY est conçu comme un moyen principal d'identifier de manière unique n'importe quelle ligne de la table, donc contrairement à UNIQUE, il ne doit pas être utilisé sur les colonnes qui autorisent les valeurs NULL. Votre index PRIMARY doit se trouver sur le plus petit nombre de colonnes suffisant pour identifier de manière unique une ligne. Souvent, il s'agit d'une seule colonne contenant un numéro incrémenté automatiquement, mais s'il existe autre chose qui peut identifier de manière unique une ligne, comme "countrycode" dans une liste de pays, vous pouvez l'utiliser à la place.

    Certains systèmes de base de données (comme InnoDB de MySQL) stockent les enregistrements d'une table sur disque dans l'ordre dans lequel ils apparaissent dans l'index PRIMARY.

  • Les index FULLTEXT sont différents de tout ce qui précède et leur comportement diffère considérablement entre les systèmes de base de données. Les index FULLTEXT ne sont utiles que pour les recherches en texte intégral effectuées avec la clause MATCH () / AGAINST (), contrairement aux trois précédentes - qui sont généralement implémentées en interne à l'aide de b-arbres (permettant la sélection, le tri ou les plages à partir de la colonne la plus à gauche) ou tables de hachage (permettant une sélection à partir de la colonne la plus à gauche).

    Lorsque les autres types d'index sont à usage général, un index FULLTEXT est spécialisé, en ce sens qu'il sert un objectif étroit: il n'est utilisé que pour une fonction de "recherche en texte intégral".

Similitudes

  • Tous ces index peuvent contenir plusieurs colonnes.

  • À l'exception de FULLTEXT, l'ordre des colonnes est significatif: pour que l'index soit utile dans une requête, la requête doit utiliser les colonnes de l'index en commençant par la gauche - elle ne peut pas utiliser uniquement la deuxième, la troisième ou la quatrième partie d'un index, sauf s'il utilise également les colonnes précédentes de l'index pour faire correspondre les valeurs statiques. (Pour qu'un index FULLTEXT soit utile à une requête, la requête doit utiliser toutes les colonnes de l'index.)

thomasrutter
la source
2
cela signifie-t-il qu'un index FULLTEXT est essentiellement inutile et une taille d'espace si vous n'utilisez pas MATCH () / AGAINST () dans vos requêtes?
user1397417
5
Oui. Il n'est également utilisé que pour les bases de données MyISAM sur MySQL, pas InnoDB. D'autres serveurs de bases de données peuvent avoir des fonctionnalités équivalentes qui peuvent fonctionner différemment.
thomasrutter
"il ne doit pas être utilisé sur les colonnes qui autorisent les valeurs NULL" -> Il doit être "ne peut pas être utilisé". Les clés primaires le sont nécessairement NOT NULL. MySQL signale show columnsqu'une clé unique non NULL est une clé primaire, si aucune autre clé primaire n'est définie.
Gordon Linoff
1
La raison ici est que NULL n'est pas considéré comme égal à lui-même. Lol je ne l'oublierai pas
Hos Mercury
2
@thomasrutter MySQL supportant FULLTEXT dans InnoDB à partir de la version 5.6
Marek Skiba
151

Ce sont tous des types d'indices.

primaire: doit être unique, est un index, est (probablement) l'index physique, ne peut être qu'un seul par table.

unique: comme il est dit. Vous ne pouvez pas avoir plus d'une ligne avec un tuple de cette valeur. Notez qu'une clé unique pouvant dépasser plusieurs colonnes, cela ne signifie pas nécessairement que chaque colonne individuelle de l'index est unique, mais que chaque combinaison de valeurs sur ces colonnes est unique.

index: s'il n'est pas principal ou unique, il ne contraint pas les valeurs insérées dans la table, mais il permet de les rechercher plus efficacement.

fulltext: une forme d'indexation plus spécialisée qui permet une recherche plein texte. Considérez-le comme créant (essentiellement) un "index" pour chaque "mot" dans la colonne spécifiée.

tpdi
la source
32
Les primaires peuvent être composites, c'est-à-dire multi-clés, dans MySQL (et beaucoup d'autres bases de données). Ce n'est qu'un index spécial. Unique n'est pas vraiment un index, c'est une contrainte (qui nécessite un index à appliquer dans des délais raisonnables, donc en crée un).
MBCook
19

Je pense que cela a été bien couvert, peut-être à l'exception des éléments suivants:

  • Simple KEY/ INDEX(ou autrement appelé SECONDARY INDEX) augmente les performances si la sélectivité est suffisante. À cet égard, la recommandation habituelle est que si le nombre d'enregistrements dans l'ensemble de résultats sur lequel un index est appliqué dépasse 20% du nombre total d'enregistrements de la table parent, alors l'indice sera inefficace. Dans la pratique, chaque architecture sera différente, mais l'idée est toujours correcte.

  • Les index secondaires (et c'est très spécifique à mysql) ne doivent pas être considérés comme des objets complètement séparés et différents de la clé primaire. En fait, les deux devraient être utilisés conjointement et, une fois ces informations connues, fournir un outil supplémentaire au DBA mysql: dans Mysql, les index incorporent la clé primaire. Cela conduit à des améliorations significatives des performances, en particulier lors de la construction intelligente d'index de couverture implicites tels que décrits ici.

  • Si vous pensez que vos données devraient l'être UNIQUE, utilisez un index unique. Vous pouvez penser que c'est facultatif (par exemple, le travailler au niveau de l'application) et qu'un index normal fera l'affaire, mais cela représente en fait une garantie pour Mysql que chaque ligne est unique, ce qui fournit par ailleurs un avantage en termes de performances.

  • Vous ne pouvez utiliser FULLTEXT(ou autrement appelé SEARCH INDEX) qu'avec Innodb (dans MySQL 5.6.4 et supérieur) et les moteurs Myisam

  • Vous ne pouvez utiliser FULLTEXTsur CHAR, VARCHARet les TEXTtypes de colonnes
  • FULLTEXTindex implique beaucoup plus que la simple création d'un index. Il y a un tas de tables système créées, un système de mise en cache complètement séparé et certaines règles et optimisations spécifiques appliquées. Voir http://dev.mysql.com/doc/refman/5.7/en/fulltext-restrictions.html et http://dev.mysql.com/doc/refman/5.7/en/innodb-fulltext-index.html
Sebas
la source