[Résolut] Comment liées 3 tables (ou +) entre elles?

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : [Résolut] Comment liées 3 tables (ou +) entre elles?

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 30 sept. 2011, 11:51

Oui ça évite de réfléchir trop longtemps pour arriver à oublier un truc ou deux ^^

Merci et bon codage à tous.

Cordialement

Re: Comment liées 3 tables (ou +) entre elles?

par Cyrano » 29 sept. 2011, 19:58

C'est effectivement une bonne idée de montrer le schéma de données utilisé.

J'ajoute pour ceux qui trouveront ce sujet dans la recherche d'une solution à leur problème : remarquez comment sont nommées les tables et les colonnes.
Comme je l'ai suggéré à Fre3z69, on nomme les table de la façon suivante :
  1. Un préfixe : ici, on voit « t_ », ça indique une table, s'il s'était agi d'une table relationnelle issue d'une relation n/n entre deux tables, alors j'aurais utilisé le préfixe « r_»
  2. Un nom significatif pour la table;
  3. Un suffixe sous la forme d'un « trigramme » si possible significatif, ça aide aussi à se retrouver. Ce suffixe servira de préfixe à toutes les colonnes de la table.
Quant aux colonnes :
  1. Un préfixe : correspond au suffixe de la table d'origine. Ça signifie donc d'une clé étrangère portera son nom d'origine, si vous regardez dans la table t_presentation_pre, la clé étrangère men_id s'identifie visuellement grâce à ce préfixe qu'elle hérite de sa création dans la table t_menu_men;
  2. un nom significatif indiquant le contenu de la colonne.
Quelques avantages de ce système :
  • On sait pratiquement tout de suite à quelle table correspond une clé étrangère;
  • On peut utiliser pour la partie « nom significatif » des mots qui d'ordinaire sont réservés tels que « date », « sum» ou tout autre mot clé du langage SQL sans le moindre risque;
  • On peut simplifier certaines jointures en utilisant NATURAL JOIN sans clause ON, la clé primaire d'une table étant strictement le même que la clé étrangère de l'autre table.
Voilà, ce sont des conventions relativement courantes, mais à mon avis largement sous-utilisées. Je sais qu'il est difficile d'espérer ramener ceux qui ont déjà depuis longtemps pris de mauvaises habitudes d'en changer, mais que tous les débutants s'inspirent de ça, ils en retrouveront tout le bénéfice tout au long de leur vie de développeur :)

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 29 sept. 2011, 14:01

Voici ci dessous une image générée par dbdesigner4, permettant de mieux comprendre comment les tables sont liées

Image

Cordialement

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 28 sept. 2011, 14:08

Bonjours à tous

Donc avec l'aide de Cyrano, j'ai pu traiter mes données comme je le souhaitais.

J'ai appris sur le coup à utiliser différentes sorte de jointures.

J'ai mit le script final, avec les commentaires permettant de suivre ce qui s'y passe, sans pour autant détailler les requêtes sql.

Je me suis aider de dbdesigner4 pour comprendre comment mes tables menu et présentation étaient liées.
J'ai pu grâce à Cyrano et dbdesigner4, n'avoir qu'une seule table pour les menus et les sous-menu, en mettant une clef étrangère ayant pour nom men_id_parrent et pour valeur, celle de men_id du menu auquel elle est liée.

