begin process at 2010 02 10 03:49:29
  Trouver un code source :
 
dans
 
Accueil > Forum > 

SQL

 > 

MySQL

 > 

Divers

 > 

Conception de BDD: relation n-n


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Conception de BDD: relation n-n

vendredi 3 octobre 2008 à 18:39:36 | Conception de BDD: relation n-n

leica69

Bonjour,
je souhaiterais concevoir une BDD mais avant d'attaquer j'aurais une question à vous poser.

En simplifiant, voici ma situation:
Je veux mettre en relation une table de médicaments et une table de propriétés (antitussif, expectorant, ...)

t_medicaments{
   medic_id
   medic_nom
}

t_proprietes{
   prop_id
   prop_nom
}

Chaque médicament a plusieurs propriétés.
Chaque propriété peut être exercée par plusieurs médicaments.
On se trouve donc dans une relation n-n

Quel est, d'après vous, le meilleur moyen de mettre en relation ces deux tables?
A/ Créer une 3ème table liant les 2 premières?
t_relations{
   relation_id
   relation_medic_id
   relation_prop_id
}

ou

B/ Ajouter à la table médicaments un autre champ qui aurait une sorte de "array" des prop_id qui lui correspondent?
t_medicaments{
   medic_id
   medic_nom
   medic_proprietes
}

pour obtenir qqch du genre:
   medic_id     medic_nom     medic_proprietes
   1                  aspirine            ['1';'32']
   2                  medicChose     ['22';'32']
   3                  medicTruc        ['43';'1']

Si je prends l'option B, pour trouver les médics ayant la propriété 23, je devrais faire un
SELECT * FROM t_medicaments WHERE 'medic_proprietes' LIKE '23'

Je n'ai jamais travaillé avec l'option B. Selon votre expérience, quelle méthode est préférable, pratique, conviviale???

Merci pour vos futurs conseils.
Antonio

PS: j'ai par erreur posté ce même message dans un autre forum, mea culpa.
vendredi 3 octobre 2008 à 22:57:20 | Re : Conception de BDD: relation n-n

nhervagault

Administrateur CodeS-SourceS
Salut,

La solution 1 est la plus recommandée et est en 3ieme forme normale
(la relation_id n'est pas trop utile)



une raison des plus contraignantes est le CRUD de ta table

exemple pour l'ajout d'une propriété tu es obligé de faire des operations de string
pour la mise à jour et suppression idem

on extrait on fait des operations (split de la chaine difficile a faire en SQL il faut utiliser un langage de prog pour) et on insert c'est pas tres propre

Ensuite pour faire des jointures tu feras comment

exemple ecrire la fiche de l'aspirine
tu dois faire un select * from properties where prop_id in(['43';'1'])
ca marche pas il faudrait avoir
select * from properties where prop_id in('43','1')

Les jointures sont plus facilement optimisable par l'optimiseur SQL, il chosit l'ordre des filtres et des jointures en fonction de la taille des tables

Donc apres cette demonstration, je pense que tu partiras sur la version 1

Les bases de données il faut le retenir sont faite pour faire du travail ensembliste et non du travail sur des chaines de caractères

Bon SQL
jeudi 9 octobre 2008 à 18:57:01 | Re : Conception de BDD: relation n-n

leica69

Merci pour cette réponse bien complète!
J'ai commencé à développer ma BDD. J'ai toutefois encore une question sur l'utilisation des "tables de jointure" (je ne sais pas si c'est la bonne dénomination)

Prenons un autre exemple, plus culinaire:
Une table ingredients:
1 | farine
2 | oeufs
3 | sucre
4 | sucre de canne

...

Une table recettes
1 | cake
2 | muffin
3 | flan

...

Une table de jointure, qui détermine les ingrédiens utilisés pour chaque recette:
// La recette 1 utilise les ingrédients (1, 2 et 4)
1 | 1
1 | 2

1 | 4

// La recette 2 utilise les ingrédients (2 et 3)
2 | 2
2 | 3

Si je vois juste, jusqu'ici ma table de jointure aura 5 lignes, cette table deviendra rapidement asses grande...

Je vois tout à fait comment récupérer les ingrédients par recette et les recettes utilisant les ingrédients (SELECT ... WHERE ingredient='2')

Là où je coince, c'est pour l'enregistrement d'une nouvelle recette. J'aurai un formulaire avec le nom de la recette et tous les ingrédients avec un case à cocher. Après validation du formulaire, je devrais avoir une nouvelle ligne dans la table de jointure correspondant à chaque case cochée. L'idée qui me vient à l'esprit est de faire une requête de ce type avec une boucle:

$requete = "SELECT id FROM recettes ORDER BY 'id' DESC LIMIT 1";
$resultat = mysql_query($requete);
$ligne = mysql_fetch_array($resultat);
$derniere_recette_ajoutee = $ligne['id'];

$nouveau_numero_de_recette = $derniere_recette_ajoutee + 1;

for ($i=1;$i<=nombre d'ingrédients;$i++){
   if($["ingredient_".$i] == 1){
      INSERT INTO table_jointure (recette, ingredient) VALUES (
$nouveau_numero_de_recette,$i)";
   }
}


Ca m'a l'air assez lourd, y aurait-il un moyen plus simple?????
Ca devient encore pire si je dois mettre à jour une requette, là, je suis perdu.

Si vous pouvez m'aider, je vous en saurai bien reconnaissant.

Antonio


jeudi 9 octobre 2008 à 21:26:11 | Re : Conception de BDD: relation n-n

