Précédent   Forum des professionnels en informatique > Bases de données > MySQL
MySQL Forum d'entraide MySQL. Avant de poster -> FAQ MySQL, Tutoriels MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/01/2011, 16h08   #1
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 77
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 77
Points : 71
Points : 71
Par défaut Clé composée de plusieurs champs

Bonjour à tous !

J'ai une question concernant les clés primaires composées de plusieurs colonnes.

Actuellement, j'ai une table formée de cette manière :

Code :
1
2
3
4
5
6
7
CREATE TABLE IF NOT EXISTS LIGNE_COMMANDE
 (
   id_commande integer(4) NOT NULL,
   id_audit integer(4) NOT NULL,
   id_site integer(4) NOT NULL, 
   PRIMARY KEY (id_commande,id_audit,id_site) 
 )
Ma clé primaire est donc : id_commande, id_audit, id_site.

Mais j'aimerais plutôt concaténé ces 3 identifiants pour n'en former qu'un seul. (En théorie, ces 3 colonnes sont censées être, selon mon MCD, des identifiants relatifs).

MySql me permet-il donc de créer une seule et unique clé qui concatènerait les 3 champs indiqués ? Ou dois-je réaliser différents traitements au niveau de mon application pour le faire ? (ce qui me semble embêtant).

Merci pour vos futurs réponses
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 16h17   #2
Membre Expert
 
Avatar de gene69
 
Inscription : janvier 2006
Messages : 951
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : janvier 2006
Messages : 951
Points : 1 063
Points : 1 063
oui tu peux le faire.
non je sais pas ce que tu peux y gagner.

Code :
1
2
3
 
SELECT CONCAT(a,b,c)
FROM tatable
__________________
PHP fait nativement la validation d'adresse électronique Vous êtes perdu en PHP? rassurez-vous ici (en)
Utilisez le bouton résolu!
gene69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 16h19   #3
Membre Expert
 
Avatar de gene69
 
Inscription : janvier 2006
Messages : 951
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : janvier 2006
Messages : 951
Points : 1 063
Points : 1 063
vu le nom des champs, tu devrais te rappeler qu'on ne fait pas de change un vendredi. d'une part du va perdre le côté sympa des clés étrangères et de l'autre côté tu ne vas rien y gagner, et en plus tu vas perdre du temps.
__________________
PHP fait nativement la validation d'adresse électronique Vous êtes perdu en PHP? rassurez-vous ici (en)
Utilisez le bouton résolu!
gene69 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 16h49   #4
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 77
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 77
Points : 71
Points : 71
Citation:
vu le nom des champs, tu devrais te rappeler qu'on ne fait pas de change un vendredi. d'une part du va perdre le côté sympa des clés étrangères et de l'autre côté tu ne vas rien y gagner, et en plus tu vas perdre du temps.
Je cherche justement une solution qui me permette de préserver les clés étrangères, tout en ayant mon identifiant composé (= concaténé) !

Citation:
Envoyé par gene69 Voir le message
oui tu peux le faire.
non je sais pas ce que tu peux y gagner.

Code :
1
2
3
 
SELECT CONCAT(a,b,c)
FROM tatable
Oui donc si je comprends bien, c'est à moi de le faire, et le SGBDR ne le fait pas.
N'y-a-t-il pas une autre solution ?

Merci pour ta réponse.
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 17h10   #5
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 241
Points : 18 241
Envoyer un message via MSN à CinePhil
La question qu'on se pose, c'est : Pourquoi diable veux-tu concaténer ces 3 identifiants ?
pas pour remplacer la clé primaire normalisée par cette concaténation j'espère ?

Ce serait une très mauvaise idée !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 18h06   #6
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 77
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 77
Points : 71
Points : 71
Non non, surtout pas.
En fait, j'ai modélisé ainsi ma bdd (enfin, ce n'est qu'une petite partie de la bdd) :

audit 0,N ---------- 1,1 (R) ligne_commande
commande 0,N ---- 1,1 (R) ligne_commande
site 0,N ----------- 1,1 (R) ligne_commande

Ce qui revient à faire une association ternaire.

Maintenant, imaginons que j'ai une ligne de ce type dans ma table ligne_commande:
Code :
1
2
3
4
 
id_audit | id_commande | id_site
----------------------------------
5        |       7     |  9
Je pensais que le SGBDR, en + d'effectuer une contrainte (primary key) sur les 3 colonnes, pouvait créer l'identifiant suivant : "579", et le caser dans une nouvelle colonne. Mais ce n'est pas le cas, j'ai dû rêver

Si ça pouvait être le cas, ça m'aurait arrangé car ça m'aurait permis d'identifier simplement une ligne de commande (et effectuer différents traitements par rapport à celle-ci).

voila
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 18h12   #7
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 241
Points : 18 241
Envoyer un message via MSN à CinePhil
Si tu as vraiment besoin d'un identifiant indépendant de la ligne de commande, tu peux ajouter une colonne auto-incrémentée et en faire ta clé primaire puis ajouter un index UNIQUE sur le triplet des anciennes colonnes clés primaires.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/01/2011, 18h15   #8
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

Citation:
Envoyé par chewing-gum Voir le message
Maintenant, imaginons que j'ai une ligne de ce type dans ma table ligne_commande:
Code :
1
2
3
4
 
id_audit | id_commande | id_site
----------------------------------
5        |       7     |  9

Si ça pouvait être le cas, ça m'aurait arrangé car ça m'aurait permis d'identifier simplement une ligne de commande (et effectuer différents traitements par rapport à celle-ci).
Et maintenant imaginaons que tu ais

Code :
1
2
3
4
5
 
id_audit | id_commande | id_site
----------------------------------
11       |       1      |  9
1        |       11     |  9
Crois tu toujours qu'il sera aussi "simple" d'identifier une ligne de commande ?
1119 = 1119

Je ne saurais qu'appuyer CinePhil :
Citation:
Ce serait une très mauvaise idée !
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2011, 14h08   #9
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 77
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 77
Points : 71
Points : 71
Citation:
Envoyé par CinePhil Voir le message
Si tu as vraiment besoin d'un identifiant indépendant de la ligne de commande, tu peux ajouter une colonne auto-incrémentée et en faire ta clé primaire puis ajouter un index UNIQUE sur le triplet des anciennes colonnes clés primaires.
Ah merci ! C'est ça que j'aurais voulu faire, mais effectivement, je peux m'en passer même si ça me faciliterait certains traitements.

Citation:
Envoyé par aieeeuuuuu Voir le message
Crois tu toujours qu'il sera aussi "simple" d'identifier une ligne de commande ?
1119 = 1119
Je les aurais séparer par des tirets : 1-11-9 et 11-1-9, mais ça n'est pas terrible, c'est vrai.

--------------------------------------------------

Du coup, j'ai une autre question.
J'ai fait un test sur MySql avec deux entités de ce genre :

ALPHA 0,N --------------- 1,1 (R) BETA

A noter que l'identifiant d'ALPHA est auto-incrémenté, celui de BETA aussi !

Ce qui me donne :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# table : alpha
CREATE TABLE alpha
 (
   id_alpha integer(2) NOT NULL AUTO_INCREMENT, 
   PRIMARY KEY (id_alpha) 
 ) 
ENGINE = innodb;
 
 
# table : beta
CREATE TABLE beta
 (
   id_alpha integer(2) NOT NULL  ,
   id_beta integer(2) NOT NULL AUTO_INCREMENT, 
   PRIMARY KEY (id_alpha,id_beta) 
 ) 
engine = innodb;
 
# creation des references de table
 
ALTER TABLE beta 
  ADD FOREIGN KEY fk_beta_alpha (id_alpha)
      REFERENCES alpha (id_alpha) ;
Mais j'obtiens l'erreur suivante :
Citation:
#1075 - Un seul champ automatique est permis et il doit être indexé
Ma question est : pourquoi je ne peux pas avoir le champ "id_beta" en auto-incrémenté ?
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2011, 14h41   #10
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 990
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 990
Points : 18 241
Points : 18 241
Envoyer un message via MSN à CinePhil
Citation:
ALPHA 0,N --------------- 1,1 (R) BETA
Normalement, avec ce schéma, tu auras pour la table BETA une clé primaire composée, comme tu l'as fait dans ton CREATE TABLE, de l'identifiant de ALPHA et de l'identifiant de BETA.

L'exemple classique de ce genre de modèle est celui des chambres d'hôtels.
Hotel -1,n----Avoir----(1,1)- Chambre
Ce MCD pourrait générer les tables suivantes :
Hotel (htl_id, htl_nom...)
Chambre (chb_id_hotel, chb_num_chambre...)

Tu remarqueras que j'ai appelé la seconde colonne de la clé primaire de Chambre "chb_num_chambre" et pas "chb_id_chambre" ; cette colonne est porteuse de sens et correspond bel et bien au numéro physique de la chambre dans l'hôtel. Ainsi, pour chaque hôtel, les numéros de chambres vont de 1 à n.

Dans ta table, tu as mis un AUTO_INCREMENT sur ce qui correspond au numéro de chambre. Autrement dit, pour une chaîne d'hôtels genre Campanile qui doit en comporter des centaines (des milliers ?), l'hôtel situé à Toulouse Labège pourrait avoir des numéros de chambre de 2815 à 2872. Ça fait bizarre non ?

Idem pour les commandes et les lignes de commande ou de facture par identification relative ; les numéros de lignes de commande ou de facture vont de 1 à n pour chaque commande. Recevoir une facture avec des lignes numérotées de 165812 à 165823, ça fait bizarre non ?

=> Il ne faut pas mettre d'auto-incrémentation sur la seconde colonne de la clé primaire ! Il faut gérer la numérotation lors de l'INSERT en cherchant l'identifiant max pour la première colonne.

Je reprends le message d'erreur que tu as reçu :
Citation:
#1075 - Un seul champ automatique est permis et il doit être indexé
C'est un message standard mais dans ce cas, c'est la seconde partie de la phrase qui est la cause de l'erreur. Dans l'index créé par la clé primaire de ta table, la colonne auto-incrémentée id_beta est située en seconde position. Du coup, elle n'est pas indexée individuellement mais seulement relativement à la première.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/01/2011, 17h01   #11
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 77
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 77
Points : 71
Points : 71
Effectivement, je comprends mieux mon erreur !

Merci pour ta réponse CinePhil
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h23.


 
 
 
 
Partenaires

Hébergement Web