Voici donc le script:
<?php
/* *** */ //si dans la liste des choix, on sélectionne Modifier:
if (!empty($_POST['Modifier']))
{
// on sécurise les données
$Id=$_POST['id'];
$Menu=$_POST['Menu'];
$Menu=mysql_real_escape_string(htmlspecialchars($Menu, ENT_QUOTES));
$MenuUrl=$_POST['MenuUrl'];
$Menu=mysql_real_escape_string(htmlspecialchars($MenuUrl, ENT_QUOTES));
//on séléction les présentations 
	$sql2="SELECT * FROM t_presentation_pre WHERE men_id='".$Id."'";
	$req2=mysql_query($sql2) or die(mysql_error());
	$nb_menus2 = mysql_num_rows($req2);
	{
		if ($nb_menus2 == 0)
		{
			echo '<p>aucune présentation à modifier</p>';
		}
		else
		{
			while ($query2=mysql_fetch_assoc($req2))
			{
			mysql_query("UPDATE t_presentation_pre SET men_id='".$Id."' WHERE men_id='".$query2['men_id']."'") or die (mysql_error());
			echo '<p>la présentation à bien été modifiée</p>';
			}
		}
	}
//On sélectionne les items qui ont men_id_parent à null
$sql  = "SELECT
  p.men_name  AS Menu,
  p.men_url   AS MenuUrl,
  t.men_name  AS SousMenu,
  t.men_url   AS SousMenuUrl
FROM `t_menu_men` AS p
  LEFT OUTER JOIN `t_menu_men` AS t ON p.men_id = t.men_id_parent
WHERE p.men_id IN (
  SELECT m.men_id
  FROM t_menu_men m
  WHERE m.men_id_parent IS NULL
)
ORDER BY p.men_id, t.men_id ASC";
//On exécute le script
	$req=mysql_query($sql) or die(mysql_error());
	$query=mysql_fetch_assoc($req);
	{
		//une fois que l'on c'est assuré que tout va bien, on update
		mysql_query("UPDATE t_menu_men SET men_name='".$Menu."', men_url='".$MenuUrl."' WHERE men_id='".$Id."'") or die (mysql_error());
		echo '<p>Le menu à bien été modifié</p>';
	}
/* Info */ //On a pas besoin de récupérer les sous-menus, étant donnée qu'ils sont déjà liées au menu par men_id_parent  /**/
}
/* *** */ //Si on a cliquer sur oui pour supprimer les données
elseif (isset($_POST['oui']))
{
$Id=$_POST['Id'];
//requête de suppression des présentation appartenant à un menu ou à un sous-menu choisi 
$sqlpre= "DELETE FROM t_presentation_pre 
WHERE men_id IN(
    SELECT men_id
    FROM t_menu_men 
    WHERE men_id_parent='".$Id."'
)
   OR men_id='".$Id."'";
//on Supprime =les présentations liées au menu par men_id, afin qu'il n'y est pas d'items orphelin dans la base de données
$sql=mysql_query($sqlpre) or die(mysql_error());

//requête de suppression des sous-menus appartenant à un menu choisi 
$sqlsmen= "DELETE FROM t_menu_men 
WHERE men_id_parent='".$Id."'";
//on supprime les sous-menus appartenant à un menu choisi 
$sql=mysql_query($sqlsmen) or die(mysql_error());

//requête de suppression du menu choisi 
$sqlmen= "DELETE FROM t_menu_men 
WHERE men_id='".$Id."'";
//on supprime le menu choisi
$sql=mysql_query($sqlmen) or die(mysql_error());
//on le signale a l'utilisateur (ici l'administrateur du site web ...)
	echo 'Les informations ont bien étaient effacés<p><a href="index.php">Terminer</a></p>';
}
/* *** */ //si on à cliquer sur non
elseif (isset($_POST['non']))
{
	//on signale à l'utilisateur que la demande à était annulée
	echo 'Demande d\'effacement annulée<p><a href="index.php">Terminer</a></p>';
}
/* *** */ //si dans la liste des choix, on sélectionne Effacer:
elseif (!empty($_POST['effacer']))
{
$Id=$_POST['id'];
//on fait une demande de vérification avant de supprimer le menu voulu
?>
Confirmez vouloir effacer ce menu?
<br />
<span style="color:#ff0000">!!! Cette action effaceras tous les sous-menus et toutes les présentations liés au menu choisit !!!</span>
<form action="index.php?g=modifmenu" method="post">
	<input type="hidden" name="Id" value="<?php echo $Id; ?>"/>
	<input type="submit" name="oui" value="oui"/>
	<input type="submit" name="non" value="non"/>
</form>
<?php
}
/* *** */ //on, dans la liste des menus, sélectionner un menu:
elseif (isset($_GET['id']))
{
//on va, dans la base de données, sélectionner le menu (x)
	$sql="SELECT * FROM t_menu_men WHERE men_id='".$_GET['id']."'";
//on exécute le script
	$req=mysql_query($sql) or die(mysql_error());
//on affiche le formulaire permettant de modifier ou supprimer le menu
	$query=mysql_fetch_assoc($req); //pas besion de while, il n'y a que un seul menu, ayant pour men_id $_POST['Id']
	{
?>
<span style="color:ff0000;">Les champs avec * sont obligatoires</span>
<form name="formulaire" action="index.php?g=modifmenu" method="post">
	<table style="border:1px #ff0000 solid;width:800px;">
		<tr>
			<td><span style="color:#ff220b;font-weight:bold;">Nom du Menu</span><span style="color:ff0000;"> *</span> : <br />ex: Les Térasses en Béton</td>
			<td><input type="text" value="<?php echo $query['men_name']; ?>" name="Menu" maxlength="22"></td>
		</tr>
		<tr>
			<td><span style="color:#ff220b;font-weight:bold;">Nom de l'url</span> : <br />ex: terasseenbeton</td>
			<td><input type="text" value="<?php echo $query['men_url']; ?>" name="MenuUrl" maxlength="22"></td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="submit" value="Modifier" name="Modifier" class="Créer">
				<input type="hidden" value="<?php echo $query['men_id']; ?>" name="id" />
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="submit" value="Effacer" name="effacer" />
			</td>
		</tr>
	</table>
</form>
<?php
	}
}
/* *** */ //si on a pas encore choisi de menu
else
{
//On liste les menus
$sql  = "SELECT m.men_id,m.men_name
  FROM t_menu_men m
  WHERE m.men_id_parent IS NULL";
//on exécute le script
	$query = mysql_query($sql) or die(mysql_error());
	//on compte les données
	$nb_menus = mysql_num_rows($query);
	//si il y a des données
	if($nb_menus > 0)
	{
		echo '<p>Choisissez le titre à modifier</p>';
		echo '<p><span style="font-weight:bold;color:#ff0000">Attention!</span> <span style="color:#0000ff">Modifier le menu choisit modifie aussi ses dépendances.</span></p>';
		//on liste les menus
		while ($statut = mysql_fetch_array($query))
		{
			echo '<p>
			<b>Titre</b>: <a class="menubleu" href="index.php?g=modifmenu&id='.$statut['men_id'].'">'.$statut['men_name'].'</a>
			</p>';
		}
	}
	//si il y a aucune données
	else
	{
		echo 'Aucun menu n\'existe.<br /><br /><a href="index.php?g=creatmenu">Créer un Menu</a>';
	}
}
//fin
?>
Merci à Cyrano pour l'aide apportée

