Page 1 sur 1

clé sur plusieurs champs

Posté : 14 juin 2005, 11:10
par Justone
Bonjour,

j'ai une table ou il y a quatre champs

je voudrais mettre une clé sur 3 champs a la fois

est ce possible? comment faire?

Merci pour votre aide

Posté : 14 juin 2005, 11:18
par Ripat
Avec une requête comme celle-ci:

Code : Tout sélectionner

ALTER TABLE nom_table ADD INDEX nom_index (col_1, col_2, col_3)

Posté : 14 juin 2005, 12:09
par robined
est tu sur ripat que c'est index qu'il mettre, moi j'obterais pour PRIMARY

Posté : 14 juin 2005, 12:11
par zeus
La PRIMARY KEY sert à éviter les doublons alors que l'INDEX sert à améliorer les recherches.

Si il veut optimiser ses recherches en sachant qu'il recherche sur ces 3 colonnes en majorité, l'INDEX sur 3 champs est plus adapté que la PRIMARY KEY sur 3 champs

Posté : 14 juin 2005, 13:43
par waf_wafe
Et l'index évite les doublons ??

Posté : 14 juin 2005, 13:59
par zeus
Non

Les 2 remplissent des fonctions différentes :

- la clé primaire permet de retrouver de manière unique un enregistrement dans une table et peut donc être utiliser comme référence dans une autre table
- l'index permet de "préparer" une recherche en faisant un tri grossier à chque modification de la base de données afin que lorsqu'on fait une recherche, on augmente les performances du serveur SQL

* L'un ne dépend pas forcément de l'autre
* On peut en avoir aucun, de l'un, de l'autre ou des deux
* Ils sont indépendant

On peut même créer un index sur une clé primaire !!! C'est idiot puisqu'une clé primaire ne doit pas contenir de doublons mais c'est possible

Posté : 14 juin 2005, 14:00
par Invité
et c'est quoi la différence entre unique et primary??

merci

Posté : 14 juin 2005, 14:05
par zeus
on ne peut pas parler de différence entre les 2 vue que c'est pas la même chose

- un champ PRIMARY KEY doit être UNIQUE, c'et à dire que ce champs permet de retrouver une ligne de manière unique dans un jeu d'enregistrement (il ne doit pas y avoir de doublons)
- un champ unique n'est pas forcément une PRIMARY KEY, c'est juste un champs qui ne doit pas contenir 2 fois la même valeur

Par exemple :
sur PHPFrance, dans la table membre, la clé primaire est un identifiant numérique mais le champ "pseudo" est un champ unique car il ne doit pas y avoir 2 fois le même pseudo dans la base de données

Posté : 14 juin 2005, 14:16
par waf_wafe
Donc il faut bien mettre un "primary" dans le code puisque lui il veut mettre 3 champs en clé primaire :wink:
Si il met index il pourrait se retrouver avec des doublons sur ces champs là justement !

Posté : 14 juin 2005, 14:21
par Ripat
La PRIMARY KEY sert à éviter les doublons alors que l'INDEX sert à améliorer les recherches.

Si il veut optimiser ses recherches en sachant qu'il recherche sur ces 3 colonnes en majorité, l'INDEX sur 3 champs est plus adapté que la PRIMARY KEY sur 3 champs
C'est une bonne définition.

Pour ma part j'ai longtemps été perturbé par la différence/ressemblance entre KEY et INDEX. Voici ma conclusion:

Quatre types d'index:
  1. Index unique
  2. Index non unique
  3. Index fulltext (pour recherche sur contenu)
  4. clé primaire
qui se créent différemment:
  1. ALTER TABLE table ADD UNIQUE nom_index (colonnes)
  2. ALTER TABLE table ADD INDEX nom_index (colonnes)
  3. ALTER TABLE table ADD FULLTEXT nom_index (colonnes)
  4. ALTER TABLE table ADD PRIMARY KEY nom_index (colonnes)
La PRIMARY KEY n'est rien d'autre qu'un index unique à la différence que :
  • une PRIMARY KEY ne peut pas contenir de valeurs nulles
  • Il ne peut y avoir qu'une seule PRIMARY KEY par table mais on peut mettre plusieurs index UNIQUE.
  • on ne peut pas utiliser la syntaxe CREATE INDEX avec les PRIMARY KEY (détail car CREATE INDEX est "mappée" vers ALTER TABLE...ADD qui, elle, accepte de créer des PRIMARY KEY. Je n'ai jamais bien compris cette limitation de syntaxe)
En passant, et pour revenir à la question de départ, l'utilisation des index est une arme à double tranchant. Comme l'a souligné Zeus, ils accélèrent les SELECT mais ils ralentissent les INSERT (les index sont automatiquement mis à jour lors d'une insertion).

Si on a des insert massifs à faire, on peut contourner le problème en supprimant les index (DROP INDEX) avant l'insertion puis de les recréer après. Ou mieux, grouper les insert à faire dans un fichier texte puis faire un LOAD DATA INFILE en lieu et place des INSERT. C'est *beaucoup* plus rapide.

Le choix de la composition des index n'est pas un exercice facile mais il vaut toujours mieux indexer sur une partie de colonne plutôt que sur la largeur totale de celle-ci. Si les x premiers caractères d'une colonne de type CHAR suffisent à distinguer suffisamment les lignes, l'index ne devrait porter que sur ces x premiers caractères. Comme par exemple

Code : Tout sélectionner

ALTER TABLE table ADD INDEX nom_index (colonnes(3))
On indexe sur les 3 premiers octets de la colonne.

L'index sera moins volumineux sur disque mais sutout, occupera moins de place en mémoire dans le key_buffer, le cache utilisé pour stocker les index. MySQL pourra ainsi stocker de plus gros morceaux de cet index en cache et la requête sera accélérée. L'espace disque ne coûte plus rien maintenant mais la mémoire....

L'utilisation appropriée des index est un sujet délicat (mais passionnant) et trouver le bon équilibre, un exercice difficile. La solution:
  1. essayer
  2. tester (chrono)
  3. planter
  4. goto 1
:wink:

Posté : 14 juin 2005, 14:31
par waf_wafe
Merci pour ces explications Ripat ! J'ai beaucoup appris =D>

Posté : 14 juin 2005, 14:41
par zeus
Si on a des insert massifs à faire, on peut contourner le problème en supprimant les index (DROP INDEX) avant l'insertion puis de les recréer après. Ou mieux, grouper les insert à faire dans un fichier texte puis faire un LOAD DATA INFILE en lieu et place des INSERT. C'est *beaucoup* plus rapide.
Question que je me pose comme ça, au passage, en lisant ton texte :
qu'est-ce qui est le plus rapide :
- ajouter des INSERT sans enlever les index
- enlever les index, ajouter les lignes et recréer les index

sachant que dans une table qui contient déjà des lignes, la création des index doit prendre un temps non négligeable, non ?

Posté : 14 juin 2005, 15:11
par ouckileou
un élément de réponse vu sur la doc MySQL :
Pour les enregistrements les plus grands, il sera plus rapide de charger les donnés dans une table qui n'a pas d'index FULLTEXT, et ensuite de créer l'index avec ALTER TABLE (ou CREATE INDEX). L'enregistrement de données dans une table qui a déjà des index FULLTEXT sera plus lent.
http://dev.mysql.com/doc/mysql/fr/fulltext-search.html

Posté : 14 juin 2005, 15:13
par zeus
Merci :pouce: