{MySQL} Optimisation-Clés primaires multiples

Fermé
alter - 9 juin 2009 à 16:39
 alter - 11 juin 2009 à 12:22
Bonjour,
J'ai créé une table qui posséde une clé primaire multiple : c'est la concaténation de 4 clés secondaires. (C'est la solution 1 que j'ai mis en dessous).
Je voudrais savoir s'il n'est pas plus judicieux de créer une clé primaire simple (un seul champs) et de faire appel à ces 4 meme clés étrangères car cette table est liée cinq fois à d'autres tables avec des relations 1,n --> 1,1. Ces relations m'obligent alors à faire référence à cette clé primaire multiple qui me semble lourde à gérer.
Je voudrais donc savoir si la 2ème solution est correcte et si elle est bien préférable.

*****************************************************
Solution 1 :
create table DONNEES
(
Donnees_Nom varchar(250) binary not null,
Donnees_Date_Start date,
Donnees_Date_End date,
FORME_ID integer not null,
CHAMPS_1_ID integer not null,
CHAMPS_2_ID integer not null,
CHAMPS_3_ID integer not null,
FORME_CATEGORIE_ID integer not null,
BASE_ID integer not null,
primary key (FORME_ID,CHAMPS_1_ID,CHAMPS_2_ID,CHAMPS_3_ID),
unique (Donnees_Nom),
FOREIGN KEY (FORME_ID) REFERENCES FORME (FORME_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_1_ID) REFERENCES CHAMPS_1 (CHAMPS_1_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_2_ID) REFERENCES CHAMPS_2 (CHAMPS_2_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_3_ID) REFERENCES CHAMPS_3 (CHAMPS_3_ID) ON DELETE CASCADE,
FOREIGN KEY (FORME_CATEGORIE_ID) REFERENCES FORME_CATEGORIE (FORME_CATEGORIE_ID) ON DELETE CASCADE,
FOREIGN KEY (BASE_ID) REFERENCES BASE (BASE_ID) ON DELETE CASCADE
) ENGINE = InnoDB;
*****************************************************
*****************************************************
Solution 2 :
create table DONNEES
(
DONNEES_ID integer auto_increment,
Donnees_Nom varchar(250) binary not null,
Donnees_Date_Start date,
Donnees_Date_End date,
FORME_ID integer not null,
CHAMPS_1_ID integer not null,
CHAMPS_2_ID integer not null,
CHAMPS_3_ID integer not null,
FORME_CATEGORIE_ID integer not null,
BASE_ID integer not null,
primary key (DONNEES_ID),
unique (Donnees_Nom),
FOREIGN KEY (FORME_ID) REFERENCES FORME (FORME_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_1_ID) REFERENCES CHAMPS_1 (CHAMPS_1_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_2_ID) REFERENCES CHAMPS_2 (CHAMPS_2_ID) ON DELETE CASCADE,
FOREIGN KEY (CHAMPS_3_ID) REFERENCES CHAMPS_3 (CHAMPS_3_ID) ON DELETE CASCADE,
FOREIGN KEY (FORME_CATEGORIE_ID) REFERENCES FORME_CATEGORIE (FORME_CATEGORIE_ID) ON DELETE CASCADE,
FOREIGN KEY (BASE_ID) REFERENCES BASE (BASE_ID) ON DELETE CASCADE
) ENGINE = InnoDB;
*****************************************************
A voir également:

5 réponses

