Si je crée une unique
contrainte sur un champ, dois-je également créer un index sur ce champ afin d'obtenir un temps d'insertion évolutif? Ou est-ce fait pour moi (même si l'index qu'il utilise n'est pas accessible au public?)
Plus précisément, je travaille avec Apache Derby pour le prototypage, bien que je vais probablement le déplacer vers MySQL dans un avenir proche. J'espère également qu'il pourrait y avoir quelque chose dans la norme SQL qui en dit long.
Je n'aurai jamais besoin de chercher par ce champ, donc je préfère ne pas faire d'index inutile. Mais je préfère avoir un index inutile que d'avoir un O(n)
temps d'insertion.
mysql
constraint
derby
unique-constraint
corsiKa
la source
la source
Réponses:
--ÉDITER--
Ma réponse originale (ci-dessous) ne vous est probablement pas utile du tout car elle ne répond pas à la question des
unique
contraintes. Comme d'autres l'ont dit, ces contraintes sont généralement implémentées avec un index unique implicite. Dans certains cas, cela peut ne pas être vrai (par exempledisable novalidate
pour Oracle).La question pourrait être: est-il possible d'imposer l'unicité sans index? De manière générale, la réponse est non, mais dans certains cas, un index clusterisé signifie que l'index et la table sont le même objet.
--END EDIT--
Vous avez dit "Je préfère avoir un index inutile que d'avoir un temps d'insertion O (n).", Mais en général les bases de données n'ont pas de temps d'insertion O (n). Il y a deux cas à considérer:
Une table normale avec ou sans index:
Les nouvelles lignes sont vidées en haut du tas. Le SGBDR ne regarde probablement que 1 bloc, donc pas seulement O (1) mais très petit O (1).
Si la table a des index, un pointeur vers la ligne sera ajouté à chacun. Ce sera généralement une opération O (log (n)).
Une table avec une sorte de clustering en cours, par exemple une table organisée par index ou un cluster pour Oracle, ou un index cluster pour SQL Server et autres:
De nouvelles lignes sont insérées dans un bloc particulier, ce qui peut entraîner une division ou un débordement du bloc, mais quoi qu'il arrive, il s'agit toujours de O (log (n)) ou mieux , provoqué par l'arborescence b ou une structure similaire utilisée pour trouver le bloc.
la source
O(n)
comme vous devez vérifier la table entière. Voilà ce que j'essaie d'éviter.O(lg n)
temps d'insertion. Ce n'est pas un problème. Ma question est si le système, sachant que vous avez besoin de cet index pour obtenir un temps d'insertion décent, créerait un index pour moi.CLÉ PRIMAIRE> = UNIQUE> = INDEX == CLÉ
Les données InnoDB sont commandées par le PK. MyISAM PK agit de la même manière qu'UNIQUE.
INSERT doit ajouter une "ligne" à chaque index (de n'importe quel type) que vous avez. Cela prend du temps. (Généralement, le temps n'est pas suffisant pour être important.) Les index sont tous stockés au format BTree. Les blocs MyISAM BTree mesurent 1 Ko; InnoDB utilise 16 Ko.
L'insertion dans InnoDB met à jour le PK et les données simultanément.
L'insertion dans MyISAM "ajoute" généralement les données au .MYD. Séparément, il ajoute une ligne au PK (le cas échéant).
INSERT doit d'abord vérifier qu'il n'y a pas de clé en double pour une clé PRIMARY ou UNIQUE. Cela se fait en utilisant l'index. Et, par conséquent, pourquoi les CONTRAINTES DE CLÉS UNIQUES et ÉTRANGÈRES construisent vraiment des index. C'est O (logN), mais généralement CPU, pas E / S, car si la mise en cache est efficace.
la source
UNIQUE
contrainte créera un index sans que l'utilisateur en spécifie un à faire?Pour répondre à la question en gras: Oui, rendre un champ unique l'indexe comme la clé primaire de s. En fait, j'avais discuté de cela dans une autre question concernant les clés primaires ayant leur propre nom pour le distinguer des autres clés uniques (candidates) .
En ce qui concerne les contraintes, des index sont créés pour vous afin que le paradigme des contraintes soit configuré. Vous devriez pouvoir supprimer les index en double, même les clés UNIQUE, tant que la contrainte que vous avez créée ne fait pas référence à d'autres clés UNIQUE que vous avez personnellement créées en dehors du paradigme de contrainte.
Vous n'aurez peut-être jamais à rechercher ce champ, mais MySQL devra certainement le rechercher pour déterminer la validité des clés et déterminer comment effectuer les opérations ON DELETE CASCADE et ON UPDATE CASCADE.
L'index UNIQUE garantit simplement l'unicité des tuples (singletons, paires, triplets, ..., n-tuples, etc.) dans chaque ligne du tableau.
Il est à votre discrétion de supprimer ces index en double, à condition de ne pas briser le paradigme de contrainte que vous souhaitez avoir dans la table.
la source
O(n)
). S'il existe un index, la recherche sera beaucoup plus rapide (probablementO(lg n)
). Voilà mon problème. Je connais bien la mécanique d'intégrité référentielle, je ne me préoccupe (pour les besoins de cette question) que des performances.