|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||
|
Invité de passage
![]() Inscription : juin 2010 Messages : 9 ![]() |
Bonjour,
Je travaille à l'heure actuelle sur la base de données d'un site e-commerce, et je me trouve devant un petit problème. En effet, j'ai deux tables qui ont chacun une clé étrangère sur l'autre. Il faudrait que je puisse les déclarer en même temps (sinon la création est refusée). Ayant eu des cours sur les bases de données lors de mon cursus scolaire, je suis à peu près sûr que c'est possible, mais j'ai été incapable de trouver la réponse sur Internet :-( En fait, j'ai plus précisément trois tables, mais je pense que si je m'en sors avec deux, je m'en sortirais aussi avec trois ^^. Voici les tables et les contraintes voulues (je laisse juste les contraintes dedans, avec juste les parties intéressantes, mais en vrai il y a beaucoup plus d'informations) : Code :
Merci d'avance ! Naoris PS : je sais pas si ça peut être important, mais j'utilise MySQL |
||
|
|
00
|
|
|
#2 |
|
Membre émérite
![]() Tony Développeur .NET Inscription : novembre 2010 Messages : 570 ![]() |
Bonjour,
si tu trouves une relation 1,1 des deux côtés, c'est qu'il y a une erreur de conception. Deux tables ne peuvent pas posséder chacune une clé étrangère vers l'autre. Si tu souhaites continuer ainsi, dis toi qu'un client possède 1 ou 0 adresse (à sa création tu insères d'abord le client, puis ses adresses, pire si il doit posséder une seule adresse cette table n'a aucun intérêt), de même pour la panier
__________________
Le Porc est un loup pour le Porc. |
|
|
00
|
|
|
#3 |
![]() ![]() |
Il faut voir dans les clés étrangères une certaines dépendance d'une table par rapport à l'autre.
Le client dépend-il de son adresse ou l'adresse est-elle une propriété (éventuellement multiple) du client ? Le client dépend-il de son panier ou le panier dépend-il du client ? Le fait qu'une adresse soit l'adresse principale du client est plutôt une propriété de l'adresse que du client. Tu pourrais modéliser cela par une colonne booléenne "mainAddress" dans la table des adresses. Idem pour le caractère temporaire d'un "cart". Sinon, pour répondre à ta question et dans le cas où tu aurais par exemple des cardinalités (1,1 - 1,n), la solution est dans l'écriture d'un trigger à l'insertion qui insère dans les deux tables "en même temps". Mais d'une manière générale, il faut éviter au maximum d'avoir des cardinalités mini à 1 des deux côtés d'une association.
__________________
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 ! |
|
00
|
|
|
#4 |
|
Invité de passage
![]() Inscription : juin 2010 Messages : 9 ![]() |
Tout d'abord, merci beaucoup pour vos réponses.
Il est vrai que je pourrais rajouter une colonne booléenne pour les adresses, mais en fait ce qui m'embête c'est que le client peut enregistrer autant d'adresses qu'il le souhaite, et en choisir une pour la rendre "principale" à tout moment, donc le caractère "principal" d'une l'adresse dépend plus du client que de l'adresse en soi (enfin je trouve ^^). Pour les paniers, ma logique était différente, car lorsqu'un client veut mettre des objets dans son panier, un panier est automatiquement créé, et se remplit. Puis le client peut enregistrer ce panier (ce qui lui enlève sa propriété "temporaire"), et un nouveau panier vide lui est alloué. Cette fois, par contre, il me semble plus logique de rajouter une colonne temporaryCart dans ma table Carts (comme vous l'avez proposé). Pensez-vous que je devrais faire la même chose pour les deux tables Carts et Addresses, en ajoutant une colonne booléenne ? |
|
|
00
|
|
|
#5 |
|
Membre émérite
![]() Tony Développeur .NET Inscription : novembre 2010 Messages : 570 ![]() |
Pour moi la notion de temporaire signifie que l'on n'a rien en base.
A quoi te servent les paniers temporaires et sauvegardés ? Un client a la possibilité de sauver plusieurs paniers et les recharger par la suite ? Le panier temporaire est rechargé si le client quitte le site et revient dessus ? Si oui, effectivement le fonctionnement est pas mal. Dans ce cas tu peux alors ajouter un champs dans client (0,1) qui correspond à l'ID du panier temporaire. De même pour l'adresse principale. Et du côté des paniers et des adresses tu sais à quel client ils appartiennent puisque dans la table tu as l'id du client.
__________________
Le Porc est un loup pour le Porc. |
|
|
00
|
|
|
#6 | ||
![]() ![]() |
Citation:
La seule "contrainte" est que si le client change d'adresse principale, il faut passer l'ancienne adresse de mainAddress = 1 à mainAddress = 0. Un trigger fait ça sans problème. Citation:
Au passage, il est d'usage de nommer les tables au singulier, tout comme les entités types dans le MCD.
__________________
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 ! |
||
|
00
|
|
|
#7 |
|
Membre émérite
![]() Tony Développeur .NET Inscription : novembre 2010 Messages : 570 ![]() |
C'est tout de même moins contraignant, je pense, d'ajouter des clés étrangères dans client pour l'adresse principale et le panier temporaire.
Au niveau des contraintes on a directement la contraint d'unicité sans trigger. Et au niveau des deux tables ça fait une info de moins, il vaut mieux 2 champs en + par client et 1 en mois par adresse et panier sachant qu'on peut avoir plusieurs adresses et paniers.
__________________
Le Porc est un loup pour le Porc. |
|
|
00
|
|
|
#8 |
![]() ![]() |
Sauf qu'on retombe sur le schéma de départ et donc l'association à cardinalités (1,1 - 1,1) que tu critiquais dans ta première réponse !
__________________
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 ! |
|
00
|
|
|
#9 |
|
Membre émérite
![]() Tony Développeur .NET Inscription : novembre 2010 Messages : 570 ![]() |
Absoluement pas !!!
ça donne deux relations Client possède 0 ou 1 Panier temporaire (adresse principale) Client possède 0 ou n Paniers (adresses)
__________________
Le Porc est un loup pour le Porc. |
|
|
00
|
|
|
#10 |
![]() ![]() |
C'est une relation (0,1)-(1,1), un client qui n'a pas fait de commande n'a pas de panier, un client qui n'a pas encore renseigné d'adresse n'a pas d'adresse principale.
Il suffit que les clefs étrangères de la table clients possèdent la propriété NULL.
__________________
Email : http://scr.im/waldar |
|
10
|
|
|
#11 |
![]() ![]() |
A -0,1----associer----1,1- B => clé étrangère dans B !
Et les clés étrangères nullables, c'est mal !
__________________
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 ! |
|
00
|
|
|
#12 |
|
Membre émérite
![]() Tony Développeur .NET Inscription : novembre 2010 Messages : 570 ![]() |
Je ne suis pas non plus un spécialiste SQL, mais il me semble que ce que Waldar a écrit correspond à ce que je pensais.
Après est-ce mal ou non une clé étrangère nullable, je ne sais pas, peut être mais alors je suis preneur pour que l'on m'explique. Ta relation, selon ma vision des choses, est un mélange des 2 relations nécessaires. Le fait de posséder un panier temporaire (ou une adresse principale) est une relation Le fait d'appartenir à un client en est une autre. Par contre effectivement, pour être adresse principale (ou panier temporaire) d'un client, il faut lui appartenir, il faut tenir compte de cette contrainte.
__________________
Le Porc est un loup pour le Porc. |
|
|
00
|
|
|
#13 |
![]() ![]() |
Je ne vois pas en quoi une clef étrangère nullable serait mal, tant au niveau physique que conceptuel !
__________________
Email : http://scr.im/waldar |
|
00
|
|
|
#14 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut !
Une clef étrangère nullable c'est choquant seulement dans la mesure où NULL est choquant tout court. Ni plus ni mois.
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
00
|
|
|
#15 |
|
Invité de passage
![]() Inscription : juin 2010 Messages : 9 ![]() |
Oula, je sens qu'on s'engueule à cause de moi ><
Sinon, j'ai l'impression que le coup des relations que décrit asmduty : Client possède 0 ou 1 Panier temporaire (adresse principale) Client possède 0 ou n Paniers (adresses) revient à mon problème du début, non ? Je n'ai peut-être pas compris, mais comme j'avais prévu que l'adresse principale et le panier temporaire soient initialement à NULL, je trouvais que mon schéma fonctionnait. Mais mon souci est que je n'arrive pas à déclarer mes tables, car je ne sais pas quelle table déclarer en premier, il y a toujours une clé étrangère qui fait coincer le script. Après, peut-être que je n'ai rien compris du tout ^^ Ce que propose CinePhil marcherait aussi, mais j'aurais l'impression d'utiliser de la place en plus, sans pour autant augmenter la quantité d'information dans ma base. Bon, sinon sur les clés étrangères nullables, moi ça me choquait pas, mais je suis loin d'être un expert... |
|
|
00
|
|
|
#16 | |||
![]() ![]() |
Citation:
Ceci fonctionne avec Oracle, ça ne doit pas être loin de l'équivalent MySQL : Code :
__________________
Email : http://scr.im/waldar |
|||
|
10
|
|
|
#17 | |
![]() ![]() |
Citation:
Avec ta structure, si un client a une adresse principale et une adresse secondaire, le stockage de l'information nécessaire pour ces deux adresses, en ne prenant en compte que la partie adresse principale / adresse non principale, occupe 4 octets dans la table client pour stocker l'identifiant de l'adresse principale. Avec ma structure la même distinction entre les deux adresses occupe deux fois un octet dans la table adress, soit deux fois moins d'octets. En terme de place, ton modèle ne devient avantageux qu'à partir de 5 adresses pour un client. Quelle proportion de clients auras-tu avec plus de 4 adresses ?
__________________
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 ! |
|
|
00
|
|
|
#18 |
![]() ![]() |
Mais il ne pas oublier le coût du trigger qui vérifie qu'il n'y a qu'une seule adresse principale par client !
__________________
Email : http://scr.im/waldar |
|
00
|
|
|
#19 |
![]() ![]() |
Le trigger n'intervient qu'à l'insertion ou à la mise à jour mais ne prend pas de place en terme de stockage de données.
__________________
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 ! |
|
00
|
|
|
#20 |
|
Invité de passage
![]() Inscription : juin 2010 Messages : 9 ![]() |
Bon, finalement je crois que je vais faire comme Waldar l'a expliqué, en ajoutant les contraintes après la création des tables. Merci Waldar !
Merci beaucoup aux autres aussi, notamment CinePhil, tu m'as appris pas mal de choses ;-) (je ne connaissais pas du tout la taille des clés étrangères). |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com