JeuWeb - Crée ton jeu par navigateur
Dénormaliser les relations 1:1 ? ... - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Dénormaliser les relations 1:1 ? ... (/showthread.php?tid=4380)

Pages : 1 2


Dénormaliser les relations 1:1 ? ... - Domz - 30-09-2009

Bonjour à tous,

Faut il dénormaliser les relations 1:1 pour augmenter les performances de sa base de données ? Pour améliorer le confort de conception ?


Après une recherche infructueuse de personnes dans le même questionnement que moi, je vais l'expliquer sous forme d'exemple.

Imaginons un jeu de course de voiture par navigateur. Dans ce jeu nous aurions comme élément logique (nos objets) :

- compte du jeu (identifiant, mails, question secrète... : 7 champs différents)
- personnage joueur (le nom du personnage, compétences de conduite, nombre de cheveux... : 12 champs au total )
- voiture (nom, couleur, caractéristiques de la voiture,... : 23 champs)
- ressources (dollars, euros, nombre de bidon d'huile... : 10 champs)
- etc (544 champs)

Dans notre modèle conceptuel de donnée ces objets sont liés par des relations 1:1 : Un compte_jeu n'a qu'un seul personnage unique, une seule voiture unique, un seul ensemble de ressource propre.

Donc monsieur Merise nous encouragerait à tout mettre dans la même table :
Table_information_joueur (identifiant, mail, question_secrete, ..., nom_personnage, age_personnage, competence_personnage, nombre_cheveux, ..., nom_voiture, couleur_voiture;..)

Ce qui va nous donner une table unique avec un nombre conséquent de colonnes.


Faut il dénormaliser le modèle pour répartir les objets logiques dans différentes table, malgré leurs relations 1:1, pour réduire le nombre de colonne de chaque table ?

Solution 1 : tout dans une table : les requêtes deviennent elles coûteuses ? Quelle nombre de colonne il serait idéal de ne pas dépasser ?

Solution 2 : ensemble logique : une table par objet (une table personnage, une table voiture, une table ressource, etc). Tant mieux pour la clarté dans le développement et tant pis pour la normalisation ?

Solution 3 : hybride des précédentes : on essaye de regrouper un maximum les tables pour limiter les dégâts et ne pas dépasser un certains nombre de colonne, tout en gardant une volonté de rester au maximum dans la normalisation ? (Une table compte_jeu + ressource, une table personnage+voiture...)

Autre ?


Que pensez vous qu'il est plus sain d'adopter ? Quel est l'équilibre à avoir entre performance de la BDD et confort de conception lorsqu'on se retrouve avec des structures de tables très denses ?


RE: Dénormaliser les relations 1:1 ? ... - pascal - 30-09-2009

Hello,

Dans cette situation, je découperai en domaines fonctionnels, en me posant aussi la question :
est-ce qu'un jour il pourrait y avoir plusieurs Xxx (voitures par joueur, comptes en banque pour les ressources, personnage par compte joueur...)

A+

Pascal


RE: Dénormaliser les relations 1:1 ? ... - Allwise - 30-09-2009

Si on est sûr que ce schéma de relations restera figé à jamais, je ne vois guère l'utilité d'éclater le schéma en plusieurs tables.
Je ne pense pas qu'une requête qui tape sur une seule table soit plus coûteuse qu'une requête avec jointures. Dans le premier cas de figure il n'y a qu'un seul parcours de tables, dans le second il y en a plus, donc davantage d'accès disques. Du moment que, lorsque tu as besoin d'une partie des données, tu ne fais pas un SELECT *, ça ne changera pas grand chose en fait.
De même pour les update, dans le premier cas de figure tu ne mets à jour qu'une table.
Bien que des entités se distinguent clairement, je serais pour tout garder dans une même table : moins de code à écrire, a priori plus logique ( si on s'en réfère à ce que dit Mr Merise Smile ).
Au pire, tu peux créer des vues si tu préfères travailler sur plusieurs entités différentes ( ça fait une autre solution mixte ).


RE: Dénormaliser les relations 1:1 ? ... - wild-D - 30-09-2009

+1 pascal

la normalisation à pour objectif d'éviter les redondance et d'assurer l'intégrité des données. Ce qui a un certain intérêt pour l'optimisation "fonctionnelle" (après tout une requête sur un index d'une table c'est sensé aller plus vite que des jointures 1:1 superflues).

Mais il faut pas oublier que dans la pratique tu n'auras pas toutes les combinaisons possible et imaginable de requêtes; tes requêtes en écriture/lecture vont indiqué les regroupements favorables.

le manuel mysql, dis max 4096 colonne dans une table et aussi 64kb par lignes (edit: ?j'ai un doute, me semble avoir balancé en bdd des blob des truc plus gros que 64k?). Ce qui force à limiter le nombre de colonnes.

si tu utilise une table myisam, ça signifie des lock table en écriture, ça peut être très vite un goulot d'étranglement sur une table unique est volumineuse.

sans compter les possibles évolutions (modification probable de ton modèle).


RE: Dénormaliser les relations 1:1 ? ... - QuentinC - 30-09-2009

Perso je séparerais quand mêm les données personnelles/de connexion du reste. Je ferais ça au cas où dans une version future du jeu, plusieurs univers parralèles seraient disponibles... ou dans ton exemple, une possibilité pour le joueur de jouer avec plusieurs personages à la fois sans pour autant que ce soit du multicompte.
Ca peut aussi être pratique pour intégrer facilement un forum à tout ça, pour ne pas être obligé de se connecter 2 fois.

Maintenant si tu es certain qu'un personnage sera toujours associé à une et une seule voiture, je ne vois pas de raison de sséparer ces deux choses dans des tables différentes.


RE: Dénormaliser les relations 1:1 ? ... - Plume - 30-09-2009

Sauf erreur de ma part, ce n'est pas du tout ce que Merise te conseillerait de faire. J'ai plutôt l'impression que tu as une mauvaise compréhension de la normalisation des données.

Vois si ça ne peut pas t'aider : http://plumeconception.olympe-network.com/blog/index.php?post/2009/09/18/Organisation-des-donnees-dans-les-tables


RE: Dénormaliser les relations 1:1 ? ... - Domz - 30-09-2009

Le titre est confus, il ne s'agit pas de normalisation en effet. Dans l'exemple le "tout dans une table" est en 3FN, mais au même titre que "tout dans des tables séparés".

En revanche il s'agit de savoir si il faut suivre rigoureusement, ou pas, le processus pour passer d'un MCP à un MPD dans le cas de nombreuses relations (1,1). Enfin j'espère que je ne dis pas de bêtises °°

Je vois que les avis sont plutôt partagés. Mais je trouve notamment l'argument de wild-D sur le lock des tables avec myisam très pertinent.

En tout cas merci pour vos réponses.


RE: Dénormaliser les relations 1:1 ? ... - naholyr - 01-10-2009

Sauf que son argument sur les locks est plutôt contre la séparation Wink

Cas "tout dans une table" :
Écriture : table lockée.
Lecture : pas de jointure, bien faire gaffe aux champs dans le select.
Cas "3 tables" :
Écriture : la table concernée est lockée, mais pas les 2 autres (ça semble cool).
Lecture : il faut faire deux jointures pour lier les 3 tables, donc de toute manière si une des trois tables est lockée c'est bloqué.

Avec 3 tables en myIsam tu as plutôt 3 fois plus de chances d'être locké pendant tes requêtes, donc ça me semble plutôt être un argument contre la séparation en plusieurs tables.

Perso, je pense que toute la question est de savoir s'il y a un intérêt réel à séparer les données. Cette question peut se résumer à « ma relation 1-1 sera-t-elle à tout jamais une relation 1-1 ou risque-t-elle d'évoluer en 0-1 ou 1-n ? ». Si tu n'est pas sûr à 100% de la stabilité de ta structure, la séparation en plusieurs tables peut sembler la bonne solution car le jour ou tu veux changer ta relation tu n'auras quasiment pas à toucher à ta base.
Mon avis est cependant différent : de toute manière si tes relations changent, il faudra recoder une bonne partie de l'applicatif, donc déplacer quelques champs ne pèsera pas bien lourd dans cette évolution. Donc autant partir de l'idée que ça ne changera pas.
Dans ce cas, je serais partisan d'aplatir les données pour t'éviter des jointures qui, si elles sont simples au départ, risquent de devenir pénibles quand tu auras des requêtes plus lourdes.

Enfin une question : comment tu concrétises une relation 1-1 dans une base de données ?


RE: Dénormaliser les relations 1:1 ? ... - christouphe - 01-10-2009

Personnellement, et je viens de lire les post, deux choses me surprennent:

* Premièrement au niveau des locks: pourquoi ne pas utiliser des tables InnoDB pour s'éviter les locks de tables entière ? J'ai travaillé avec une table rassemblant TOUTES les information d'une application de 60 champs (ou c'est peu), même en passant par un script d'administration PHP, si la table était lockée, et bien je ne pouvait pas mettre à jour les données correctement.

* Deuxièmement, naholyr demande comment représenter une relation 1:1 dans une table, je pense qu'en mettant une contrainte Fk de la table 2 sur la table 1 traduirait bien la chose, en effet, pour une ligne de la table 1 donnée, il ne pourra y avoir en face une seule ligne sur la table 2, enfin c'est ma vision.


RE: Dénormaliser les relations 1:1 ? ... - naholyr - 01-10-2009

Une FK d'une table A vers une tables B (A.B_id pointe B.id) représente une relation 1-n classique (ou « 1 to 0..* ») : pour une ligne B tu as n (≥ 0) lignes A.
Si on ajoute un index UNIQUE sur cette FK, on ne pourra plus avoir 2 lignes A pointant vers la même ligne B : on a toujours une relation 1-n mais avec n ≤ 1. Dans ce cas on a donc une relation qu'on pourrait appeler « 1-1 » mais en détaillant ça reste du « 1 to 0..1 ».

Je ne trouve pas de représentation concrète (hors utilisation de triggers) en base de données d'une relation « 1 to 1..1 », et c'est ce qui me fait pencher aussi vers l'aplatissement des données, pour une simple question de garantie de la cohérence des données au niveau du schéma.


P.S: dans tous les cas +1 pour InnoDB.