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

Schéma Discussion :

Struture de données pour données réflexives ?


Sujet :

Schéma

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 8
    Points : 6
    Points
    6
    Par défaut Struture de données pour données réflexives ?
    Salut a tous,

    Je cherche la structure la mieux adaptée pour mes données et mes requetes :

    - J'ai des utilisateurs (nom, prénom, etc...)
    - J'ai des groupes d'utilisateurs :
    * Un groupe peut contenir 0..n utilisateurs.
    * Un groupe peut contenir 0..n groupes.
    * Un utilisateur ne peut faire partie que d'un seul groupe ou pas du tout.

    Au niveau modèle des données je pensais avoir des entités "utilisateur" et "groupe" avec les relations :

    utilisateur[0..1] -> groupe[0..n] : "Fait partie"
    groupe[0..1] -> groupe[0..n] : "Contient"

    Ensuite je veux faire des requêtes sur les groupes.
    La difficulté est que je vais chercher à récuperer tous les utilisateurs par rapport à leurs groupes.

    Je prend un exemple :

    5 utilisateurs : U1, U2, U3, U4 et U5.
    3 Groupes : G1, G2 et G3

    Avec :
    G1 = G2 + G3 + U1
    G2 = U2 + U3
    G3 = U4
    U5 (n'appartient à aucun groupe)

    Maintenant je veux écrire une requête du type "récupérer la liste des utilisateurs du groupe G1". Ca doit me renvoyer "U1, U2, U3, et U4"

    Est-on obligé d'écrire une procédure complexe qui "descende" dans les groupes ou peut-on organiser ça d'une meilleure façon ? Je suis ouvert à tout...

    Merci !

    rahan2000fr @ free.fr
    PS : Je suis sous SQLServer

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Maintenant je veux écrire une requête du type "récupérer la liste des utilisateurs du groupe G1". Ca doit me renvoyer "U1, U2, U3, et U4"

    Est-on obligé d'écrire une procédure complexe qui "descende" dans les groupes ou peut-on organiser ça d'une meilleure façon ? Je suis ouvert à tout...
    Avec une modélisation classique (une table des groupes avec une colonne nullable contenant l'identifiant du groupe père), le requêtage dans les niveaux de sous-groupes entraîne l'utilisation de requêtes récursives dès lors qu'il y a plus d'un niveau de sous-groupe et potentiellement une infinité.

    La solution est alors de regarder du côté de la modélisation d'arbre par représentation intervallaire.


    Un utilisateur ne peut faire partie que d'un seul groupe ou pas du tout.
    Groupe -0,n----Comprendre----0,1- Utilisateur

    Dans ce cas, on crée une table associative :
    Comprendre (cpr_id_utilisateur, cpr_id_groupe)
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 8
    Points : 6
    Points
    6
    Par défaut Pour les utilisateurs...
    Comme ils ne font partie que d'un seul groupe ou ne font pas partie d'un groupe, je pensais qu'il n'y avait pas besoin de rajouter une table associative.

    Le rajout d'une table n'est nécessaire que quand la relation est N-aire de chaque côté de la flèche de la relation.

    Ici comme on a 0..1 du côté des utilisateurs, on peut rajouter directement dans la table des utilisateurs une colonne "Groupe" qui a pour valeur Null ou bien un identificateur de groupe (clef étrangère je crois).

    Dans le cas où un utilisateur pourrait faire partie de plusieurs groupes, alors oui il y aurait une relation N-aire dans le MCD ce qui conduirait à une table de la relation de la façon qui est décrite.

    Comprendre (cpr_id_utilisateur, cpr_id_groupe)

    Je me trompe ?

    Sinon la représentation intervallaire est très puissante en accès mais c'est compliqué à gérer en insertion / suppression. Comme a priori je n'ai pas accès aux fonctions récursives sous SQL Server, je vais devoir m'y coller... J'avais pas appri ça à l'école !

    Cordialement.

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,

    Citation Envoyé par Rahan2000 Voir le message
    Le rajout d'une table n'est nécessaire que quand la relation est N-aire de chaque côté de la flèche de la relation.

    Ici comme on a 0..1 du côté des utilisateurs, on peut rajouter directement dans la table des utilisateurs une colonne "Groupe" qui a pour valeur Null ou bien un identificateur de groupe (clef étrangère je crois).
    Tout d’abord, NULL n’est pas une valeur, mais une marque au sens de Codd (mark).

    Ensuite, l’ajout au niveau tabulaire d’une table associative est effectivement nécessaire quand les cardinalités de deux entités-types du MCD sont en relation avec des cardinalités de type x,N / y,N.

    Dans le cas 0,1 / y,N ou dans le cas 0,1 / y,1, une table associative s’impose elle aussi dès que l’on se situe dans le contexte relationnel, car le redoutable bonhomme NULL est interdit de séjour dans le Relationland. Évidemment si l’on ne tient pas à sortir des marécages du SQLland, on fait ce qu’on veut.

    Autrement dit, la FAQ Merise n’est pas assez précise à ce sujet. La règle qui y est énoncée est la suivante, je cite :
    « Pour les relations, cela dépend de la dimension et des cardinalités
    Relation binaire avec une cardinalité *,1
    La relation devient un lien référentiel avec une clé étrangère dans la table correspondant à l'entité coté cardinalité *,1 »

    Vu de celui qui a la responsabilité du niveau logique, cette règle doit être amendée dans le sens suivant :
    « Pour les relations, cela dépend de la dimension, des cardinalités et du contexte cible
    Relation binaire avec une cardinalité *,1
    Si par dérivation on produit des variables relationnelles (relvars), la relation fait l’objet d’une variable relationnelle, sinon, si l’on produit des tables, si l’on ne veut pas du bonhomme NULL, la relation fait l’objet d’une table, sinon, si tels les frères de Naf-Naf on ne se soucie pas des risques encourus, la relation devient un lien référentiel avec une clé étrangère dans la table correspondant à l'entité coté cardinalité *,1.
    Etc. »


    Au niveau SQL, façon Naf-Naf :

    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
    CREATE TABLE GROUPE
    (
            GprId    Char(6)      NOT NULL
          , GprNom   Varchar(32)  NOT NULL
        , CONSTRAINT GROUPE_PK PRIMARY KEY (GprId)
    ) ;
    CREATE TABLE COMPOSER
    (
            EnfantId    Char(6)      NOT NULL
          , ParentId    Char(6)      NOT NULL
        , CONSTRAINT COMPOSER_PK PRIMARY KEY (EnfantId, ParentId)
        , CONSTRAINT COMPOSER_FK1 FOREIGN KEY (EnfantId) REFERENCES GROUPE (GprId)
        , CONSTRAINT COMPOSER_FK2 FOREIGN KEY (ParentId) REFERENCES GROUPE (GprId)
        , CONSTRAINT COMPOSER_CHK1 CHECK (EnfantId <> ParentId)
    ) ;
    CREATE TABLE UTILISATEUR
    (
            UtilId    Char(6)      NOT NULL
          , UtilNom   Varchar(32)  NOT NULL
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (UtilId)
    ) ;
    CREATE TABLE UTIL_GROUPE
    (
            UtilId    Char(6)      NOT NULL
          , GprId     Char(6)      NOT NULL
        , CONSTRAINT UTIL_GROUPE_PK PRIMARY KEY (UtilId)
        , CONSTRAINT UTIL_UTIL_FK FOREIGN KEY (UtilId) REFERENCES UTILISATEUR (UtilId)
        , CONSTRAINT UTIL_GROUPE_FK FOREIGN KEY (GprId) REFERENCES GROUPE (GprId)
    ) ;

    Pour récupérer les groupes et les utilisateurs rattachés à g01 (ainsi que les groupes et utilisateurs rattachés aux groupes ratttachés à g01, etc.) :

    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
    WITH DESCENDANCE (ParentId, EnfantId) AS
    (
     (
      SELECT   ParentId, EnfantId
      FROM     COMPOSER
      WHERE    ParentId = 'g01'
     )
    UNION ALL
     (SELECT   x.ParentId, x.EnfantId
      FROM     COMPOSER AS x JOIN DESCENDANCE AS y
                 ON y.EnfantId = x.ParentId
     )
    )
      SELECT ParentId, EnfantId
      FROM   DESCENDANCE
    UNION 
      SELECT x.ParentId, y.UtilId
      FROM   DESCENDANCE AS x JOIN UTIL_GROUPE AS y 
               ON x.ParentId = y.GprId ;
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Rahan2000 Voir le message
    Salut a tous,

    Je cherche la structure la mieux adaptée pour mes données et mes requetes :
    * Un utilisateur ne peut faire partie que d'un seul groupe ou pas du tout.

    Ensuite je veux faire des requêtes sur les groupes.
    La difficulté est que je vais chercher à récuperer tous les utilisateurs par rapport à leurs groupes.
    Salut à toi, ô petit-petit-petit-...-fils de Crao!

    Juste une remarque à 2 cents: "Un utilisateur ne peut faire partie que d'un seul groupe", et, u peu plus loin, "leurs groupes"!

    D'après ton exemple, U2 appartient à G2 et aussi à G1 puisque tu veux le retrouver lors d'une requête sur G1!

    A un moment donné, si tu veux avoir les idées claires, je crois qu'il faudra bien que tu choisisses précisément si tu appelles "appartenance", l'appartenance directe ou l'appartenance indirecte! Non?

    )jack(

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/09/2013, 16h24
  2. Réponses: 2
    Dernier message: 23/10/2009, 14h18
  3. comment faire ma base de donnée pour un moteur de recherche
    Par HoB dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 04/05/2004, 15h07
  4. Type pour données de type email avec @
    Par jeff37 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 26/01/2004, 14h50
  5. [EJB2] Sources de données pour EJB
    Par thomy dans le forum Java EE
    Réponses: 4
    Dernier message: 04/06/2003, 15h52

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