Bon courage et bon développement à tous

Cordialement

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 25 sept. 2011, 11:44

La table présentation contient les information saisies pas l'utilisateur afin de présenter ce qu'il souhaite et l'afficher sur le site, lors du clique sur le "bouton" dans le menu, par le quel il est rattaché

Si tu crée un Menu qui ce nome Menu1
Tu créer une page de présentation liée au Menu1
Lors du clique de l'utilisateur sur Menu1 dans le menu du site, la page créer précédemment seras alors affichée.

Est cela que tu souhaitais savoir?

Merci

Re: Comment liées 3 tables (ou +) entre elles?

par Cyrano » 25 sept. 2011, 11:03

Salut,
je voudrais être sûr : sommairement, ta table Presentation contient dans ses colonnes le contenu des pages et les tables Menu et SousMenu ne contiennent que les urls et les éléments permettant de construire l'arborescence du menu de navigation, c'est ça ?

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 25 sept. 2011, 02:14

C'est lié par LienUrl qui prend la valeur de l'Url du Menu ou du SousMenu auquel il est attaché.
Il ne peux y avoir qu'un lien par présentation, même si il peux avoir plusieurs présentations ayant la même url.

J'ai fait exprès de les liés de cette manière, car déjà à l'époque je ne connaissait pas les requêtes multi-tables, et de plus, ça me semble beaucoup trop difficile de déterminer si l'Id du lien, (nommé ici LienId) a pour valeur l'id du menu ou du SousMenu, sachant que chacun auras forcement des valeur commune, comme par exemple MenuId:1 - SousMenuId:1.

