IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

[SQL] Nombre de requête élevé pour un menu


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 43
    Par défaut [SQL] Nombre de requête élevé pour un menu
    Bonjour à tous,
    je développe actuellement un site personnel en PHP.
    Là je travaille sur le menu principale.
    Ce menu se compose de sous-menus, qui peuvent contenir des sous-menus, etc...
    Tous le menus est enregistré dans une table de ma base de donnée (MySql), dont voici la structure (j'ai enlevé les colonnes inutiles) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE `menu` (
      `id_menu` int(11) NOT NULL auto_increment,
      `nom_menu` varchar(100) NOT NULL,
      `ordre_menu` int(11) NOT NULL,
      `id_menu_pere` int(11) NOT NULL,
      `nb_sous_menu` int(11) NOT NULL,
      PRIMARY KEY  (`id_menu`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=52 ;
    Tout mon menu doit être placé dans un array, qui contiendra les menus, puis les sous-menus, dans des array, etc...
    Voici le code actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function sous_menu($menu_pere)
    {
    	global $BdD;
    	$sous_menu = Array();
    	$retour_sous_menu = $BdD->mysql_query('SELECT * FROM menu WHERE id_menu_pere='.$menu_pere['id_menu'].' ORDER BY ordre_menu');
    	while($donnee_sous_menu = mysql_fetch_array($retour_sous_menu))
    	{
    		if($donnee_sous_menu['nb_sous_menu']!=0)
    			$donnee_sous_menu['sous_menu'] = sous_menu($donnee_sous_menu);
    		array_push($sous_menu,$donnee_sous_menu);
    	}
    	return $sous_menu;
    }
    $menu = Array();
    $retour_menu_princ = $BdD->mysql_query('SELECT * FROM menu WHERE id_menu_pere=0 ORDER BY ordre_menu');
    while($donnee_menu_princ = mysql_fetch_array($retour_menu_princ))
    {
    	if($donnee_menu_princ['nb_sous_menu']!=0)
    		$donnee_menu_princ['sous_menu'] = sous_menu($donnee_menu_princ);
    	array_push($menu,$donnee_menu_princ);
    }
    Comme vous pouvez le voir, pour chaque sous-menus, je fais une requête SQL, et pour l'heure cette page me fais plus de 30 requêtes sql, pour m'afficher ce menu.

    Pouvez vous m'aider à améliorer ce script ?
    Merci d'avance pour vos réponse et pour votre aide.

    Information : Le fait de mettre le menu de la sorte dans un array est très important car j'utilise le template Smarty pour l'affichage de mes pages.

    EDIT :
    Descriptions des champs :
    id_menu (Id du menu)
    nom_menu (Nom a afficher)
    ordre_menu (ordre d'affichage, 1, 2, 3, etc... )
    id_menu_pere (id de menu a qui appartient ce menu, 0 pour le premier menu)
    nb_sous_menu (Nombre de sous-menu, 0 si pas de sous-menus)

  2. #2
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 505
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 505
    Par défaut
    Dans ton cas tu n'auras pas tellement le choix. A chaque niveau tu dois faire une requêtes. Je me suis retrouvé dans la même problèmatique que toi. Seul solution que j'ai trouvé qui permet de le faire en une seul requête.
    C'est d'utiliser un champs texte ayant se format.
    111
    111.111
    111.112
    111.113
    111.113.111
    112
    112.111
    Avec un champs qui à ce genre d'information il facile de savoir le niveau, la profondeur, son parent. Bref en une seul requête avec un LIKE '111.___' ou LIKE '111.%' ça permet de chercher très facilement. De pouvoir boucler sur les niveaux. Ceci avec qu'une requête SQL.
    Je ne fait rien pour générer ces chiffres je le gère automatiquement dans une procédure stocké .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 43
    Par défaut
    Je n'ai pas très bien compris comment tu as fait.

    Mais j'ai trouvé une solution, pour n'en faire qu'une seule, le problème c'est que je parcours la table en entier, pour chaque menu. Qu'est-ce qui est le mieux, faire une requête sql, mais alourdir le code php, ou faire plusieurs requêtes mais avoir un code php rapide ?

    Voici comment j'ai fait pour ceux que ça intéresse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <?php
    function sous_menu($menu_pere)
    {
    	global $BdD;
    	global $donnee_menu_p;
    	$sous_menu = Array();
    	foreach($donnee_menu_p as $donnee_sous_menu)
    		if($donnee_sous_menu['id_menu_pere']==$menu_pere['id_menu'])
    		{
    			if($donnee_sous_menu['nb_sous_menu']!=0)
    				$donnee_sous_menu['sous_menu'] = sous_menu($donnee_sous_menu);
    			array_push($sous_menu,$donnee_sous_menu);
    		}
     
    	return $sous_menu;
    }
    $menu = Array();
    $retour_menu = $BdD->mysql_query('SELECT * FROM menu ORDER BY ordre_menu');
    $donnee_menu_p = Array();
    while($donnee_menu = mysql_fetch_array($retour_menu))
    	array_push($donnee_menu_p,$donnee_menu);
     
    foreach($donnee_menu_p as $donnee_menu_princ)
    	if($donnee_menu_princ['id_menu_pere']==0)
    	{
    		if($donnee_menu_princ['nb_sous_menu']!=0)
    			$donnee_menu_princ['sous_menu'] = sous_menu($donnee_menu_princ);
    		array_push($menu,$donnee_menu_princ);
    	}

  4. #4
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 505
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 505
    Par défaut
    Je dirais qu'il est préférable d'"allourdir" le php que la base de données mais le bute c'est qu'il faut être claire lorsque tu reviens dessus ou une autre personne.
    La technique que je te proposais était de placer le plan pour chaque enregistrement.
    Exemple : 111.112.111 signifie que l'enregistrement courant est dans une deuxième profondeur. Sont parent c'est le 112 et le parent de celui-ci est 111. Bref, c'est un moyen simple de récolter des informations sur un élément hiérarchisé.
    Donc si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM maTable WHERE level LIKE '111%' ORDER BY level
    Cela va afficher tout les fils de l'élement 111 Donc
    1 : 111
    2 : 111.112
    3 : 111.112.111

    Dans le tableau que tu parcours tu peux faire tes sous menu à partir du moment ou tu change de profondeur. Là c'est facile à les détecter.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 43
    Par défaut
    Ok, là je vois comment tu veux le faire, et donc pour chaque menu tu fais une requête sql.
    Mais si je fais ça de la sorte, je vais rencontrer un autre problème (possible à réaliser, mais là aussi lourd), qui est la gestion de ce menu.
    En fait j'ai une page d'administration qui me permet d'administrer ce menu, ainsi que l'ordre d'affichage des menus, et des sous-menus.
    Ainsi pour cette exemple :
    111
    111.111
    111.111.111
    111.111.112
    111.112
    112
    113
    113.111

    Si je passe le 2ème menu en premier il ma faudra tout changer de la sorte :
    112
    112.111
    112.111.111
    112.111.112
    112.112
    111
    113
    113.111

    Je pense que tu vois où est le problème à ce niveau.

    Merci pour tes réponses.

  6. #6
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 505
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 505
    Par défaut
    C'est un risque en effet. Mais je me préocupe pas de cela. J'ai un champs ordre. C'est celle-ci que je me base. Le level permet seulement de savoir à qui est ton parent et de connaitre son origine.
    Personnellement j'ai pas terminé lorsque je fais une modificiation de menu mais c'est prévus. Comme je te le disais, je suis dans le même cas que toi. Mon cas est que ma menu peut se retrouver dans un autre sous menu. Il faut que je fasse l'algo pour cela.
    En gros c'est le principe de la taxinomie ou taxonomie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2000] Meilleure méthode pour insérer un grand nombre de lignes
    Par nicodev24 dans le forum Développement
    Réponses: 11
    Dernier message: 31/10/2016, 11h25
  2. plus de javascript aprés requéte ajax pour mon menu
    Par pouktoro dans le forum jQuery
    Réponses: 2
    Dernier message: 23/10/2009, 13h44
  3. Requête SQL dans la table utilisée pour l'état
    Par phil_klb dans le forum IHM
    Réponses: 1
    Dernier message: 22/07/2009, 20h31
  4. [SQL-SEVER2005] Gestion des erreurs pour les requêtes
    Par eagleleader dans le forum MS SQL Server
    Réponses: 22
    Dernier message: 16/10/2007, 09h59
  5. Réponses: 4
    Dernier message: 14/11/2006, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo