# Les bases de données/Les clés primaires et secondaires

En théorie, l'ajout ou la modification d'un enregistrement dans la table ne doit pas pouvoir permettre la présence de doublons : chaque ligne n'est présente que dans un seul exemplaire dans la table. Dans la pratique, c'est une autre paire de manche : de nombreux SGBD acceptent d'avoir des lignes en plusieurs exemplaires dans une table sans problème. Mais nous allons passer cette contrainte sous le tapis pour le moment. Tout ce chapitre va répondre à cette simple question : comment le SGBD peut-il éviter les doublons ?

## Clés primaires et secondaires

Une solution simple consisterait à interdire l'ajout d'une ligne si on trouve une ligne identique dans la table. Mais cette solution pose un léger problème quand les valeurs NULL sont autorisées dans la table : on peut ajouter une ligne identique à une autre dans la table, si ce n'est qu'un champ autrefois à NULL a été modifié. Or, je rappelle que NULL peut signifier que la valeur de l'attribut n'était pas connue lors de la création de la ligne. Dans ce cas, rien ne nous garantit que les deux lignes correspondent à des clients/objets/personnes différents : il se peut très bien que la ligne ajoutée corresponde à la même personne ou au même objet, mais pour lequel on dispose de plus d'informations qu'avant.
Pour éviter ce genre de désagrément, et quelques autres que nous aborderons plus tard, on doit trouver un mécanisme pour identifier chaque donnée dans la table. Ce mécanisme consiste à choisir un ensemble de colonnes qui détermine un objet ou une personne unique dans la table : on sait que si ces ensembles d'attributs ont la même valeur dans deux lignes, alors les deux lignes correspondent à une même donnée. Cet ensemble de colonnes est ce qu'on appelle une clé. Les clés peuvent très bien contenir une seule colonne, mais c'est tout sauf systématique. Dit autrement, chaque personne ou objet donnera une seule et unique valeur pour chaque attribut de la clé : deux données différentes auront au moins un attribut dont la valeur sera différente. Par exemple, prenons le cas d'un établissement scolaire qui établit une liste d'élèves. Il arrivera certainement que deux élèves aient le même prénom ou le même nom de famille : dans ce cas, l'ensemble des colonnes nom et prénom ne peuvent pas servir de clé primaire.
Un même enregistrement peut très bien avoir plusieurs clés. Dans ce cas, on choisit le plus souvent une clé parmi toutes les autres, qui sera considérée comme une meilleure clé que les autres : c'est la clé primaire. Les autres clés seront alors appelées des clés secondaires ou clés alternatives. Petit détail : dans une clé primaire, les attributs ne peuvent pas être à NULL. Dit autrement, seules les colonnes qui n'appartiennent pas à la clé primaire peuvent contenir des NULL. Généralement, on peut préciser au SGBD quelles sont les colonnes qui peuvent servir de clé primaire : tout introduction d'un NULL dans un attribut de cette colonne se soldera par un message d'erreur et un refus d'insérer la ligne dans la table. Cette contrainte est ce qu'on appelle la contrainte de clé.

### Clés artificielles

Certaines clés ne sont même pas dérivées des informations présentes dans la ligne : on peut très bien ajouter un identifiant sans signification pour chaque ligne de la table. Par exemple, on peut attribuer arbitrairement un identifiant numérique pour chaque élève d'un établissement scolaire, à une personne dans la population (pensez au numéro de sécurité sociale), à tout livre publié (ISBN), ou à toute autre forme de donnée présente dans une table. Ces identifiants attribués arbitrairement sont appelés des clés artificielles, et sont généralement des nombres entiers.

## Dépendances fonctionnelles

Maintenant, on peut se demander comment déterminer quelles sont les colonnes destinées à former une clé (primaire ou non). Une solution simple est de faire marcher son cerveau et d'improviser intelligemment : cela peut fonctionner avec un peu d'expérience. Mais il existe des techniques plus mécaniques pour trouver les clés primaires. Celles-ci utilisent ce qu'on appelle des dépendances fonctionnelles. Deux attributs (ou groupes d'attributs) ont une dépendance fonctionnelle quand la connaissance de l'un permet de déterminer les valeurs de l'autre.

### Exemples de dépendances fonctionnelles

Illustrons ce concept avec un exemple. Nous allons prendre le cas d'une entreprise qui utilise une BDD pour garder trace de ses ventes. La table des ventes contient cinq colonnes : le client, le produit vendu, le prix unitaire (celui d'un produit), la quantité commandée, et le prix total (pour l'ensemble de la commande). Il existe plusieurs dépendances fonctionnelles dans cette table. Premièrement, une fois qu'on connaît le produit, on connaît son prix de vente : un produit n'a qu'un seul prix unitaire. Deuxièmement, le prix total est déterminé par le prix unitaire et de la quantité vendue. Prenons maintenant un exemple plus complexe. Là encore, nous reprenons l'exemple d'une entreprise qui vend des produits finis à ses clients. La table contient les colonnes suivantes :
* IdClient : un numéro de client (une clé artificielle qui identifie un client) ;
* Nom : le nom du client ;
* Adresse : l'adresse du client pour les livraisons ;
* NuméroCommande : un numéro de commande ;
* Date : la date de commande ;
* NuméroProduit : le numéro du produit vendu au client ;
* QuantitéVendue : la quantité de produits vendus ;
* Prix : le prix unitaire de la commande.
Cette fois-ci, les dépendances fonctionnelles sont plus nombreuses. Premièrement, le numéro de commande permet de déterminer le client final, la date de commande, la quantité vendue. Une commande est reliée à un seul client, à une seule date, à un numéro de produit et à une quantité vendue bien précise. Ensuite, la connaissance du numéro de produit permet de déterminer son prix, comme pour la première table. Et enfin, la connaissance du numéro de client permet de déterminer son nom et son adresse.
Maintenant, prenons l'exemple d'une université qui veut gérer ses élèves. Pour rappel, à la fac, un professeur ne s'occupe généralement que d'un cours bien précis à chaque semestre, ce qui sera le cas dans cet exemple. Celle-ci a, dans sa base de données, une table qui associe un étudiant , un professeur, un cours, et un semestre. Cette table permet de savoir que lors de tel semestre, tel étudiant est censé être dans tel cours avec tel professeur. On peut facilement remarquer quelques dépendances fonctionnelles : la connaissance du semestre et du cours permet de déterminer le professeur, et inversement.

### Détermination des clés depuis les dépendances

Il est possible de représenter graphiquement ces dépendances fonctionnelles avec ce qu'on appelle un graphe, un ensemble de machins reliés entre eux par des flèches. Dans notre cas, les machins en question seront les nom des attributs de la table, et les flèches indiqueront les dépendances fonctionnelles entre deux attributs. Une flèche d'attribut A vers un autre attribut B indique qu'il y a une dépendance fonctionnelle de A vers B : la connaissance de A détermine celle de B. Les clés primaires ou secondaires d'une table peuvent se déduire de ce graphe de dépendances. Les attributs de la clé seront ceux qui ne sont déterminés par aucun autre attribut : la connaissance de ces attributs permet de déduire tous les autres. Sur le graphe, les flèches doivent partir de ces attributs, mais pas en sortir. Les attributs d'où ne sortent ni ne partent de flèches font aussi partie de la clé.