Pour faire au plus simple, j'ai dit que la table Présentation seras appelée pour afficher les valeurs que quand on affiche l'url $_GET['s'] ayant la même valeur.

Mais toute fois il est vrai que si 2 SousMenu (ou +) on la même valeur textuel, il y a conflit.

J'aimerais bien refaire cette liaisons, mais je ne sais pas comment procéder.

Que me proposerais tu de faire et comment déterminer si il s'agit d'un lien avec un Menu ou d'un lien avec un SousMenu?

merci de ton aide

Cordialement

Re: Comment liées 3 tables (ou +) entre elles?

par Cyrano » 25 sept. 2011, 01:54

Je ne suis pas certain de ce que tu veux obtenir, mais j'ai un doute sur ta compréhension de ce qu'est la jointure.

Ce qu'il faut comprendre : la jointure établit comment sont reliées les données d'une ligne d'une table données aux lignes d'une autre table. Là, tu ne sembles pas trop avoir suivi les recommandations que je t'ai faites en matière de clés primaires et de clés étrangères, ça te faciliterait pourtant considérablement la vie. Par ailleurs, il faut impérativement éviter de lier des tables par des données dites « signifiantes », donc des colonnes avec des valeurs susceptibles d'être modifiées ou supprimées pour les besoins fonctionnels de l'application : tu dois utiliser des clés primaires et étrangères indépendantes des données qui sont traitées dans l'application.

Nous avons là trois tables. Je vois assez bien comment sont reliées Menu et SousMenu, mais je m'interroge sur le lien de l'une ou l'autre avec Presentation et comment sont reliées les colonnes d'url LienUrl avec MenuUrl ou SousMenuUrl... :-k . Là, je crois qu'il est important que tu t'arrêtes un moment sur les concepts de modélisation de base de données. Et comme je l'ai mentionné à diverses reprise sur ces forums, il faut partir du besoin fonctionnel. Qu'est-ce que tu veux obtenir, comment souhaites-tu que ça fonctionne pour l'utilisateur : à ce stade, oublie le code, il faut commencer par structurer tes données de façon cohérente. Or ça devrait justement être clair pratiquement rien qu'en observant les tables de ta base, ce qui n'est pas encore le cas.

Re: Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 25 sept. 2011, 01:18

J'ai tester une requête en espérant que ça soit bon
mysql> SELECT
    ->  m.Menu,
    ->  m.MenuUrl,
    ->  t.SousMenu,
    ->  t.SousMenuUrl,
    ->  p.LienUrl
    -> FROM `Menu` AS m
    -> LEFT OUTER JOIN `SousMenu` AS t ON m.Id = t.MenuId
    -> LEFT OUTER JOIN `Presentation` AS p ON p.LienUrl = m.MenuUrl OR p.LienUrl
 = t.SousMenuUrl
    -> ORDER BY m.Id, t.Id, p.Id ASC;
+--------+---------+-----------------+----------------+----------------+
| Menu   | MenuUrl | SousMenu        | SousMenuUrl    | LienUrl        |
+--------+---------+-----------------+----------------+----------------+
| Menu 1 | menu1   | Menu1SousMenu 1 | Menu1SousMenu1 | menu1          |
| Menu 1 | menu1   | Menu1SousMenu 1 | Menu1SousMenu1 | Menu1SousMenu1 |
| Menu 1 | menu1   | Menu1SousMenu 2 | Menu1SousMenu2 | menu1          |
| Menu 2 | Menu2   | NULL            | NULL           | NULL           |
+--------+---------+-----------------+----------------+----------------+
4 rows in set (0.01 sec)
Cela semble être ce que je souhaite avoir, mais, a la 3eme ligne, on a menu1 affiché dans LienUrl alors qu'aucune présentation n'est faite pour cette ligne

Est-ce bien comme ça qu'on écrit la requête, ou y a t'il une erreur?

Merci de votre aide

Cordialement

Re: Comment liées 3 tables (ou +) entre elles?

par Cyrano » 24 sept. 2011, 18:32

Un autre tuto sur les jointures, beaucoup plus basique que celui néanmoins excellent de developpez.com