wjaouadi Messages postés 25 Date d'inscription vendredi 13 mars 2009 Statut Contributeur Dernière intervention 25 décembre 2009 160
10 juin 2009 à 10:27
Bonjour,
A mon avis la première solution reste la plus appropriée étant données qu'en mettant les clé étrangère en primaire multiples ceci indique implicitement que l'entité donnée est définie par ces champs la et exprime ainsi une forte liaison entre les entités.
Alors qu'en ajoutant une clé primaire cette relation forte n'est plus aussi clairement exprimée.
Mise à part que la gestion des clés n'ai pas aussi lourde à gérer au contraire elle permet de garantir l'intégrité des données.
0
Bonjour
Dommage cette solution 1 ne m'arrange pas parce que j'ai une erreur quand je lie cette table DONNEES (en solution 1 ci-dessus) à une autre table qui se nomme CHOIX : Seule FORME_ID est détectée comme clé étrangère, les trois autres clés qui devraient etre validée comme étant clés étrangères ne le sont pas :
Voici ce que j'obtiens en regardant les colonnes de la table CHOIX (reliée à la table DONNEES avec une relation 1,1 --> 0,n) :
+---------------------------------------+---------+------+------+---------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------------------+---------+------+------+---------+-------------------+
| CHOIX_ID | int(11) | NO | PRI | NULL | auto_increment |
| Donnees_Date_Start_Choisie | date | NO | | | |
| Donnees_Date_End_Choisie | date | NO | | | |
| FORME_ID | int(11) | NO | MUL | | |
| CHAMPS_1_ID | int(11) | NO | | | |
| CHAMPS_2_ID | int(11) | NO | | | |
| CHAMPS_3_ID | int(11) | NO | | | |
+---------------------------------------+---------+------+-------+--------+-------------------+

Voici mon code de création de la table CHOIX :
create table CHOIX
(
CHOIX_ID integer not null auto_increment,
Donnees_Date_Start_Choisie date not null,
Donnees_Date_End_Choisie date not null,
FORME_ID integer not null,
CHAMPS_1_ID integer not null,
CHAMPS_2_ID integer not null,
CHAMPS_3_ID integer not null,
primary key (CHOIX_ID),
INDEX (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID),
FOREIGN KEY (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID) REFERENCES DATA_TYPE (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID) ON DELETE CASCADE
) ENGINE = InnoDB;

Je ne vois pas l'erreur dans le code de création de la table CHOIX, est-ce que vous la voyez ?
0
Dans la table CHOIX, j'ai marqué DATA_TYPE au lieu de DONNEES. C'est une erreur dans mon énoncée mais ce n'est pas ça l'erreur que je ne recherche...
0
wjaouadi Messages postés 25 Date d'inscription vendredi 13 mars 2009 Statut Contributeur Dernière intervention 25 décembre 2009 160
10 juin 2009 à 17:22
Re Bonjour,
Il faut essayer de déclarer chaque clé étrangère à part en utilisant la primitive
Constraint FK_XXX FOREIGN KEY (champs) references table(champs)ON DELETE CASCADE,
...
Pas besoin de mettre la contrainte non null à CHOIX_ID c'est une clé primaire donc la contrainte est implicite.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonjour,
J'ai suivi tes conseils mais c'est sans succès. J'obtiens le même résultat que précédemment avec ce nouveau code :
create table DONNEES
(
Donnees_Nom varchar(250) binary not null,
Donnees_Date_Start date,
Donnees_Date_End date,
FORME_ID integer not null,
CHAMPS_1_ID integer not null,
CHAMPS_2_ID integer not null,
CHAMPS_3_ID integer not null,
FORME_CATEGORIE_ID integer not null,
LOCAL_ID integer not null,
primary key (FORME_ID,CHAMPS_1_ID,CHAMPS_2_ID,CHAMPS_3_ID),
unique (Donnees_Nom),
CONSTRAINT FK_FORME FOREIGN KEY (FORME_ID) REFERENCES FORME (FORME_ID) ON DELETE CASCADE,
CONSTRAINT FK_CHAMPS_1 FOREIGN KEY (CHAMPS_1_ID) REFERENCES CHAMPS_1 (CHAMPS_1_ID) ON DELETE CASCADE,
CONSTRAINT FK_CHAMPS_2 FOREIGN KEY (CHAMPS_2_ID) REFERENCES CHAMPS_2 (CHAMPS_2_ID) ON DELETE CASCADE,
CONSTRAINT FK_CHAMPS_3 FOREIGN KEY (CHAMPS_3_ID) REFERENCES CHAMPS_3 (CHAMPS_3_ID) ON DELETE CASCADE,
CONSTRAINT FK_FORME_CATEGORIEB FOREIGN KEY (FORME_CATEGORIE_ID) REFERENCES FORME_CATEGORIE (FORME_CATEGORIE_ID) ON DELETE CASCADE,
CONSTRAINT FK_LOCAL FOREIGN KEY (LOCAL_ID) REFERENCES LOCAL (LOCAL_ID) ON DELETE CASCADE
) ENGINE = InnoDB;

create table CHOIX
(
CHOIX_ID integer auto_increment,
Donnees_Date_Start_Choisie date not null,
Donnees_Date_End_Choisie date not null,
FORME_ID integer not null,
CHAMPS_1_ID integer not null,
CHAMPS_2_ID integer not null,
CHAMPS_3_ID integer not null,
primary key (CHOIX_ID),
INDEX (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID),
CONSTRAINT FK_DONNEES FOREIGN KEY (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID) REFERENCES DONNEES (FORME_ID, CHAMPS_1_ID, CHAMPS_2_ID, CHAMPS_3_ID) ON DELETE CASCADE
) ENGINE = InnoDB;

show columns from CHOIX;
+----------------------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+---------+------+-----+---------+----------------+
| CHOIX_ID | int(11) | NO | PRI | NULL | auto_increment |
| Donnees_Date_Start_Choisie | date | NO | | | |
| Donnees_Date_End_Choisie | date | NO | | | |
| FORME_ID | int(11) | NO | MUL | | |
| CHAMPS_1_ID | int(11) | NO | | | |
| CHAMPS_2_ID | int(11) | NO | | | |
| CHAMPS_3_ID | int(11) | NO | | | |

+----------------------------+---------+------+-----+---------+----------------+

********************************************************************************************************
Les autres tables créées précedemment et qui sont reliées à DONNEES sont ci-dessous. Elles ne posent pas de problème.
create table FORME_CATEGORIE
(
FORME_CATEGORIE_ID integer auto_increment,
Forme_Categorie_Name varchar(2) binary not null,
Forme_Categorie_Description varchar(250) binary,
primary key (FORME_CATEGORIE_ID),
unique (Forme_Categorie_Name)
) ENGINE = InnoDB;

create table FORME
(
FORME_ID integer auto_increment,
Forme_Name varchar(2) binary not null,
Forme_Description varchar(250) binary,
FORME_CATEGORIE_ID integer not null,
primary key (FORME_ID),
unique (Forme_Name),
INDEX (FORME_CATEGORIE_ID),
CONSTRAINT FK_FORME_CATEGORIEA FOREIGN KEY (FORME_CATEGORIE_ID) REFERENCES FORME_CATEGORIE (FORME_CATEGORIE_ID) ON DELETE CASCADE
) ENGINE = InnoDB;

create table LOCAL
(
LOCAL_ID integer auto_increment,
Local_Name varchar(2) binary not null,
Local_Description varchar(250) binary,
primary key (LOCAL_ID),
unique (Local_Name)
) ENGINE = InnoDB;

create table CHAMPS_1
(
CHAMPS_1_ID integer auto_increment,
Champ1_Name varchar(2) binary not null,
Champ1_Description varchar(250) binary,
primary key (CHAMPS_1_ID),
unique (Champ1_Name)
) ENGINE = InnoDB;

create table CHAMPS_2
(
CHAMPS_2_ID integer auto_increment,
Champ2_Name varchar(2) binary not null,
Champ2_Description varchar(250) binary,
primary key (CHAMPS_2_ID),
unique (Champ2_Name)
) ENGINE = InnoDB;

create table CHAMPS_3
(
CHAMPS_3_ID integer auto_increment,
Champ3_Name varchar(2) binary not null,
Champ3_Description varchar(250) binary,
primary key (CHAMPS_3_ID),
unique (Champ3_Name)
) ENGINE = InnoDB;
********************************************************************************************************
0