47 votes

Pourquoi utiliser une clé primaire auto-incrémentée alors qu'il existe d'autres champs uniques ?

Je suis un cours intitulé "systèmes de bases de données" et pour notre projet de classe, je dois concevoir un site web.

Voici un exemple de tableau que j'ai créé :

CREATE TABLE users
(
  uid INT NOT NULL AUTO_INCREMENT,
  username VARCHAR(60),
  passhash VARCHAR(255),
  email VARCHAR(60),
  rdate DATE,
  PRIMARY KEY(uid)
);

Le professeur m'a dit que "uid" (user id) était complètement inutile et superflu et que j'aurais dû utiliser le nom d'utilisateur comme clé primaire, puisque deux utilisateurs ne peuvent pas avoir le même nom d'utilisateur.

Je lui ai dit qu'il était pratique pour moi d'utiliser un identifiant d'utilisateur parce que lorsque j'appelle quelque chose comme example.com/viewuser?id=5 Je vérifie simplement le paramètre avec : is_numeric($_GET['id']) ... inutile de dire qu'il n'était pas convaincu.

Comme j'ai vu user_id et d'autres attributs similaires (thread_id, comment_id, entre autres) sur de nombreux tutoriels et en regardant le schéma de base de données de logiciels populaires (par exemple vbulletin), il doit y avoir beaucoup d'autres raisons (plus fortes).

Ma question est donc la suivante : comment justifier le besoin d'un identifiant non nul à incrémentation automatique comme clé primaire par rapport à l'utilisation d'un autre attribut comme le nom d'utilisateur ?

82voto

meagar Points 85475

Incrémentation automatique des clés primaires sont utiles pour plusieurs raisons:

  • Ils permettent de dupliquer les noms d'utilisateur que sur un Débordement de Pile
  • Ils permettent à l'utilisateur (nom ou adresse e-mail, si c'est utilisé pour la connexion) être modifié (facilement)
  • Sélectionne, les jointures et les inserts sont plus rapides que varchar clés primaires comme beaucoup plus rapide de maintenir un index numérique
  • Comme vous l'avez mentionné, la validation devient très simple: if ((int)$id > 0) { ... }
  • L'assainissement de l'entrée est trivial: $id = (int)$_GET['id']
  • Il y a beaucoup moins de frais généraux comme les clés étrangères de ne pas avoir à dupliquer potentiellement important de la chaîne de valeurs

Je dirais d'essayer d'utiliser n'importe quel morceau de la chaîne de l'information comme un identificateur unique pour un enregistrement est une mauvaise idée quand un auto-incrémentation touche numérique est si facilement disponible.

Les systèmes avec des noms d'utilisateur unique sont très bien pour un très petit nombre d'utilisateurs, mais l'Internet a rendu fondamentalement brisé. Quand vous considérez le nombre de personnes nommé "john" qui pourraient avoir à interagir avec un site web, il est ridicule d'exiger de chacun d'entre eux d'utiliser un unique nom d'affichage. Elle conduit à l'affreux système, nous voyons si souvent avec des chiffres aléatoires et des lettres, à la décoration d'un nom d'utilisateur.

Cependant, même dans un système où vous avez appliqué les noms d'utilisateur unique, c'est toujours un mauvais choix pour une clé primaire. Imaginez un utilisateur avec 500 postes: La clé étrangère dans l' posts tableau va contenir le nom d'utilisateur, dupliqué 500 fois. La surcharge est prohibitif, même avant d'envisager la possibilité que quelqu'un pourrait éventuellement besoin de changer son nom d'utilisateur.

16voto

Matt Caldwell Points 818

Si le nom d'utilisateur est la clé primaire et qu'un utilisateur change son nom d'utilisateur, vous devrez mettre à jour toutes les tables qui ont des références de clé étrangère à la table des utilisateurs.

11voto

onedaywhen Points 24594

Si vous avez démontré à votre professeur que l'attribution d'un nombre entier arbitraire unique à chaque utilisateur est utile à votre application, il aurait bien sûr tort de dire que c'est "complètement inutile et superflu".

Cependant, vous n'avez peut-être pas compris ce qu'il voulait dire. S'il vous a dit que l'exigence est que "deux utilisateurs ne peuvent pas avoir le même nom d'utilisateur", alors vous n'avez pas satisfait à cette exigence.

Merci sincèrement d'avoir publié votre DDL SQL, c'est très utile mais la plupart des gens ne se donnent pas la peine de le faire.

En utilisant votre tableau, je peux le faire :

INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);
INSERT INTO users (username) VALUES (NULL);

Ce qui donne ceci :

SELECT uid, username, passhash, email, rdate 
FROM users;

uid   username   passhash   email   rdate
1     <NULL>     <NULL>     <NULL>  <NULL>
2     <NULL>     <NULL>     <NULL>  <NULL>
3     <NULL>     <NULL>     <NULL>  <NULL>
4     <NULL>     <NULL>     <NULL>  <NULL>

Je pense que c'est ce que votre professeur essayait de faire : sans appliquer la clé naturelle sur les username il n'y a pas vraiment d'intégrité des données.

Si j'étais le professeur, je vous recommanderais également de supprimer les colonnes nullables de votre conception.

7voto

RC. Points 15804

C'est ce qu'on appelle généralement un clé de substitution et il présente de nombreux avantages. L'un d'entre eux est d'isoler les relations de la base de données des données de l'application. Pour plus de détails et les inconvénients correspondants, voir le lien wiki ci-dessus.

4voto

OMG Ponies Points 144785

Parce que quelqu'un pourrait vouloir changer son nom d'utilisateur (ou n'importe quel nom d'ailleurs).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X