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 :

Entité en relation avec 2 autres entités ayant une relation entre elles [MCD]


Sujet :

Schéma

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Par défaut Entité en relation avec 2 autres entités ayant une relation entre elles
    Bonjour,

    J'ai un problème de conception sur lequel je me demande quelle est la solution la plus juste...

    Imaginons le cas suivant :
    - 1 entité BusinessLine
    - 1 entité ProductLine en relation 1..n avec BusinessLine (une ProductLine est nécessairement liée à une BusinessLine) -> cela constitue un référentiel (idée de la volumétrie : ~6/7 BusinessLine et 50/60 ProductLine)
    - 1 entité CommercialInformation qui peut être reliée à une BusinessLine et/ou à une ProductLine...dont la signification métier est le périmètre de cette information...

    La question est si je relie une Information à une ProductLine, alors la BusinessLine doit être celle de la ProductLine...
    Si on passe au modèle physique, dans la table Information, je vais avoir une FK vers ProducLine et une FK vers BusinessLine...et pour la table ProductLine, une FK vers BusinessLine.
    La question est comment gérer la colonne sur laquelle est la FK BusinessLine de la table Information : dois-je "dupliquer" la valeur de la BusinessLine référencée dans la table ProductLine si une Information référence une ProductLine ?
    Ex :
    ProductLine(Id,IdBL)
    (1,1)
    (2,1)
    ...
    et Information(Id,IdBL,IdPL) :
    1) tuple (1,1,1) -> avec une "assertion" (au sens modèle relationnel) pour contraindre IdBL
    ou 2) tuple (1,null,1) -> avec des vues (ou via le code) pour récupérer la BusinessLine via la ProductLine

    Mon dilemme est que 2) fait qu'on met de la "neige" (terme utilisé par fsmrel...François si tu me reconnais) et qu'on "galère" un peu pour récupérer la BusinessLine...et que 1) fait que j'ai l'impression qu'on duplique de la donnée...

    Merci de votre éclairage.

    Cdlt,
    Clément

  2. #2
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Bonjour,

    Si j'ai bien tout compris, vous avez actuellement le MCD suivant :
    BusinessLine -0,N---()---1,1- ProductLine
    CommercialInformation -0,1---()---0,N- BusinessLine
    CommercialInformation -0,1---()---0,N- ProductLine

    Ce qui donnerai le MLD :
    BusinessLine(id)
    ProductLine(id, id_businessLine)
    CommercialInformation(id, id_businessLine, id_productLine)

    Une fois en SQL, pour votre première solution il faudra apparemment effectuer un ordre INSERT avec NULL et ensuite corriger le tir avec un Trigger (Assertion).
    Pour la deuxième solution, le travail est simplement reporté sur la vue, mais il y aura de la neige dans votre table.

    Vous pourriez peut-être opter pour un MLD comme celui-ci:
    BusinessLine(id)
    ProductLine(id, id_businessLine)
    CommercialInformation(id)
    InfoProduct(id_productLine, id_commercialInformation)
    InfoBusiness(id_business, id_commercialInformation)

    Tout risque d'enneigement et ainsi écarté au niveau des tables.
    Mais il faudra quand même passer par une vue si vous voulez à tout pris une représentation de ce type : Information(Id,IdBL,IdPL).

    Voilà pour ma proposition, je passe la main aux autres en espérant avoir était utile

  3. #3
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Effectivement avec des cardinalités 0,1 -- 0,n, il faut normalement une table associative, comme dans le cas 0,n -- 0,n.
    Donc ici il en faut deux.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Par défaut
    Merci pour vos retours, en effet, je me souviens qu'il faut une table d'association pour les relations 0,1 et 0,N pour éviter la neige...mais mon problème se posait plus entre une solution nécessitant une jointure et une solution sans jointure (mais avec une sorte de "duplication").

    Si je repose le problème avec les tables d'association, cela donne :
    1) insertion dans les tables InfoBusiness et InfoProduct, sachant qu'il faut alors un trigger qui vérifie que le tuple ajouté dans InfoBusiness est bien cohérent avec ce qui est ajouté dans InfoProduct...ce que j'appelle une sorte de duplication puisque le lien Information-BusinessLine peut-être déduit des relations Information-ProductLine et ProductLine-BusinessLine lorsqu'il y a une ProductLine
    2) mettre contrainte d'exclusion entre InfoProduct et InfoBusiness (c'est l'un ou l'autre ou aucun) et déplacer le problème dans la(les) vue(s)...c'est une solution que j'ai déjà expérimenté et j'en suis moyennement content car les requêtes peuvent devenir plus complexes...

    Qu'en pensez-vous ?

    @Oishiiii : merci pour la clarification du MCD, c'est en effet ça.
    Pour la solution 1), j'aurais en effet fais un INSERT puis Trigger, mais j'aurais plutôt inséré un idBusinessLine au lieu de NULL, et fait un trigger qui aurait fait seulement une assertion plutôt qu'une mise à jour de la table, c'est-à-dire vérifier qu'une contrainte est bien remplie (celle qui dit que idBusinessLine d'une information doit être la même que idBusinessLine de la productline liée à l'information).

  5. #5
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 212
    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 212
    Billets dans le blog
    16
    Par défaut
    Bonsoir,

    Bienvenue à toi Clément.


    Citation Envoyé par clement.bouillier Voir le message
    Mon dilemme est que 2) fait qu'on met de la "neige" (terme utilisé par fsmrel...François si tu me reconnais) et qu'on "galère" un peu pour récupérer la BusinessLine...et que 1) fait que j'ai l'impression qu'on duplique de la donnée...
    De fait, dans le 1er cas on produit de la redondance et ça mérite a priori une petite punition, tandis que dans le 2e cas le Bonhomme Null fait son apparition, ce qui vaut d’être traduit devant le Tribunal Relationnel...

    Citation Envoyé par Oishiiii Voir le message
    Vous pourriez peut-être opter pour un MLD comme celui-ci:
    BusinessLine(id)
    ProductLine(id, id_businessLine)
    CommercialInformation(id)
    InfoProduct(id_productLine, id_commercialInformation)
    InfoBusiness(id_business, id_commercialInformation)

    Tout risque d'enneigement et ainsi écarté au niveau des tables.
    Mais il faudra quand même passer par une vue si vous voulez à tout pris une représentation de ce type : Information(Id,IdBL,IdPL).
    Hugh ! Oishiiii a bien parlé, puisqu’on évite le Bonhomme Null.

    N.B. La clé primaire de la table InfoProduct est réductible, puisqu’il existe la dépendance fonctionnelle :
    id_commercialInformation id_productLine
    Même chose pour la table InfoBusiness :
    id_commercialInformation id_business
    =>
    BusinessLine(id)
    ProductLine(id, id_businessLine)
    CommercialInformation(id)
    InfoProduct(id_commercialInformation, id_productLine)
    InfoBusiness(id_commercialInformation, id_businessLine)


    Citation Envoyé par clement.bouillier Voir le message
    mettre contrainte d'exclusion entre InfoProduct et InfoBusiness (c'est l'un ou l'autre ou aucun) et déplacer le problème dans la(les) vue(s)...c'est une solution que j'ai déjà expérimenté et j'en suis moyennement content car les requêtes peuvent devenir plus complexes...
    Il est un fait que l’utilisation d’une vue conduit à la mise en œuvre d’un trigger d’exclusion. On peut donc chercher plus simple. Dans la mesure où, par trigger, on insère une ligne dans la table InfoBusiness lors de l’insert d’une ligne dans la table InfoProduct, certes on produit de la redondance, mais il n’y a pas péril en la demeure, puisque le SGBD contrôle totalement les opérations.

    Exemple avec SQL Server (cas de l’INSERT) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TRIGGER Cial_Prod_1 ON InfoProduct INSTEAD OF INSERT AS
      INSERT INTO InfoProduct
        SELECT id_commercialInformation, id_productLine
        FROM   inserted
      ;
      INSERT INTO InfoBusiness
        SELECT x.id_commercialInformation, y.id_businessLine 
        FROM     inserted as x JOIN ProductLine as y
                   ON x.id_productLine = y.id_productLine             
      ;
    Mais il ne faudra pas oublier de traiter du cas de l’UPDATE et du DELETE.

    A noter que si l’on cherche à insérer une clé en double dans la table InfoBusiness (via le trigger ou en direct), on aura droit à un code retour de la part du SGBD, ce qui est la moindre des choses...
    (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.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 8
    Par défaut
    Merci François pour ce retour.

    Cependant, techniquement, comme dit à Oishiii, j'aurais plutôt fait l'insertion moi-même dans les 2 tables et mis un trigger sur l'insertion dans ProductLine pour faire une assertion qui lève une erreur du type "Violation de contrainte d'intégrité...".
    Ca me semble plus dans l'idée de l'assertion au sens modèle relationnel, non ?

    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TRIGGER InformationBusinessLineAssertion ON [ProductLine]
    FOR INSERT, UPDATE
    AS
    IF NOT EXISTS (SELECT * FROM BusinessLine bl ON
          JOIN INSERTED i ON r.IdInformation = i.IdInformation 
          JOIN ProductLine pl ON pl.IdProductLine = i.IdProductLine
          WHERE pl.IdBusinessLine = bl.IdBusinessLine)
    BEGIN
       RAISERROR ('Violation de contrainte d'intégrité...', 16, 1)
    END
    Y'a-t-il un(des) soucis à faire un RAISERROR dans un trigger ?

    Merci.

    Clément

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Modèle de Contexte] 8 Entités "0,n" en Relation avec deux autres "0,n"
    Par Invité dans le forum Merise
    Réponses: 4
    Dernier message: 15/02/2014, 14h51
  2. Réponses: 11
    Dernier message: 20/04/2007, 23h08
  3. Table avec lignes ayant une relation "père-fils"
    Par the java lover dans le forum Windows Forms
    Réponses: 7
    Dernier message: 02/04/2007, 11h20
  4. liste déroulante en relation avec un autre formulaire
    Par nicolovitch dans le forum Access
    Réponses: 1
    Dernier message: 20/07/2006, 17h26
  5. Ajout dans une table et relation avec d'autres
    Par climz dans le forum Access
    Réponses: 5
    Dernier message: 12/05/2006, 15h32

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