Clefs et base de données, les bonnes manières

Les identifiants techniques : les clefs primaires

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. 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 ces lignes. Ce qui arrive dans deux cas :

  • Les références de table à table dans le SGBD.
  • On peut aussi stocker des valeurs de clefs primaires en dehors de la base, dans des programmes et des scripts clients. Par exemple pour afficher un libellé dans un programme, on peut être amené à écrire “en dur” dans le code une valeur de clef primaire.

Par principe, 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.

C’est parce qu’elles ne doivent jamais être modifiées, que les valeurs de clefs primaires ne devraient pas être connue par la partie fonctionnelle. En fait l’utilisateur final devrait simplement en ignorer l’existence.

L’identifiant le plus efficace est alors un simple entier que le SGBD se chargera si possible d’incrémenter.

Pas d’intégrité référentielle par triggers !

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.

Les identifiants de l’utilisateur : les clefs fonctionnelles

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 plusieurs identifiants fonctionnels.

L’utilisateur stockera certains identifiants fonctionnels en dehors des logiciels informatiques, en les écrivant sur des dossiers papiers par exemple. À 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 s’accomode toujours d’exceptions, pour la technique c’est plus douloureux. Aussi dans la mesure du possible on évitera d’utiliser la clef fonctionnelle comme clef primaire.

L’unicité des lignes d’un point de vu fonctionnel peut toutefois être implémentée de façon souple. En effet, l’unicité fonctionnelle n’est pas toujours absolue et tolère parfois 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 a posteriori. Le logiciel se contentera alors d’un message d’avertissement et de l’affichage d’une liste des doublons.

Quand la conception décide qu’une unicité fonctionnelle est absolue, on peut l’implémenter dans le SGBD au moyen d’une contrainte unique.

Un exemple

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).

Leave a Reply

Your email address will not be published. Required fields are marked *

Mesure anti-spam. Merci de copier le code « y41Bng » dans le champ ci-dessous :