Le tuto est basé sur deux tables, mais si tu en comprends le fonctionnement, ça marchera aussi bien pour trois, quatre voire douze ou vingt tables, même si il est vrai que plus tu auras de liaisons, plus ce sera complexe pour obtenir des résultats vraiment pertinents.
Le tuto commence avec une manière de faire en établissement les liaisons dans la clause WHERE, mais il termine en montrant comment faire des jointures normalisées, comme je te l'ai du reste montré en privé ;)

Ce que tu as fait avec une seule table, c'est également une jointure, mais vu qu'il n'y a qu'une seule table, on appelle ça une auto-jointure et on doit impérativement utiliser des alias. La, il est bon d'en utiliser aussi selon les cas, ça reste une bonne habitude et on a du code plus clairement lisible.

Prends aussi l'habitude d'écrire tes requêtes de façon à en faciliter la lecture, tant pour les autres que pour toi-même.
Exemple, au lieu de faire :
CREATE TABLE SousMenu (Id int(13) UNIQUE AUTO_INCREMENT, MenuId int(13) UNSIGNED, SousMenu mediumtext, SousMenuUrl mediumtext, MenuMenu mediumtext, PRIMARY KEY (Id));
Tu peux faire :
CREATE TABLE SousMenu (
  Id          INT(13) UNIQUE AUTO_INCREMENT,
  MenuId      INT(13) UNSIGNED,
  SousMenu    MEDIUMTEXT,
  SousMenuUrl MEDIUMTEXT,
  MenuMenu    MEDIUMTEXT,
  PRIMARY KEY (Id)
);
Mets les mots-clés en majuscule et utilise une indentation : comme tu peux voir, c'est beaucoup plus clair et tu vois immédiatement de quoi peut avoir l'air ta table.

Je te suggère de voir le tuto mentionné, de faire ensuite quelques essais, et, si tu as des difficultés, de nous montrer ici ce que tu as fait, ce que tu attendais comme résultat et ce que tu as obtenu à la place, on repèrera rapidement où tu auras fait une erreur.

[Résolut] Comment liées 3 tables (ou +) entre elles?

par Fre3z69 » 24 sept. 2011, 15:27

Salutation à tous

Je suis actuellement, en train de travailler sur un script permettant d’effacer en même tant, un menu et toutes les dépendances attachés à ce dernier.

C'est à dire, que mon menu comporte un ou plusieurs sous-menus, et que le menu "parent" et le ou les sous-menus peuvent avoir chacun une ou plusieurs présentations.

De ce faite, j'ai besoin que ma requête vérifie avec même temps tout cela, et supprime les dépendance et le menu.

J'ai vu un tutoriel sur les jointures multiple tables, mais j'y comprend rien dés que il y a plus de 2 tables.
Tutoriel

Voici à quoi ressemble mes tables

Création de la table Présentation
CREATE TABLE Presentation (Id int(13) unique auto_increment, Login mediumtext, Numero mediumtext, Titre mediumtext, Contenu mediumtext, Name mediumtext, LienUrl mediumtext, PRIMARY KEY (Id));
Création de la table Menu
CREATE TABLE Menu (Id int(13) unique auto_increment, Menu mediumtext, MenuUrl mediumtext, PRIMARY KEY (Id));
Création de la table SousMenu
CREATE TABLE SousMenu (Id int(13) unique auto_increment, MenuId int(13) unsigned, SousMenu mediumtext, SousMenuUrl mediumtext, MenuMenu mediumtext, PRIMARY KEY (Id));
On voit que j'ai liée la table Présentation avec LienUrl qui correspond à l'url du menu ou sous-menu auquel elle est rattachée.
J'ai pas mit de "MenuId" dans la table de présentation, car j'ai trouver ça plus complexe, étant donnée que je n'affiche la page en question que si l'URL* est égale à $LienUrl. *exemple: index.php?u=LienUrl

Sinon la table SousMenu est liée au menu parent par MenuId et MenuMenu
Dans ce cas je me sert de Id pour ressortir les sous-menu rattachés au menu et les affichées
Lien de l'aide précédente posté ici même

Merci de votre aide, en espérant que j'ai bien posté ma demande.

Cordialement