Bonsoir rabDev,
A propos de l'ordre des colonnes dans la clé primaire d’une table SQL.
Il est impératif que les colonnes de la clé d’une table T2
identifiée relativement à une table T1 soient ordonnées en fonction de l’importance relative de ces deux tables : en tête, doivent figurer les colonnes de la clé de T1, celles de T2 venant seulement à la suite. En effet, au niveau conceptuel, T2 n’est jamais qu’une propriété multivaluée de T1. En conséquence, au stade SQL, les accès mettront fondamentalement en jeu les attributs composant la clé primaire de T1 (et la clé étrangère correspondante portée par T2, jointure oblige).
Exemple des factures (qu’on pourrait qualifier de canonique, tant il revient souvent) :
Lors du passage au MLD, JMerise (0.4.0.1) génère simultanément le code SQL suivant,
lequel comporte ici une anomalie (présence d’une colonne sans nom dans l’en-tête de la table LIGNE_FACTURE...) :
#------------------------------------------------------------
# Table: FACTURE
#------------------------------------------------------------
CREATE TABLE FACTURE(
id_facture Int NOT NULL ,
num_facture Int NOT NULL ,
date_facture Date NOT NULL ,
PRIMARY KEY (id_facture ) ,
UNIQUE (num_facture )
)ENGINE=InnoDB;
#------------------------------------------------------------
# Table: LIGNE_FACTURE
#------------------------------------------------------------
CREATE TABLE LIGNE_FACTURE(
id_ligne_facture Int NOT NULL ,
quantite Int NOT NULL ,
Int ,
id_facture Int NOT NULL ,
PRIMARY KEY (id_ligne_facture ,id_facture )
)ENGINE=InnoDB;
La clé primaire générée est la suivante :
{id_ligne_facture, id_facture}
Le point important concerne la performance des requêtes SQL : pour accéder aux lignes d’une facture, il va falloir un
index supplémentaire de clé {id facture} pour la table LIGNE_FACTURE. Qui plus est, le regroupement des données en mémoire (
clustering) sera par défaut sur id_ligne_facture ce qui fait qu’il faudra un I/O par ligne de facture (à moins que juste après la génération du code, le DBA arrive à temps pour rendre cluster l’index supplémentaire à la place du 1er (manip qui est SGBD dépendante...)).
Par contre, si JMerise générait la clé primaire suivante :
{id_facture, id_ligne_facture}
Alors tout rentrerait dans l’ordre, la recherche des lignes d’une facture ne nécessiterait qu’une I/O, et en plus, il serait
inutile de créer un index supplémentaire. Sémantique, coût et performance se rejoignent... A noter que DB-MAIN, PowerAMC, même MySQL Workbench ordonnent les colonnes ainsi. Pour ma part je suis très vigilant sur ce point et en plus de 30 ans de baroud (concepteur ou DBA) dans les grandes entreprises, à m’engager sur la validité et la performance de leurs bases de données SQL, je n’ai jamais eu à changer d’approche (sauf dans de rares cas de problèmes de contention, mais je ne voudrais pas sortir du sujet, qui concerne plus le réglage des accès aux données, tout au fond de la soute).
Partager