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

 MySQL Discussion :

Table avec multi possibilités par colonne


Sujet :

MySQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mai 2021
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2021
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Table avec multi possibilités par colonne
    Bonjour,

    J'ai beaucoup cherché mais je ne trouve pas de réponse à ma problématique, je vous pose donc la question en espérant que quelqu'un puisse m'aider.
    Je souhaite créer une base de données pour les sorts de D&D, et j'ai une problématique sur plusieurs tables.
    Certains sorts se retrouvent dans plusieurs manuels, et sont utilisables par plusieurs classes.
    Pour les autres infos j'ai la solution, mais pour ces deux cas je ne trouve pas comment faire.
    Mon idée initiale était de créer une table "sorts" avec entre autres une colonne "classes" et une "manuels" avec un id reliant le sort à une table Classes et à une table Manuels.
    Le problème étant qu'un sort pouvant être lancé par exemple par un magicien et un prêtre, je ne peux pas mettre l'idclasse du magicien dans la colonne Classes de la table Sorts, et oublier le prêtre, ni mettre l'idclasse du prêtre et pas celle du magicien.
    Y aurait-il une solution pour pouvoir renseigner plusieurs classes dans la même colonne, ou dois-je faire une table Sorts avec un booléen par classe, ce qui rallongerait mon nombre de colonnes d'une dizaine, sachant que j'aimerai par la suite préciser le niveau de sort dans la classe en question (il est possible que ce soit un sort de magicien de niveau 0, mais un sort de prêtre de niveau 2).
    Le problème est le même pour les manuels, un sort peut être décrit dans plusieurs manuels ou dans un seul, sauf qu'il n'y a pas de complication avec un niveau quelconque.

    L'objectif final étant de pouvoir faire des requêtes SELECT simples pour avoir tous les sorts d'un niveau choisi d'une classe donnée de n'importe quel manuel, par exemple, avec les informations complètes du sort, sans avoir à passer par des requêtes de 10 lignes avec des jointure à se perdre.

    Merci d'avance pour vos conseils!

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 200
    Points : 12 776
    Points
    12 776
    Par défaut
    Bonjour
    Citation Envoyé par Djad33 Voir le message
    Certains sorts se retrouvent dans plusieurs manuels, et sont utilisables par plusieurs classes.
    Si un sort peut être lié à plusieurs classes, il faut une table qui fait le lien entre les deux, avec l'Id du sort et l'Id de la classe. Idem pour les manuels.
    Citation Envoyé par Djad33 Voir le message
    Mon idée initiale était de créer une table "sorts" avec entre autres une colonne "classes" et une "manuels" avec un id reliant le sort à une table Classes et à une table Manuels.
    Mauvais plan, tu ne sauras pas si un sort est lié à une classe ou à un manuel. Essaies de créer le schéma correspondant dans un outils de modélisation, et tu verras que tu ne peux pas raisonner ainsi.
    Citation Envoyé par Djad33 Voir le message
    Y aurait-il une solution pour pouvoir renseigner plusieurs classes dans la même colonne, ou dois-je faire une table Sorts avec un booléen par classe, ce qui rallongerait mon nombre de colonnes d'une dizaine, sachant que j'aimerai par la suite préciser le niveau de sort dans la classe en question (il est possible que ce soit un sort de magicien de niveau 0, mais un sort de prêtre de niveau 2).
    Le problème est le même pour les manuels, un sort peut être décrit dans plusieurs manuels ou dans un seul, sauf qu'il n'y a pas de complication avec un niveau quelconque.
    A chaque fois que tu voudras ajouter un lien, tu devras modifier le schéma. Et je ne parle même pas des requêtes pour gérer le bousin...
    Citation Envoyé par Djad33 Voir le message
    L'objectif final étant de pouvoir faire des requêtes SELECT simples pour avoir tous les sorts d'un niveau choisi d'une classe donnée de n'importe quel manuel, par exemple, avec les informations complètes du sort, sans avoir à passer par des requêtes de 10 lignes avec des jointure à se perdre.
    Avec deux tables, une pour faire le lien entre un sort et une classe, l'autre pour faire le lien entre un sort et un manuel, tu règles tous ces problèmes. Tu peux sans problème ajouter des colonnes dans ces tables, par exemple le niveau de sort, et la requête dont tu parles ne nécessitera que 2 jountires.

    Tatayo.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mai 2021
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2021
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok, je crois que tu réponds en partie à mes interrogations, et en partie que tu m'indiques que je me suis mal exprimé... ^^'
    Je pensais faire plus de tables, mais pour le problème que j'ai je vais prendre l'exemple d'un sort plusieurs classes et niveaux associés.

    Je pensais créer une table Sorts (idsort, def, [...], idclasse, idniveau)
    une table Classes (idclasse, NomClasse, MagieProfane(booléen), MagieDivine(Booléen))
    une table Manuels (idmanuel, NomManuel, idsort)
    [...]

    Dans la table Sorts je peux mettre un idclasse mais pas plusieurs, si?
    Sinon, est-ce que je devrais pas créer une table ClassesSorts (CléPrimaire, idsort, idclasse) avec plusieurs lignes pour le même sort, genre "idsort=1, idclasse=3; idsort=1, idclasse=7" ?
    Auquel cas pour mes requêtes il me faudra prévoir une jointure, et si je veux ajouter le niveau de sort en plus je vais avoir une double jointure de plus, sans compter pour le manuel, ou est-ce qu'il y aurait un moyen de lier les tables de façon à ce que si je fais un SELECT dans une table, elle aille me chercher les infos dans les autres tables pour me les afficher aussi?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 200
    Points : 12 776
    Points
    12 776
    Par défaut
    Alors si je comprends bien:
    1. Un sort n'est que dans un seul manuel
    2. Un sort est lié àune ou plusieurs classes
    3. Une classe est liée à plusieurs sorts

    Dans ce cas il faut l'Id du manuel dans la table sort, et comme tu l'a deviné une table liée entre sort et classe (avec le niveau).

    Pour le dernier point, pour aller chercher une donnée dans une table à partir d'une autre table, il faut faire une jointure, il n'y a pas d'autre solution.

    Maintenant si tu veux par exemple tous les sorts d'une classe avec un niveau donné, ce n'est pas très compliqué:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select * <= c'est pour simplifier
    from Sort as s
    inner join ClasseSort as cs on cs.idSort = Sort.id
    inner join classe as c on c.id = cs.idClasse
    where cs.niveau = 2
    Et si tu as besoin d'info provenant de la table manuel, il faut juste ajouter une autre jointure, rien de bien compliqué.

    Tu peux également ajouter d'autres infos dans la table ClasseSort si besoin.

    Tatayo.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mai 2021
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2021
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok merci, tu viens de me confirmer ce que je craignais, mais au moins je sais où aller...
    Il va bien falloir que je fasse des jointures du coup.
    là où ça se complique c'est qu'un sort peut être dans plusieurs manuels, il peut être lancé par plusieurs classes, et à des niveaux différents.

    Donc il me faut une table Sorts pour les détails, une table Classes pour la liste des classes, une table ClasseSorts pour faire la liaison entre la table Sorts et la table Classes, une table Manuels pour la liste des manuels, et une table ManuelsSorts pour faire le lien entre les sorts et les manuels dans lesquels le trouver.
    Reste plus qu'à monter une requête pour rechercher tout ça, mais j'ai plus que deux jointures, ça va c'est dans mes compétences je crois

    Ta requête fonctionne si on suppose que je fais une colonne Niveau dans ClasseSort, ce qui est une très bonne idée, merci! ça éviterait de créer une table niveau en plus, et je peux faire une ligne idsort=1, idclasse=3, niveau=0 et une ligne idsort=1, idclasse=7, niveau=2!

    Par contre ça suppose que je renseigne toutes les autres infos directement dans une de ces trois tables (Sorts, ClasseSorts et ManuelsSorts), comme la durée du sort, la portée, etc. c'est pas gênant en soi, mais comme beaucoup de données sont les mêmes j'avais pensé à faire une table pour chaque avec quelques id à rappeler à chaque fois depuis la table Sorts (ex: iddurée=1). Ceci dit c'est pas gênant si ça me permet de ne pas avoir à faire des requêtes longues comme mon bras à chaque fois, je préfère faire une grosse intégration au début et être plus tranquille après coup.

    Si tu as d'autres conseils je suis preneur, tu m'as déjà bien aidé!
    Merci !!

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 142
    Points : 38 926
    Points
    38 926
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Pour répondre à ce genre de questions et d'une façon générale, pour bien modéliser les bases de données, le plus sage est de commencer par réaliser le modèle conceptuel des données (MCD) sans se préoccuper ni des tables ni des clefs étrangères.

    Pour pouvoir réaliser le MCD, il faut rédiger les règles de gestion, c'est ce qu'à fait en partie Tatayo ci-dessous :

    Citation Envoyé par tatayo Voir le message
    Alors si je comprends bien:
    1. Un sort n'est que dans un seul manuel
    2. Un sort est lié àune ou plusieurs classes
    3. Une classe est liée à plusieurs sorts
    En partie seulement, car il faut établir les règles dans un sens et dans l'autre pour chaque type d'entité (ou classe d'entité en langage UML).
    Chaque règle doit exprimer les cardinalités minimales et maximales
    Il est également recommandé d'attribuer un numéro à chaque règle de gestion.
    Ce qui peut donner par exemple
    • R001: un sort est contenu dans un et un seul manuel
    • R002 : un manuel contient au moins un sort
    • R003 : un sort est lié à une ou plusieurs classes
    • R004 : une classe est liée à zéro à plusieurs sorts


    On peut supposer également qu'un personnage n'appartient qu'à une et une seule classe
    • R005 : un personnage appartient à une et un seule classe
    • R006 : à une classe peuvent appartenir zéro à plusieurs personnages


    Si ces règles sont correctes et donc validées par la maîtrise d'ouvrage, on passe à l'étape de schématisation avec un outil ad hoc, ici j'utilise Looping :

    Pièce jointe 598580

    Comme tout bon logiciel de modélisation, Looping génère automatiquement le MLD (et donc les tables et les FK) ainsi que le script DDL associé au SGBD choisi
    Ce qui donne le MLD :
    Pièce jointe 598581

    Et le script :
    Code SQL : 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    CREATE TABLE CL_classe(
       CL_ident INT AUTO_INCREMENT,
       CL_code CHAR(6) NOT NULL,
       CL_libelle VARCHAR(50) NOT NULL,
       PRIMARY KEY(CL_ident),
       UNIQUE(CL_code)
    );
     
    CREATE TABLE MN_manuel(
       MN_ident INT AUTO_INCREMENT,
       PRIMARY KEY(MN_ident)
    );
     
    CREATE TABLE PE_personnage(
       PE_ident INT AUTO_INCREMENT,
       PE_nom VARCHAR(50) NOT NULL,
       CL_ident INT NOT NULL,
       PRIMARY KEY(PE_ident),
       FOREIGN KEY(CL_ident) REFERENCES CL_classe(CL_ident)
    );
     
    CREATE TABLE SO_sort(
       SO_ident INT AUTO_INCREMENT,
       SO_code CHAR(4) NOT NULL,
       SO_libelle VARCHAR(50) NOT NULL,
       SO_portee DECIMAL(5,0) NOT NULL,
       MN_ident INT NOT NULL,
       PRIMARY KEY(SO_ident),
       UNIQUE(SO_code),
       FOREIGN KEY(MN_ident) REFERENCES MN_manuel(MN_ident)
    );
     
    CREATE TABLE lier(
       SO_ident INT,
       CL_ident INT,
       PRIMARY KEY(SO_ident, CL_ident),
       FOREIGN KEY(SO_ident) REFERENCES SO_sort(SO_ident),
       FOREIGN KEY(CL_ident) REFERENCES CL_classe(CL_ident)
    );

    Attention : avec seulement ces règles, un personnage peut posséder un manuel, voire, exercer des sorts qui ne correspondent pas à sa classe.
    C'est pourquoi il me semble plus cohérent d'associer les sorts à une et une seule classe. Ce qui permettra d'ajouter une contrainte d'intégrité fonctionnelle (CIF) stipulant qu'un personnage ne peut exercer un sort que si ce sort correspond à sa classe
    Ce faisant, le personnage pourra tout à fait posséder un manuel de sorts (qu'il aura par exemple trouvé) mais sans pour autant savoir s'en servir.
    Ca correspond beaucoup mieux aux règles habituelles des RPG

Discussions similaires

  1. Réponses: 6
    Dernier message: 21/12/2012, 00h14
  2. Requete difficile multi table avec multi champ
    Par jujoluca dans le forum Requêtes
    Réponses: 9
    Dernier message: 07/06/2012, 19h59
  3. Table avec uniquement des des colonnes primary key
    Par BenoitM dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/03/2012, 11h58
  4. Table avec multi-référénce à elle-même
    Par Bakoi dans le forum Schéma
    Réponses: 2
    Dernier message: 27/08/2009, 10h03
  5. Réponses: 3
    Dernier message: 11/04/2008, 15h37

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