Identifiants

MĂȘme avec un schĂ©ma bien normalisĂ©, il peut y avoir des scenarii dans lesquels il est impossible de choisir la clĂ© primaire qui est un super-key.

Nous avons déjà vu l'exemple :

etudiant_idcours_id

1

SGBDR

1

Backend

2

Angular

3

Backend

3

Angular

cours_idprix

SGBDR

1000

Backend

1500

Angular

2000

Dans l’exemple, les cours sont identifiĂ©s par leur nom en français, mais si on devait utiliser un systĂšme localisĂ© (traduit), le nom du cours n’est plus une super-key.

Un autre exemple, dans le cas d’un Ă©tudiant, il n’y a pas de set d’attributs qui identifie chaque Ă©tudiant, puisqu’il y a toujours la possibilitĂ© que 2 Ă©tudiants partagent les mĂȘmes attributs (nom de famille, prĂ©nom, date de naissance, etc).

Nous désignons alors un identifiant. Mais lequel ?

Une chose est certaine : le ID doit ĂȘtre une super-key et donc avoir des mĂȘmes caractĂ©ristiques :

  • ĂȘtre unique sur toutes les lignes de la table

  • identifier une seule ligne de la table

ID type auto-increment

Une option fournie par beaucoup de SGBDR est l'identifiant de type entier qui s'incrémente automatiquement avec chaque insert into. Le SGBDR prend note de la progression de ce compteur, assurant alors son unicité.

On utilise le mot auto_increment :

create table etudiant (
  id int not null auto_increment,
  nom varchar(255),
  prenom varchar(255),
  primary key (id)
);

Ce type de clé a plusieurs avantages :

  • Facile Ă  lire

  • Un Ă©tudiant n’a qu’à retenir son numĂ©ro pour accĂ©der aux services

  • Optimal pour la construction des indexes

En revanche, il y a aussi plusieurs désavantages :

  • Facile Ă  espionner : Si on connait le numĂ©ro d’un Ă©tudiant, par exemple, 55, on saurait immĂ©diatement qu’il y a un Ă©tudiant 54 et 56

  • On peut dĂ©terminer la quantitĂ© (minimale) d’entitĂ©s dans la table juste par son ID. Ex. nombre de commandes passĂ©s

  • Risque d’erreurs en insertion en parallĂšle. Imaginons que 2 processus essaie d’insĂ©rer une ligne en mĂȘme temps. Comment la valeur s’incrĂ©mente ?

  • Difficile Ă  gĂ©rer les doubles dans les systĂšmes distribuĂ©s : s'il a plusieurs data-centers, chacun gĂšre son identifiant, le risque de doublon est Ă©levĂ© !

Exercice

Insérer quelques lignes à la table dessus.

  • Qu'est-ce que vous observez ?

  • Supprimer la derniĂšre ligne, et en ajoutez une nouvelle. Qu'est-ce que vous observez ?

ID type UUID

Un UUID (Universal Unique Identifier) est un numĂ©ro alĂ©atoire gĂ©nĂ©rĂ© (par un algorithme) selon un set de variables qui sont plus ou moins garanties d’ĂȘtre uniques :

  • La date, heure, secondes, millisecondes

  • L’adresse mac de l’ordinateur

  • La tempĂ©rature de l’ordinateur au moment de la gĂ©nĂ©ration

  • ... et un ensemble de facteurs similaires

L'objectif ultime est de pouvoir, Ă  tout moment, gĂ©nĂ©rer une valeur qui est garantie (ou au moins aura une trĂšs trĂšs haute probabilitĂ©) d'ĂȘtre unique au monde. Bien Ă©videmment, ceci est une tĂąche presque impossible. Mais, ce qui suffit pour notre plateforme, est que la valeur soit unique, juste dans le domaine de notre table, qui est beaucoup plus faisable !

Dans notre SGBDR, on peut récupérer une valeur type UUID avec une fonction :

select uuid();

On peut appeler cette fonction comme default pour notre identifiant :

create table customer (
  id varchar(36) not null default uuid(),
  name varchar(256),
  primary key (id)
);

Les UUIDS ont des avantages et désavantages aussi.

Avantages :

  • unicitĂ© et (presque) garanti

  • difficile Ă  espionner

  • facilite des SGBDR distribuĂ©s

DĂ©savantages :

  • difficile Ă  lire (donc pas appropriĂ© pour donner aux utilisateurs, comme numĂ©ro d'Ă©tudiant par exemple)

  • plus de place nĂ©cessaire pour le stockage

  • plus lent pour les recherches

Triggers

Un déclencheur est une sorte de fonction qui est appelée systématiquement avant ou aprÚs une action (insert, update, delete) sur une ligne.

Ils peuvent ĂȘtre donc trĂšs utiles pour faire un prĂ©traitement de nos donnĂ©es, ou bien des post-traitements, pour, par exemple, dĂ©clencher des mises Ă  jour secondaires.

Par exemple, dans le cas de gĂ©nĂ©ration de UUIDon pourra intercepter la requĂȘte insert, et en modifiant les valeurs :

create trigger before_insert_customer
before insert on customer
for each row
set new.id = uuid();

Ici, on précise before insert on customer : avant d'insérer une nouvelle ligne à la table customer. On procÚde à générer un uuid pour la nouvelle ligne.

C'est ainsi qu'on assure de toujours générer en interne nos UUID.

Je vous laisse comme exercice une exploration plus profonde : https://www.mariadbtutorial.com/mariadb-triggers/mariadb-create-trigger/

DerniĂšre mise Ă  jour