nhervagault

Administrateur CodeS-SourceS
Salut,

C'est assez simple en fait,

Prenez par exemple un combobox ou select en html

Tu stockes la cle de l'ingredient dans la value de l'option
et tu connais la cle de ta recette

ensuite a l'enregistrement tu inseres
une ligne avec l'id de ta recette et la value de chaque ligne

Donc si tu as 3 cases cochées tu auras 3 insertions
le probleme est la mise à jour et la suppression d'un ingrédient

Il faut stocker la liste courante et faire un diff
pour savoir les nouveau et les detruit
et ensuite gerer en fonction les INSERT et les UPDATE

Il y a peut etre mieux.

jeudi 9 octobre 2008 à 23:02:20 | Re : Conception de BDD: relation n-n

leica69

La clé de la recette je ne la connais pas à la base, vu que mon "id" est auto-incrémenté, d'où mes 5 premières lignes de code:
$requete = "SELECT id FROM recettes ORDER BY 'id' DESC LIMIT 1";
$resultat = mysql_query($requete);
$ligne = mysql_fetch_array($resultat);
$derniere_recette_ajoutee = $ligne['id'];

$nouveau_numero_de_recette = $derniere_recette_ajoutee + 1;

Mais comment faire le diff de manière efficace sans avoir trop de lignes de code inutiles??

"..ensuite gerer en fonction les INSERT et les UPDATE". Ca serait pas plutôt Insert et Delete? Si on supprime un ingrédient pour une recette, il faut supprimer la ligne correspondante dans la table de jointure? Je ne vois pas l'utilité d'un update.

Est la boucle je je propose dans mon précédent post te paraît cohérente?
jeudi 9 octobre 2008 à 23:23:57 | Re : Conception de BDD: relation n-n

nhervagault

Administrateur CodeS-SourceS
Oui pour la boucle mais pour recuper
l'id c'est pas bon

Il faut utiliser dans la requete d'insertion en meme temps

insert ....() values();
select  last_insert_id();

et tu auras l'id venant d'etre inserer

oui
c'est des delete et des inserts
il faut charger dans une collection et apres comparer avec la collection initial et la collection final pour faire un merge.




jeudi 9 octobre 2008 à 23:31:05 | Re : Conception de BDD: relation n-n

leica69

Je ne connaissais pas "last_insert_id()". Je vais potasser ça.

Merci
vendredi 31 octobre 2008 à 19:05:04 | Re : Conception de BDD: relation n-n

leica69

Bonjour,
je tenais encore à vous dire merci pour vos conseils. Je n'ai pas encore fini le développement, mais la partie d'administration est presque terminée. En tout cas, ça fonctionne bien, c'est efficace et bien pratique.

J'aurais peut-être bientôt une autre question, mais je dois cogiter avant, histoire de ne pas poser trop rapidement une question à laquelle je pourrais trouver une réponse par moi-même en réfléchissant un peu...

Encore merci.
vendredi 31 octobre 2008 à 19:40:04 | Re : Conception de BDD: relation n-n

nhervagault

Administrateur CodeS-SourceS
C'est bien ce raisonnement.

Bravo

Bon courgae


Cette discussion est classée dans : table, id, relation, proprietes, medic


Répondre à ce message

Sujets en rapport avec ce message

if dans une procédure stocké ? [ par jesusonline ] Bonjour, je ne connais pas encore SQLj'ai une table articles qui a un champ ID et je voudrais une fonction stocké qui prend en paramètre un ID et qui Selectionner les lignes dont un champ apparait plusieurs fois [ par bluebird_29200 ] Bonjour a tous ! sur la table reservations client_id  |  transaction_id je cherche a faire ressortir les client_id dont le nombre d'apparitions dep requete croisement de table [ par sdisp ] Bonjour, je souhaiterais pouvoir croiser des ligne dans mon tableau, je expliques, j'ai une table de se genre: id id_suivant référence 1 3 10 2 1 1 Problème de requête à double jointure ... HELP ! [ par vladam ] Hello,Voici mon problème.J'ai une table "Table_3" avec 3 champsle premier ID numériquele deuxième ID2 numériquele troixième ID3 numériquej'ai une seco une requete qui me casse la tête [ par chmouette ] Salut les gens!Mon problème est purement SQL. J'ai une table Ma Table avec des champs tels que :+-------------------------+ !            MaTable  &nbs auto increment [ par bob ] Bonsoir ! Alors voila, j'ai une question qui va etre surement trés simple pour vousvoila le sql de mla table CREATE TABLE `blogs` ( `id` smallint(6) requête sur le résultat d'une requête [ par sev622 ] Bonjour, J'ai un problème dans la construction de ma requête. J'ai une table avec 2 champs numériques : id_p, id_f Je veux compter le nombre d'id_p qu erreur 1785 [ par sev622 ] Bonjour, Je crée des tables avec pas mal de foreign key et j'ai l'erreur suivante :Serveur : Msg 1785, Niveau 16, État 1, Ligne 1L'introduction d'une help pour requete SQL [ par lenneth666 ] Voila j'ai une table avec les champs suivants : ens_id form_id mat_id annee_id nb ens_id,form_id et mat_id sont une clé composé de cette table. La INSERT a l'id qu'on vient de DELETE [ par Bassman ] Voila j'aimerais savoir sous mysql comment forcé l'insertion dès le "départ", c'est a dire, par exemple dans votre table utilisateur vous venez d'en s


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,312 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales