CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[DB] Simplification table "en double"

Caletlog
Caletlog
Niveau 10
10 août 2014 à 23:32:38

Hey,

Je bosse actuellement sur un petit projet et réalise donc quelques diagrammes pour la conception de la base de données, mais je bloque un peu sur un morceau en particulier.

Pour simplifier puisque c'est seulement un morceau de la base (légende : les tables sont entre _Underscores_, et les idées transmises par certaines relations 'entre single quotes'.)

- Un _Utilisateur_ a un 'avis' sur un _Element_.
- Cet 'avis' est un choix parmi une liste d'_Avis_, chacun ayant un certain nombre d'infos fixes complémentaires (d'où la nécessité d'une table _Avis_).
- Ayant besoin de la date à laquelle 'l'avis' a été mis pour une analyse temporelle, j'utilise une table _aPourAvis_ avec un champ date (entre autres).
:d) On a donc, de ce côté là de la base, une triple relation _Utilisateur_, _Element_ et _Avis_, reliée par la table _aPourAvis_.
Cardinalités : Un _Utilisateur_ peut avoir (0,N) relations d'avis. Un _Avis_ peut correspondre à (0,N) relations, et un élément peut être jugé par (0,N) relations. Une relation _aPourAvis_ a une cardinalité de (1,1) envers les 3 autres tables.

Maintenant, de l'autre côté de la base, j'utilise une structure similaire mais beaucoup plus simple : un _Evenement_ est jugé par un _Avis_ (donc relation directe entre les deux _Evenement_ (0,1) <--> (0,N) _Avis_). Un _Avis_ est totalement identique à celui de la partie précédente ; mais, et c'est là que mon problème arrive, les "titres" des avis sont différents pour cette relation. J'ai les mêmes équivalences : l'élément 1 a, dans les deux cas, tous ses champs identiques (je me sers de valeurs stockées dans les _Avis_ pour faire des graphes), seul son champ "titre" est différent (par exemple, un _Avis_ positif de niveau 1 signifiera "Gentil" dans la première relation et "Utile" dans la seconde, puisqu'on ne traite pas de mêmes types d'éléments (c'est un exemple)).

Du coup, il est stupide de faire deux tables équivalentes à la table _Avis_ pour ces deux relations. Mais, du coup, je suis bloqué par ce problème de noms stockés dans la table. Je ne peux pas les délocaliser de la table pour les utiliser 'en dur' dans mes vues, puisque je vais avoir besoin de les réutiliser très souvent ; il faut donc que ces noms soient stockés dans le modèle.

Existe-t-il un patron de conception qui permet de résoudre typiquement cette situation ?

Désolé si la solution paraît simplissime, mais je bosse sur cette base gargantuesque depuis trop longtemps pour avoir du recul pour des solutions simples, je crois :o))

Merci.

Caletlog
Caletlog
Niveau 10
10 août 2014 à 23:37:20

Okay, je viens de réaliser que y'avait peut-être pas besoin d'autant détailler, ça a du plus embrouiller qu'autre chose.

Donc, version courte :
J'ai deux relations différentes qui doivent puiser dans une table _Avis_. Les deux relations ont des besoins parfaitement semblables au niveau des champs de cette table, mis à part pour le champ 'titre', qui est différent suivant que l'_Avis_ est "tiré" depuis une des deux relations.

La solution de facilité serait d'avoir deux tables _Avis_, mais je me retrouve avec un doublon parfait, sauf pour un seul champ, ce qui semble stupide.

lisarael
lisarael
Niveau 13
10 août 2014 à 23:53:51

Mets les infos particulières dans ta table de relation, avec une colonne de type qui spécifie le type de relation et donc son remplissage.

vava740
vava740
Niveau 10
11 août 2014 à 00:09:50

Je suis pas sûr d'avoir tout saisi donc je m'avance pas pour les suggestions... bon tu me diras c'est pas l'heure à laquelle je suis le plus apte à modéliser mentalement une base de données. :hap:

Bref si tu dis que t'as fais un diagramme, ça peut aider aussi. :o))
Ou les create table qui vont bien, éventuellement.

deepblue
deepblue
Niveau 16
11 août 2014 à 09:40:43

Tu peux utiliser un inheritance pattern (héritage) de table. Voila comment Propel le propose : http://propelorm.org/docuumentation/08-inheritance.html

L'idée dans ton cas sera de conserver une table AVIS avec les relations entre les différentes données de ta base avec la notion de date, puis de créer des tables pour le stockage des titres. Tu devras aussi ajouter une class_key dans la table AVIS pour savoir de quelle "sous-table" tu fais référence : la classe_key, dans propel, est le nom du modèle PHP à utiliser pour hydrater les données.

