Conseil d'amelioration PHP/Mysql
Je dois améliorer une partie d'un site internet, Kadolis.
Surtout la partie qui concerne les packs.
Je m'explique, Kadolis propose des Packs. Les Packs sont eux même des produits qui contiennent des options. Les options sont eux aussi des produits...
Par exemple le site propose des chambres de bébé donc une chambre est un produit qui elle même contient d'autre produits par exemple : un lit, une commode ect...
Cependant lorsqu'une chambre est vendue, le stock est bien décrémenté d'une chambre sauf que les options doivent être modifié manuellement dans le stock.
Il faudrait une solution lors du paiement de la commande, pour gérer tout le stock automatiquement.
Grâce à une boucle qui recherche les produits en fonction de leurs id et qui fait un UPDATE de la quantité a chaque fois.
En regardant le site et plus particulièrement la partie chambre de bébé, pouvez-vous me dire si vous voyez des améliorations a faire.
Pour une meilleure visibilité, pour gérer plus facilement les packs ?
http://www.kadolis.com/chambre_bebe_ch [...] -1-c2-89.html
site en php4, sgbd est phpmysql
Tout et n'importe quoi de constructif serait d'une grande aide pour moi...
Je vous remercie
29 réponses
La discussion porte sur la gestion des packs chez Kadolis, où un pack contient des produits et des options, et où le stock des options n’est pas mis à jour automatiquement lors de la vente. Des réponses suggèrent de clarifier le modèle relationnel (MCD/MLD) et d’implémenter des tables comme PRODUIT, COMPOSE et INCLUT, avec une gestion du stock réel dans PRODUIT et un statut de commande pour ajuster le stock. Plusieurs contributions insistent sur le suivi du statut des commandes (en cours, traité, annulé) pour ajuster le stock réel, et proposent une table dédiée pour lier produits englobants et englobés, avec éventuelle récursivité. En complément, il est noté qu’une mise à jour du stock lors d’une commande ne s’effectue pas forcément sur une quantité unique, et qu’il faut cibler les quantités en fonction des composants et du statut.
-
ContributeurOui voilà, c'est ça l'idée et c'est déjà ce que j'avais dis un peu plus haut. Comme quoi il faut tout lire, ça évite de perdre du temps ;)
~ N'oubliez pas la balise "Résolu" lorsque votre problème est... résolu :) ~ -
Donc si j'utilise simplement la table INCLUT avec préalablement l'ajout des produits qui compose une commande dans la table en fonction des choix du clients :
//Ajout d'une commande
$prix_total_calcule = '1500';
mysql_query ("INSERT INTO COMMANDE ( Com_id, Prix_total_calculé, client_id ) VALUES ( NULL, '".$prix_total_calcule."', '')");
//Ajout des produits de la commande
if(isset($_GET['optionNum']) && $_GET['optionNum'] > 0) {
for($i=1; $i<=$_GET['optionNum']; $i++) {
$opt1 = explode("/",$_GET['option'][$i]);
$optionList[] = $opt1[0].(($opt1[3]=="")?"":" - ".$opt1[3]);
$priceMod[] = $opt1[1];
$optionPoids[] = $opt1[2];
$optionRefs[] = $opt1[3];
$optionachat[] = $opt1[4];
}
}
$updatePrice = array_sum($priceMod);
echo $updatePrice."<br/>";
$ref = $optionRefs[1];
echo $ref."<br/>";
$ref = "CSG-B";
$req_id = mysql_query("SELECT products_id FROM products WHERE products_ref = '".$ref."'");
while ($row = mysql_fetch_array($req_id)) {
echo $row['products_id']."<br/>";
mysql_query("INSERT INTO INCLUT ( Com_id, products_id, Quantite, Prix) VALUES ( '15', '".$row['products_id']."', '1', '0 + ".$updatePrice."')");
}
J'ai testé ça marche.
Pour ensuite gérer la défalcation simplement comme cela :
//Defalquer le stock en fonction d'une commande donnée
$id = mysql_query("SELECT products_id FROM INCLUT WHERE Com_id = '".$com_id."'");
while ($row = mysql_fetch_array ($id)) {
$qt = mysql_query("SELECT Quantite FROM INCLUT WHERE products_id = '".$row['products_id']."'");
while ($row1 = mysql_fetch_array ($qt)) {
$up = "UPDATE products SET products_qt = products_qt - (".$row1['Quantite'].") WHERE products_id = '".$row['products_id']."'";
mysql_query($up);
}
}
Il manque quelques trucs mais dans l'idée, ça suffirait ? Il n'y aurais pas besoin alors d'utiliser la table COMPOSE ?
La table COMPOSE ne servirait qu'a visualiser comme il faut les différents packs... -
ContributeurRe,
Sincèrement, la solution a déjà été donnée. Tu t'emmêle les pinceaux.
Comment faire pour différencier les options, en fonction des choix des clients pour que le stock soit defalquer correctement ?
Deux questions en une. Première question : comment différentier les options. Seconde question : comment défalquer correctement.
La réponse à la seconde question a été données plus haut.
La réponse à la première question est tout autre. La base de données actuelle ne permet pas de représenter les options présentables aux clients lorsqu'ils souhaitent acheter un produit.
Cette base te permet de gérer correctement ton stock (si tu te réfère et suit les réponses précédemment données), c'est déjà une chose.
Pour ce qui est de représenter les différents choix, il faut penser à refaire la base d'une autre manière, ou la modifier pour intégrer ces choix entre différents produits.
Là dessus, je sèche - pour le moment. Il faudrait à la rigueur un peu plus de précision sur la question :
- Est ce que le nombre d'option est limité, ou est ce qu'il faut prendre en compte la possibilité d'avoir beaucoup d'option.
- Est ce qu'un produit qui est une option / choix peut l'être sur plusieurs produit (exemple du tiroir B qui peut être une option pour différente armoire ou bureau par exemple)
- Comment s'organisent les options entre elle pour un même produit. Par là je veux dire : est ce que pour un produit qui présente des options, tu as des cas où c'est "je choisis entre ça, ou bien ça, ou bien ça" mais aussi "je choisis entre ça ou bien ça ou bien ça ET ça ou bien ça) (plusieurs choix d'option lié au même objet)
Je pense qu'en répondant à ces questions tu avancera déjà un peu vers la solution à mettre en place.
-
Bonjour,
J'ai implémenté une fonction défalquerStock qui utilise la table produit et la table COMPOSE pour deflaquer le stock.
<?php
function defalquerStock($idproduit,$quantite){
$return="fonction defalquer\r\n";
$query = mysql_query("SELECT products_qt, products_id, products_sold
FROM products
WHERE products_id = '".$idproduit."'");
$row = mysql_fetch_array($query);
if($quantite !== 0 && !($row===false)) {
$aaa = $row['products_qt']-$quantite;
if($aaa<0)$aaa=0;
$bbb = $row['products_sold']+$quantite;
$updateStock = mysql_query("UPDATE products
SET
products_qt = ".$aaa.",
products_sold = ".$bbb."
WHERE products_id = '".$row['products_id']."'");
if($updateStock===false)$return.="\t\tstock produit non defalque\r\n";
else $return.="\t\tstock produit defalque\r\n";
}
$q = mysql_query( "SELECT Slave_id, Nombre FROM COMPOSE WHERE Master_id = '".$product_id."'" );
while( $row = mysql_fetch_assoc( $q )){
defalquerStock( $row['Slave_id'], $row['Nombre'] * $quantite );
}
}
?>
Par contre il subsiste un problème. Car dans la table COMPOSE il y a le produit Master et le produit Slave correspondant. Mais un client va choisir une chambre par exemple mais différentes options vont se présenter a lui : entre une commode 3 tiroirs et une commode 2 portes, 1 tiroir.
Donc dans la table COMPOSE il y aura : par exemple
Master Slave
530 526
530 527
530 : produit_id chambre
526 : commode 3 tiroirs
527 : commode 2 portes, 1 tiroir.
Comment faire pour différencier les options, en fonction des choix des clients pour que le stock soit defalquer correctement ?
Il faut surement utiliser la table INCLUT. Et je pensais faire un truc comme ça :
Code : PHP
<?php
$q = mysql_query( "SELECT Slave_id, Nombre FROM COMPOSE WHERE Master_id = '".$product_id."'" );
$q1 = mysql_query(SELECT products_id FROM INCLUT WHERE Com_id = "'.$Com_id."'");
while( $row = mysql_fetch_array($q)){
while ( $row1 = mysql_fetch_array($q1){
if ($row['products_id'] == $row1['Slave_id']){
while( $row = mysql_fetch_assoc( $q )){
defalquerStock( $row['Slave_id'], $row['Nombre'] * $quantite );
}
?>
Fait correspondre le bon products_id choisi par le client contenu dans la table INCLUT avec celui de la table COMPOSE.
Mais c'est un peu tiré par les cheveux, y'a surement une solution plus optimale...
Merci,
Tibo -
ContributeurSalut,
Dans ce cas oubli tous ce que je t'ai dis et repars de 0. Tu ne pourras pas faire ce que tu souhaites avec ce que je t'ai donné.
Pourquoi ? Parce que la table COMPOSE est là pour représenter le lien entre les produits. L'information concernant le stock n'y est pas présente, et d'ailleurs comment l'inclure dans cette table ? Ce n'est pas possible.
Défalquer c'est bien beau, mais de la manière dont tu souhaites le faire c'est défalquer de 1 uniquement à chaque fois, a moins d'avoir l'information comme quoi tu dois pour telle commande défalquer de 3 et non 1 seul sur tel type d'objet (par exemple trois tiroirs B compris dans la commode C)
Bon courage pour la suite, et si tu trouve une solution adéquat, n'oublie pas de la poster ici, ça pourra toujours aider à l'avenir, ou ne serait-ce que pour moi, pour pouvoir aiguiller plus correctement la prochaine fois.
++
-
J'ai bien compris le système... Mais en faite il faut que j'arrive a défalquer le stock en utilisant la table COMPOSE.
En appelant cette fonction de manière récursive, pour pouvoir défalquer tous les produits contenus dans le pack...
function defalquerStock($idproduit,$quantite,$options=""){
$return="fonction defalquer\r\n";
$query = mysql_query("SELECT products_qt, products_id, products_sold
FROM products
WHERE products_id = '".$idproduit."'");
$row = mysql_fetch_array($query);
if($quantite !== 0 && !($row===false)) {
$aaa = $row['products_qt']-$quantite;
if($aaa<0)$aaa=0;
$bbb = $row['products_sold']+$quantite;
$updateStock = mysql_query("UPDATE products
SET
products_qt = ".$aaa.",
products_sold = ".$bbb."
WHERE products_id = '".$row['products_id']."'");
if($updateStock===false)$return.="\t\tstock produit non defalque\r\n";
else $return.="\t\tstock produit defalque\r\n";
}
Et aussi utiliser la table INCLUT pour les quantités des différents produits ! -
ContributeurHum, c'est ce que je t'ai expliqué un peu plus haut justement.
Ta base de données te sert à plusieurs choses:
- modéliser le lien entre les différents produits (via la table COMPOSE). Ce lien possède une quantité, mais attention, ce n'est qu'une quantité fixe non représentative du stock, elle est là pour dire : cet objet est composé de tant de cet autre objet (pour chaque objet qui le compose, ou que lui-même compose)
- représenter le stock réel des produits (via la table PRODUIT). La table PRODUIT comprend une quantité, qui elle reflète le nombre de produit en stock réel pour chacun des produits enregistré dans la base de données.
- enregistrer les commandes clientes (via la table COMMANDE et INCLUT). La table COMMANDE permet de symboliser la commande, la table INCLUT permet de faire le lien entre la commande elle-même, et les produits commandés pour cette commande. Il y aura donc autant de lien dans la table 'INCLUT' que de différent type de produit commandé dans une commande. La table INCLUT possède une quantité qui représente le nombre d'exemplaire d'un produit commandé. En aucun cas il ne représente le stock réel, mais uniquement un nombre commandé (non encore retiré du stock, selon où en est bien sur la commande : attention, ce que je dis là entre ces parenthèses dépends d'un choix de gestion de la mise à jour du stock à faire, expliqué plus bas)
A partir de là, il apparait une chose que tu n'as pas encore pris en compte pour bien gérer ton stock : savoir si une commande a été traitée ou non.
Pourquoi cette notion est importante : pour la simple et bonne raison que puisque dans la table PRODUIT tu as la quantité en stock réel de chaque produit, si tu souhaites pouvoir ajuster ce stock réel (donc cette quantité) de manière à savoir à n'importe quel moment si un produit est en stock ou non (selon les commandes passées - qu'elle soient en cours de traitement ou déjà traitées), il faut alors savoir le statut des commandes.
Ainsi, ton stock réel sera défalqué lorsqu'une commande passe en statut 'traitée' par exemple. Si bien que lorsqu'un client souhaite commandé un produit (et les produits qui le composent), il te faudra calculé s'il reste ou non en stock ces produits, en fonction du stock "réel", et les commandes passées qui ne sont pas encore "traitées" : ceci est logique, puisque tu ne vas pas autoriser un client à commander quelque chose qui virtuellement est encore en stock (dans la table PRODUIT) mais réellement est en rupture de stock (parce qu'il y a déjà plus de commande passées et non traitée que de produit en stock)
Attention : j'ai dit qu'un le stock d'un objet doit être défalqué lorsqu'une commande passe en statut 'traité', mais il faut bien noté qu'il s'agit d'un choix de gestion à choisir selon ce qui te semble le plus judicieux !
Je serai toi, j'ajouterai trois valeur possible sur le statut d'une commande : 'en cours', 'traité' et 'annulée'.
Ainsi, tu défalque la quantité de produit directement lorsqu'une commande est créer (statut 'en cours' donc). Et à chaque changement de statut de la commande, tu ajuste le stock. Par exemple, pour une commande en cours, le stock des produits commandés ayant été déjà défalqué (ce qui permet d'avoir une image en base du stock réel beaucoup plus juste en temps réel et évite de faire des calculs dans les scripts), si la commande est validée (statut 'traité'), ce stock ne changera pas. Par contre, si la commande est annulée, alors il faudra remettre le stock à niveau, en ajoutant les produits de la commande au stock réel (puisque ces produits seront à nouveau disponible)
ps: Au risque de me répéter, la table COMPOSE est surtout là pour tout ce qui attrait à la présentation des produits (et sous produits) aux clients lorsqu'ils souhaitent visualiser les produits, et les commander.
En espérant que cela t'ai donné une vision un peu plus clair de ce que ta base de données représente et permet de faire.
~ N'oubliez pas la balise "Résolu" lorsque votre problème est... résolu :) ~ qu -
Bonjour,
J'ai mis en place un bout de code qui permet de défalquer automatiquement le stock pour une commande donnée :
En utilisant que la table INCLUT et PRODUIT :
$id = mysql_query("SELECT products_id FROM INCLUT WHERE Com_id = '12'");
while ($row = mysql_fetch_array ($id)) {
$qt = mysql_query("SELECT Quantite FROM INCLUT WHERE products_id = '".$row['products_id']."'");
while ($row1 = mysql_fetch_array ($qt)) {
$up = "UPDATE products SET products_qt = products_qt - (".$row1['Quantite'].") WHERE products_id = '".$row['products_id']."'";
mysql_query($up);
}
}
C'est normal que je n'utilise jamais la table COMPOSE pour défalquer ?
Elle me sert a rien dans ce cas la !
Parce que j'ai l'impression que ce code marche pour n'importe quelles commandes... Y'a un truc qui m'échappe ? -
Ok c'est bien ce que je pensais !
j'ai fait un bout de code qui tend vers la solution générale :
//COMMANDE d'un client d'une Chambre Bebe Childwood Country Stone Grey
/* Commode 3 tiroirs
Matelas TENCEL
Lit 60-120 */
//inserer chambre dans la table INCLUT
$inser1 = mysql_query("INSERT INTO INCLUT ( Com_id, products_id, Quantite, Prix) VALUES ( '12', '530', '1', '1499')");
$inser2 = mysql_query("INSERT INTO INCLUT ( Com_id, products_id, Quantite, Prix) VALUES ( '12', '526', '1', '40')");
$inser3 = mysql_query("INSERT INTO INCLUT ( Com_id, products_id, Quantite, Prix) VALUES ( '12', '529', '1', '0')");
$inser4 = mysql_query("INSERT INTO INCLUT ( Com_id, products_id, Quantite, Prix) VALUES ( '12', '221', '1', '0')");
$sel = mysql_query("SELECT products_id FROM INCLUT WHERE Com_id = '12'");
for ($i=0; $i<("SELECT COUNT(*) FROM INCLUT WHERE Com_id ='12'"); $i++){
$row = mysql_fetch_array ($sel);
$up = "UPDATE products SET products_qt = products_qt -1 WHERE products_id = '".$row[$i]."'";
}
Donc j'ai ajouté tous les produits correspondant a une chambre dans la table INCLUT qui lie COMMANDE a PRODUIT.
Et ensuite je voulais defalquer le stock; a chaque itération faire un UPDATE de la quantité du produit un tel (en fonction de son id).
Mais ça a pas l'air de marcher.... Déjà est-ce une bonne méthode pour défalquer le stock ? ou faut t-il procéder autrement ? Et je n'arrive pas a trouver l'erreur que j'ai commise, si il y en a une !-
ContributeurOui c'est la bonne façon de faire, mais une erreur s'est glissée:
Dans ta requête d'update du stock pour chaque produit lié à une commande, au niveau de la quantité à défalquer, ce n'est pas toujours 1. La preuve, certaines quantité sont à 0 dans tes requête d'insert dans la table 'INCLUT', et tu laisse à -1 lorsque tu défalquer.
A un moment donné tu vas avoir un problème d'intégrité de ta base de données, les chiffres / les calculs sur les champs désignant les stocks ne correspondront pas à ce qu'il y a réellement en stock (dans la réalité)
Donc dans ta requête d'update, il faut défalqué de la quantité de l'item (pas juste de 1 fixe):
Qui plus est, ton code est quelque peu érroné au niveau du traitement effectué pou défalquer.
Fais comme ça plutôt:
$sel = mysql_query("SELECT products_id, Quantite FROM INCLUT WHERE Com_id = '12'"); while ( ($line = @mysql_fetch_array($sel)) != null ){ $up = "UPDATE products SET products_qt = products_qt - ".$line[1]." WHERE products_id = '".$line[0]."'"; }
-
-
ContributeurSalut,
DELETE ON CASCADE, comme l'instruction l'indique, permet de faire du DELETE en cascade en cas de suppression d'une valeur dans une table (ainsi que les valeurs auxquelles elle est la rattachée dans d'autres tables - éventuellement.
Du moins c'est comme ça que je le comprends, je ne l'ai jamais utilisé pour autant.
Pour faire de la mise à jour d'un champ d'un produit (ton stock dans ton cas) et le répercuter sur les sous produits, il faut simplement faire comme je te l'ai déjà indiqué dans un des post plus haut (par rapport au fait que ce qu'un client commande se trouve dans la relation 'PASSE' entre 'COMMANDE' et 'PRODUIT', et qu'à partir de ces informations, tu peux défalquer le nombre en stock de chacun des produits)
Je ne pense pas que tu puisse automatiser ce genre de traitement au même titre qu'un DELETE ON CASCADE, mais j'avoue ne pas m'y connaitre suffisamment en instruction SQL pour l'affirmer réellement.
-
Bon j'ai un petit soucis..
J'ai remplit les nouvelles tables que j'ai créées pour faire des tests.
Je voudrais que quand un produit master est défalquer tous les produits slaves qu'ils contient le soient aussi. Je pensais qu'avec les relations entre les tables avec DELETE ON CASCADE marcherait mais ça n'a pas l'air d'être le cas.
Cependant il faut que je gère aussi le fait que le client parmi le produit master a plusieurs options.
Par exemple pour un produit master : chambre de bébé il a le choit entre :
-une commode 1 tiroir, 2 portes OU une commode 3 tiroirs.
J'ai un peu de mal a visualiser comment faire pour mettre en place la solution adéquate, pour que le stock soit défalquer correctement lors de la validation de la commande d'un client.
Par exemple cette requête :
$query4 = "UPDATE products SET products_qt = products_qt -1 WHERE products_id = '530'";
//execute requête
mysql_query($query4);
Elle défalque bien d'une unité a chaque fois le stock ! Mais que le produit master !
Que dois-je faire pour que les autres produits contenu dans l'offre (commode, lit, ...) soient eux aussi défalquer correctement de façon automatique et direct !
Merci beaucoup. -
Bon j'ai mis en place la solution suivante :
J'ai changé le moteur en InnoDB pour les différents tables :
ClientBoutique (CodeClient, Nom, Adresse, CodePostal, Ville, Tel)
COMMANDE (Com_id, Prix_total_calculé, client_id)
avec client_id => type INDEX relié a ClientBoutique->CodeClient ON DELETE CASCADE
Produit (products_id, ... , Vendable(true/false))
INCLUT (Com_id, products_id, Quantité)
avec Com_id => type INDEX relié a COMMANDE->Com_id ON DELETE CASCADE
avec products_id => type INDEX relié a Produit->products_id ON DELETE CASCADE
COMPOSE(Master_id, Master_slave, Obligatoire(true/false), Nombre)
avec Master_id => type INDEX relié a Produit-> products_id ON DELETE CASCADE
avec Slave_id=>type INDEX relié a Produit-> products_id ON DELETE CASCADE
Je me suis pas occupé encore de la table OPTION
Je pense pas que ça soit idiot ce que j'ai fait mais je sais pas du tout si c'est correct !
y'a un moyen de vérifier ? -
ContributeurMySQL ne gère pas les liens via les clefs étrangères, du moins pas dans les anciennes versions, et j'ai appris avec les anciennes.
Pour le coup il suffit juste de faire le lien toi-même de la façon suivante:
- PRODUIT, a pour clef primaire 'id_produit'
- COMPOSE à pour clef primaire le couple 'master_id' et 'slave_id'. Ces deux identifiant sont exactement du même type que 'id_produit' (puisque ce seront des id de produit). Ces deux champs forment la clef primaire (composée) de la table 'COMPOSE'.
- INCLUT, aura les champs suivants:
+ id_produit
+ id_commande
+ quantité
'id_produit' ET 'id_commande' forment à elle deux la clef primaire (composée) de cette table. Ces deux identifiant sont exactement du même type que ceux de la table 'PRODUIT' et 'COMMANDE'.
- COMMANDE, comme tu l'as déjà dit
- CLIENT, comme tu l'as déjà dit
- PASSE, contiendra les deux clef primaires héritées des tables qu'elle lie, à savoir 'id_commande' et 'id_client' (exactement de même type que ceux des tables 'CLIENT' et 'COMMANDE'
Attention : Dans les tables représentant les associations de ton MCD, les clef primaires sont généralement un couple de champs "hérité" ou représentant des identifiants d'autres tables. Autant dans les tables elle-même ces identifiants uniques sont en mode auto-increment, autant dans les tables des relations, ces identifiants ne le sont en aucun cas !
Ces tables sont là pour représenter des liens, en aucun cas ils ne doivent être créé par le gestionnaire de la base de données.
En gros, lorsque tu créé une commande, tu créera une nouvelle entrée dans la table COMMANDE, dont le champ identifiant sera généré automatiquement par le gestionnaire de la BDD. Une fois ce champ récupéré (ainsi que celui d'un produit à lier à cette commande), tu pourra alors créer une nouvelle entrée dans la table "PASSE", en stipulant les identifiants ainsi récupérés.
Dans l'interface graphique d'EasyPHP, dans l'administration de la base de données, tu as possibilité de sélectionner plusieurs champs en tant que clef primaire de la table.
Ca te semble clair ?
Dans d'autres SGBD comme Orable, où les clefs étrangères sont gérées, c'est différents par contre, tu n'as pas à créer de tables intermédiaires comme c'est le cas ici de "PASSE" par exemple.
-
Donc j'utilise pas InnoDB et la gestion des relations pour faire les relations entre les tables ?
Mais je comprend pas alors comment les relations et les contraintes de DELETE ON CASCADE, ... vont se faire ?
Et comment on fait pour que par exemple dans la table COMPOSE Master_id et Slave_id soient des clefs héritées de products_id ?
Et dans PASSE je met le même nom alors que dans COMMANDE et CLIENT cad Com_id et CodeClient ?
J'ai fait de la base de donnée essentiellement sous Oracle (j'ai un peu de mal a visualiser comment les liens se font sous phpMySQL) -
ContributeurEffectivement, j'oubliais que tu devais le faire avec la gestion de clefs étrangères pour faire des DELETE ON CASCADE.
Je t'avoue que je suis pas très à l'aise avec ce genre de truc, habituellement je fais tout par moi-même dans des scripts, c'est plus compliqué à maintenir et à mettre en place, plus susceptible aussi d'inclure des erreurs, mais je n'ai appris que comme cela. Et les bases de données, je n'en fais malheureusement pas suffisamment pour justifier une auto-formation là dessus ^^'
Libre à toi d'utiliser ce qu'il a été dit plus haut (et fait niveau MCD/MLD) pour créer ta base de données en utiliser innoDB dans ce cas.
Je serai intéressé pour le coup d'oeil d'avoir ta solution une fois faite.
-
-
J'ai un petit soucis de compréhension avec phpMySQL (c'est la première fois que je l'utilise vraiment)
Surtout pour mettre les contraintes (foreign key)
J'ai créer les tables qu'il fallait :
Client (existait déjà)
Commande (que j'ai créé) : Com_id | int(6) | Not null | auto_increment
Prix_total_calculé | decimal (8,2)
Produit (existait déjà) : products_id | int(6) | not null | auto_increment
...
Inclut (que j'ai créé) : Quantité
Compose (que j'ai créé) : Master_id, Slave id => je n'ai pas pu les mettre tous les deux en auto_increment ! Faut-il que je m'en mette aucun des deux ou un des deux ? lequel ?
Obligatoire(true/false)
Nombre
Après quelques recherches j'ai vu que pour gérer les contraintes en mode graphique il fallait mettre le moteur en InnoDB pour pouvoir voir l'onglet gestion des relations.
Donc je vois bien comment ça marche, mais si j'ai bien compris il faudrait que je rajoute des champs vide ? dans mes tables (qui ont le même nom que la clé primaire ?) qui représenterai la clé étrangère ? et après je fais le lien grâce a gestion des relations ! -
ContributeurNon, tu as deux "liens" entre "produit" et "compose". L'un symbolise le fait qu'un produit soit composé de..., l'autre symbolise le fait qu'un produit compose...
C'est ce qu'on l'on appelle une relation parent-enfant : c'est une relation sur la même entité, avec deux liens ayant chacun un sens, l'un allant de l'entité (ici "produit") vers la relation (ici "compose") et l'autre allant de la relation vers l'entité.
Tu saisie la différence ?
Si tu ne fais qu'un seul lien, comment sais-tu quel produit compose l'autre ? Et inversement ?
Ici pense bien qu'il s'agit uniquement d'un MCD, et non pas de la représentation même de ta base de données.
Dans ta base de données, tu n'auras au final qu'une seule table "compose", avec les deux champs identifiant.
Le fait qu'un identifiant se retrouve sur la première clef (master_id) signifiera qu'il est composé d'un autre produits, le fait qu'il se retrouve sur la seconde (slave_id) clef signifiera qu'il compose un autre produit.
Le MLD ne change pas cela dit, tu as raison sur ce point :) Et c'est bien le MLD qui se rapprochera donc le plus de la représentation de ta base de données.
~ N'oubliez pas la balise "Résolu" lorsque votre problème est... résolu :) ~ -
Alors plutôt comme cela :
http://www.monsterup.com/image.php?url=upload/127168216552.png
ça me parait un peu bizarre et je ne vois pas trop ce que ça change...
En tout cas le MLD reste le même non ? le même nombre de tables ? -
ContributeurBonjour,
Ton modèle n'est pas bon à un endroit :
La table "compose" n'est pas une entité en soit, mais une relation père-fil sur la table "produit" (un produit lié à un autre via la relation "compose".
Donc par rapport à ton MCD, la relation "est composé" est à supprimer / remplacer par la relation "compose" :
------------| |------------------
PRODUIT | <----- | COMPOSE
-------------| ------>|------------
Désolé pour la médiocrité du schéma, je n'ai pas accès aux sites de hosting depuis où je suis.
Mais sinon le reste est correct, good job.
Pour la création de la base de données, mieux vaut passé par l'interface graphique puisqu'elle est là pour te simplifier la tâche.
Une fois la base créée complètement, exporte ta base de données (structure complètes des tables inclues les drop if exist, etc.. + les données dites "métier")
Les données dites "métier", c'est tout ce qui est mis "en dur" dans la base de données. Dans ton cas par exemple, ce sera les options de commande. Ce n'est pas quelque chose que tu vas créer dynamiquement depuis ton site, mais quelque chose que tu insère dans la base à l'avance, une bonne fois pour toute, et qui te servira dans ton site.
Idem, les produits ne sont à priori pas créer dans ton site mais à la main, où du moins il y en a toute une tripotée qui existent déjà, donc autant les insèrer. De même pour les liens entre produits existants, à créer également avec l'exportation de ta base de données.
Exporter ta base de données au format texte (à sauvegarder dans un fichier donc), ce sera si des fois ta base crash, où du moins l'installation de ton SGBD, tu pourras toujours la recréer à partir de ce fichier de sauvegarde.
~ N'oubliez pas la balise "Résolu" lorsque votre problème est... résolu :) ~ -
J'ai conçu le MCD et le MLD correspondant :
MCD : http://www.monsterup.com/image.php?url=upload/1271673258948.png
MLD :
CLIENT (CodeClient, Nom, Adresse, CodePostal, Ville, Tel)
COMMANDE (Com_id, Prix_total_calculé, #CodeClient)
OPTION (Option_id, Option_value, Option_value_name, #Com_id)
INCLUT (#Com_id, #Products_id, Quantité)
PRODUIT (Products_id, Prix, Vendable(true/false))
COMPOSE (Master_id, Slave_id, Obligatoire, Nombre)
Je pense que les modèles sont corrects ?
Maintenant il faut que je m'interesse à la création des tables et a son incorporation propre dans la BD existante (phpMySQL).
Faut-il mieux que je le code a la main en SQL, ou que j'utilise "l'interface graphique" ?
Je vais éditer mon post au fur et a mesure que j'avancerai dans la conception des tables ... -
T'es un Dieu, j'ai bien compris je pense comment modéliser tout ça... je vais faire ça au propre.
Je viens de me rendre compte qu'il faut que j'ajoute une table Option lié a la table Commande pour les options de livraisons, ...
Par contre la table Produit en lien avec la table Compose est vraiment bien pensé.
Je te remercie vraiment sincèrement pour ton aide précieuse...
Je risque de revenir poser des questions quand j'aurais bien mit au propre ce modèle..
Mais ça sera après le weekend =)
Merci encore, kij_82.
Tibo-
ContributeurBon week-end et à lundi.
Au passage, si jamais tu n'as pas appris de méthodologie de modélisation, celle que j'utilise couramment est MERISE, petite explication ici:
https://forums.commentcamarche.net/forum/affich-37622101-merise-modele-conceptuel-des-donnees
Et des exercices pratiques:
http://www.sam-mag.com/P53,53,5,55,,,default.aspx
(Bien) Concevoir est l'une des phases les plus importantes dans une application.
-
-
ContributeurOui, il est effectivement possible de faire comme cela. Mais c'est vrai que ça complique énormément le système d'information et surtout sa bonne gestion.
J'ai repensé à un exemple concret de ce que tu es en train de mettre en place : Ikea. Es-tu déjà allé dans un magasin Idea ?
Si ce n'est pas le cas, explication : sur chaque produit vendable là-bas tu as une référence distincte. Et les caractéristiques rentrent en compte dans le produit lui-même. Exemple : un meuble noir avec trois tiroir aura une référence (ce qui correspond à ton ID dans ton cas) différente d'un meuble noir/blanc/etc. avec deux tiroirs.
Ce modèle permet de simplifier beaucoup la gestion du stock.
Appliquer à ce que tu souhaite faire, cela veut dire qu'il faut:
- lister les différentes distinction d'un produit (couleur, dimensions, etc.) et les incorporer à la table 'produit'
- avoir juste un table qui fait le lien entre les produits à coté.
Ainsi, ton MCD reste simple à gérer, mais représentera peut-être un poil plus de données dans ta base (et encore, à ce niveau là je ne suis même pas sûr !)
MCD:
PRODUIT
- id (clé primaire de la table)
...
- prix
- vendable (true/false)
COMPOSE (table de lien)
- id master
- id slave (la réunion des deux ID composent la clé primaire de la table)
...
- mandatory (obligatoire, true/false)
- number (nombre de produit slave qui compose le produit master, pour les tiroirs par exemple)
Voilà, deux tables, simple, efficace je pense.
Ca c'est pour représenter les liens entre les différents produits, et qui te permettra donc d'en gérer le stock, la modularité pour présenter les choix aux clients.
Si tu souhaites enregistrer les choix des clients, il te faudra faire une nouvelle table, 'commande' par exemple, avec ses propriétés (id, prix total calculé par rapport à ce qui est commandé), ainsi qu'une table de relation entre cette commande et l'ensemble des produits regroupés sous cette commande, qu'on nommera 'inclut' par exemple et qui comprendra en propriété l'identifiant de la commande et celui de du produit, le nombre commandé de ce produit et d'autres choses si tu en as besoin.
Ainsi, avec cette gestion des commandes, tu pourras facilement décroitre ton stock actuel par rapport à ce qui est commandé / acheté, ou inversement l'augmenter par rapport à ce qui avait été commandé s'il y a annulation de la commande. Et ça fait toujours un inventaire des commandes pour faire des statistiques sur les produits les plus achetés, etc. (ça peut toujours intéressé la boite pour laquelle tu fais ça)
Idem par la suite, tu pourra inclure une table pour les clients, ainsi qu'une autre pour lier les clients à leur commande (si c'est le veux de gestion de la boite bien sur, sinon ça ne sert à rien). Comme ça des profils pourront être plus ou moins dressés pour proposer des choses en guise de publicité aux clients enregistrés.
Pour en revenir au problème premier (le stock), je serais toi, j'opterais pour le MCD à deux tables, plus simple à gérer. Mais à choisir selon les choix de gestion de ta boite (si elle souhaite réellement gérer des couleurs ou des dimensions, ce qui m'étonnerai puisque ce n'est pas ça qui créé le chiffre d'affaire mais bel et bien le produit lui-même - non ses caractéristiques)
Désolé si mes dires passent d'un choix à l'autre, je découvre en même temps ce dont tu as réellement besoin, etc. ^^
~ N'oubliez pas la balise "Résolu" lorsque votre problème est... résolu :) ~
- 1
- 2