Bonjour, tout le monde,
J’ai une table dénommée ‘’produits ‘’ dans laquelle j’enregistre tous les produits commercialisés par une boutique et qui comporte 02 colonnes :
upload/1525448972-60115-produits.jpg
et une autre table dénommée ‘’journal’ ’qui comporte 5 colonnes, chaque ligne contient les éléments d’un journal de stock de produits comme suit :
journal
upload/1525449079-60115-journal.jpg
Je voudrais parcourir la table ‘’journal’’ à l’aide de chaque produit qui se trouve dans la table ‘’produit’’, sélectionner l’ensemble des opérations qui concernent le produit en question dans la table ‘’journal’’ et ensuite classer les résultats obtenus dans des tableaux d’affichages pour chaque type de produits comme suit :
upload/1525449156-60115-affichage.jpg
Pour parvenir à cet objectif jai essayé de lire la table avec une boucle ‘’while’’ a l’intérieur de laquelle j’introduis une requête ‘’select ‘’ afin de pouvoir y collecter les données qui devront figurer dans mes petits tableaux d’affichage. J’ai effectué cette technique elle marche mais ma table journal ne comporte qu’un petit nombre de lignes pour le moment. Maintenant je voudrais savoir lorsque que la table ‘’journal’’ comportera dans l’avenir plusieurs lignes (des centaines ou des milliers) est ce que cette méthode sera efficace, est ce qu’elle ne va pas ralentir l’exécution de mon code car j’ai appris dans plusieurs documentations que, introduire une requête dans une boucle while n’est pas conseillé.
Si la méthode que j’ai adoptée présente des risques de performance au fur et a mesure que les enregistrements de ma table augmentent dans le moyen et le long terme, quelle méthode alternative qui me mettrait à l’abris d’ennuis futurs me conseillez-vous .
Voici mon code :



<html>
<head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="" />
    </head>
	
<body>
<?php
         //connection a la base de données
    try 
         { 
         $bdd = new PDO('mysql:host=localhost;dbname=comptes','root','',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); 
         } 
    catch(Exception $e) 
         { 
          die('Erreur : '.$e->getMessage()); 
         } 
         // Compter le nombre d'enregistrements contenus dans la table produits
			      $req = $bdd->prepare('SELECT * FROM produits');   
                  $req->execute();			
                  echo $req->rowCount() . ' resultat(s)'.'<br />';
			      $nbrlignes = $req->rowCount();
                  echo $nbrlignes.'<br />';
	
	  //inialisation de la premiere ligne de la table produit 
		          $ligneproduit = 1;
				  
	    //creation de la boucle chargée d'effectuer toutes les operations
   while ( $ligneproduit <=$nbrlignes ) 
          { 
              //Selection du produit dans la table "produits" 
            $req = $bdd->prepare('SELECT * FROM produits WHERE id= :id');
		                         $req-> execute(array(
		                         'id'=> $ligneproduit,
                                 ));
		                        while ($donnees = $req->fetch())	            { 
                                	 $produit =$donnees['prdt'];
							        } 	
	         //Recherche dans la table ''journal'', l'ensemble des produits ayants comme nom 
                   $produit
					           
		 $req = $bdd->prepare('SELECT * FROM journal WHERE designation= :designation');
		                         $req-> execute(array(
		                         'designation'=> $produit,
                                 ));
                 // Creation du tableau d'affichage
								 
                                echo$produit . '<br>';// titre du tableau
								echo "<table border=\"\">"; 
                                         //entête du tableau 
                                         echo "<tr>"; 

                                         echo "<th WIDTH=100 HEIGHT= 40>Entrée</th>"; 
                                         echo "<th WIDTH=100 HEIGHT= 40>Sortie</th>"; 
                                         echo "</tr>"; 
                     //fin de l'entête 

		  while ($donnees = $req->fetch())
		             { 
                          $entree =$donnees['entree'];
			 $sortie =$donnees['sortie'];

                   echo "<tr ALIGN=center>"; 
                                      
                                         echo "<td WIDTH=100 HEIGHT= 40>".$entree."</td>"; 
                                         echo "<td WIDTH= 100 HEIGHT= 40>".$sortie."</td>"; 
                                         echo '</tr>'; 
										 
			      } 
                     echo "</table>"; 
		      echo ' </br ><br >';
                      $ligneproduit = $ligneproduit +1; 
      } 
                         $req->closeCursor();
       
?>
</body>

</html>
Merci niuxe pour le lien, mais mon anglais est embryonnaire et pour l'eau tu sais
chez nous celle du robinet est toujours potable c'est pourquoi ça se trouve pas en magasin dans les étalages
Modérateur
et l'eau = Hello....

un article sur la clef étrangère

Dernièrement, j'ai posté une réponse qui devrait t'aider à comprendre le princope de la clef étrangère. (enfin, c'est le résultat de ce principe. Pas de redondance....)

<<<EDIT
ps :
- dry
- kiss
- pep20 (en français)
EDIT;
Modifié par niuxe (04 May 2018 - 18:54)
salut,

je pense que et ta modélisation et ton code ne sont pas performants.

Pour la modélisation tu as quelque chose de très simple. Il faut te dire que dès lors que tu as une redondance de données dans une table, il devient préférable d'externaliser ces données.
C'est le cas pour ta colonne "produit" dans ta table "journal". Tu as en plus déjà une table "produit" qui liste l'ensemble des produits. Ta colonne "produit" de la table "journal" doit alors simplement avoir une référence à l'identifiant de ton produit (c'est ce qu'on appelle une clé étrangère avec dans ce cas une relation 1*n).
Tu peux voir à quoi pourrait ressembler ta modélisation.

upload/1526411086-49848-mpd.jpg

Tes données ressembleront par la suite à ça :

upload/1526411206-49848-tabbles.jpg

Ta requête s'en trouve simplifiée :

$bdd->query(
       'SELECT *
	FROM journal j
	INNER JOIN produit p
	ON p.id_produit = j.id_produit
	ORDER BY libelle_produit'
);
Dans la table produits, rajouter une colonne stock_initial, sauf si on ne fait jamais d'inventaire (c'est interdit !)
Dans la table journal, rajouter une colonne de type timestamp automatique ou datetime