Dernière mise à jour le 3 septembre 2005.
Clefs et base de données, les bonnes manières
Dans une base de données, chaque table devrait contenir une clef primaire. Une clef primaire est une contrainte d'unicité sur une ou plusieurs colonnes. Dans un SGBDR la clef primaire est le moyen technique d'identifier chaque ligne de données. Les valeurs de la clef primaire sont ensuite utilisées pour référencer des lignes de données. Ce qui arrive dans deux cas :
Il est raisonnable d'affirmer dès la conception qu'une valeur de clef primaire ne devra jamais être modifiée, ni même réutilisée si par hasard elle venait à être supprimée. En effet, même s'il est parfois possible de créer des procédures stockées qui viennent à bout de l'intégrité référentielle, pensez aux futurs développeurs qui devront faire évoluer une telle base et ses dépendances.
C'est parce qu'elles ne doivent jamais être modifiées, que les valeurs de clefs primaires ne devraient pas avoir de sens d'un point de vue fonctionnel. En fait l'utilisateur final n'a pas à connaitre ces valeurs, et devrait même en ignorer l'existence.
Une fois ces notions ainsi posées, on admettra que l'identifiant le plus efficace est un simple entier que le SGBD se chargera d'incrémenter, si possible.
Juste une petite disgression pour préciser qu'en général dans le développement informatique il faut utiliser les standards. Et le standard en matière de liens entre tables dans un SGBDR, c'est l'intégrité référentielle. Attention à la tentation du trigger implémenté manuellement qui, sous couvert de sur-mesure, va compliquer sérieusement la tâche des logiciels de reverse engineering et des développeurs qui reprendront votre projet.
Un utilisateur identifie toujours chaque ligne de données d'un point de vue fonctionnel. Il utilise pour cela un ensemble de colonnes dont la définition est souvent intuitive (il s'agit par exemple des colonnes affichées dans une combo-box). Il peut arriver que pour une même table on ait deux identifiants fonctionnels.
L'utilisateur stockera certains identifiants fonctionnels en dehors des logiciels informatiques, en les écrivant sur des dossiers papiers par exemple. A cause de ces références externes et comme pour la clef primaire, il est rare qu'un identifiant fonctionnel soit modifié. Notez qu'un utilisateur a souvent conscience du caractère immuable de sa clef et vous le dira. Mais cette responsabilité est du domaine fonctionnel et ne nous concerne pas. Il importe même de ne pas lui faire confiance : le fonctionnel pourra s'accomoder d'exceptions car l'être humain est intelligent, la technique ne le pourra pas. Aussi dans la mesure du possible, on évitera d'utiliser la clef fonctionnelle comme clef primaire.
S'il existe une notion d'unicité d'un point de vue fonctionnel (deux lignes ne doivent pas pouvoir être confondues), cette notion peut en revanche être traduite de façon souple d'un point de vue technique. En effet, l'unicité fonctionnelle n'est pas toujours absolue et peut parfois tolérer des moments de non-intégrité. Par exemple un utilisateur peut préférer ne pas s'occuper des doublons lors de sa saisie et corriger à postériori.
Toutefois quand la conception détermine qu'une unicité fonctionnelle est absolue, on peut l'implémenter dans un SGBDR au moyen d'une contrainte unique.
Voyons un exemple. Prenons le cas d'une table Ville qui référence une table Pays. Voici un script de création des tables :
create table Pays (
id_pays integer not null primary key,
code_pays char(3) not null unique,
nom_pays varchar(255) not null unique,
superficie_km2 integer
);
create table Ville (
id_ville integer not null primary key,
nom_ville varchar(255) not null,
ref_pays integer not null references Pays (id_pays),
nb_habitants integer,
unique (nom_ville, ref_pays)
);
La table Pays possède une clef primaire (id_pays) et deux clefs fonctionnelles (code_pays et nom_pays).
La table Ville possède une clef primaire (id_ville) et une clef fonctionnelle. Techniquement cette clef fonctionnelle est composée de la colonne nom_ville et de la clef étrangère vers la table Pays. D'un point de vue fonctionnel, elle est composée du nom de la ville (nom_ville) associée à la clef fonctionnelle de la table Pays (code_pays ou nom_pays, au choix).
J'espère avoir éclairci la problématique. N'hésitez pas à me faire part de vos commentaire.
Thomas Mur

© Copyright 2005 Thomas Mur. Ce document est sous licence GNU FDL. Vous pouvez le copier et modifier librement les copies tant que cette mention apparaît clairement.