vava740
vava740
Niveau 10
11 août 2014 à 10:53:09

Si t'utilises PostgreSQL y'a une notion d'héritage native qui peut peut-être t'intéresser.

http://www.postgresql.org/docs/9.1/static/ddl-inherit.html

Sinon de façon plus standard, je pense à la structure suivante, mais la façon dont tu organises tes données dépend aussi beaucoup de la façon dont tu vas les utiliser, donc selon le contexte c'est peut-être pas le plus adapté...

element
- id pk
- ...

event
- id pk
- ...

user
- id pk
- ...

element_review
- element_id -> element(id)
- review_id -> review(id)
- title
- pk (element_id, review_id)

event_review
- event_id -> event(id)
- review_id -> review(id)
- title
- pk (element_id, review_id)

review
- id pk
- user_id -> user(id)
- ...

« pk » représentant une clé primaire et « -> » une contrainte de clé étrangère.

Caletlog
Caletlog
Niveau 10
11 août 2014 à 11:31:27

Hop, merci pour toutes vos réponses :)

lisarael > je suis pas sûr de tout comprendre. Une fois que j'ai spécifié le type, comment je récupère les infos qui changent (donc le titre) en fonction dudit type ? Je le stocke dans une table à part, avec seulement les titres et un 'lien' vers le type de la table précédente ?
Précision : j'ai une table de relation pour la première partie, mais pour la seconde partie (événement - avis) qui est une relation directe, j'ai pas de table supplémentaire de relation.

vava740 (1) > Pour l'instant c'est tout dans mon bloc-notes et j'ai pas de scanner :o))
Je bidouille un modèle rapide sur AnalyseSI si tu veux.

deepblue > hum, donc si je comprends bien, c'est le même genre de solution que celle de lisarael ? (ou ce que j'ai compris de celle de lisarael ?)
Sinon j'aurais du préciser, je pars sur l'ORM ActiveRecord de Rails. Mais la base du pattern est intéressante à exploiter, merci.

vava740 (2) > de ce que je vois, ça revient à dissocier le titre d'un avis des autres infos de cet avis, puisque tu stockes le titre dans la table de relation, non ? Donc au final on se retrouve avec pas mal de redondance de données j'ai l'impression, étant donné qu'un titre, dans une relation ou l'autre, a toujours les mêmes infos statiques (mis à part le titre) (exemple type d'une entrée _Avis_ : 1 (id), "Gentil"/"Utile" (titre), 0 (bool : mélioratif), 50 (points), ...)

vava740
vava740
Niveau 10
11 août 2014 à 11:57:45

Si tu dis que le titre est justement le seul truc qui change (pas tout compris, j'imagine que un coup c'est un varchar(32) et l'autre c'est un varchar(64) not null par exemple, donc ça oblige à avoir deux définitions de colonne différente selon « d'où vient la relation »), c'est bien justifié d'avoir un titre **différent** dans la table de relation plutôt que d'avoir titre_1 et titre_2 dans la table review.

Toutes les données qui sont agnostiques de la relation (tout sauf le titre donc) se retrouvent sans problème dans la table review.

« Les deux relations ont des besoins parfaitement semblables au niveau des champs de cette table, mis à part pour le champ 'titre', qui est différent suivant que l'_Avis_ est "tiré" depuis une des deux relations. »

Avec la structure que je propose, un avis **d'élément** et un avis **d'événement** partagent tous leurs champs sauf le titre, qui est dans la table de relation.

Après j'ai peut-être rien compris à ce que tu veux faire, concrètement je vois pas ce qui pousse à avoir une définition de la colonne titre différente selon d'où vient la relation.

deepblue
deepblue
Niveau 16
11 août 2014 à 11:59:41

Yep, même solution. Je donnais Propel en exemple pour illustrer de manière concrète le pattern :-) Il n'est pas très compliqué à mettre en place, la seule difficulté (largement surmontable) est cette notion de class_key, pour charger et hydrater le bon modèle.

lisarael
lisarael
Niveau 13
11 août 2014 à 13:57:41

Moi j'trouve mon explication meilleure pasqu'elle est plus courte pour dire la même chose que ce que vous avez dit. :D

Mais bref, Caletlog, mes compères ont détaillé ma réponse mieux que moi pendant mon absence :)

Caletlog
Caletlog
Niveau 10
11 août 2014 à 22:58:04

Okay, je pense avoir compris, je devrais pouvoir me débrouiller à partir de là :)

Merci bien pour votre aide :-)

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment