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 :

Sémantique des connecteurs [MCD]


Sujet :

Schéma

  1. #1
    Membre du Club
    Homme Profil pro
    Transport et logistique
    Inscrit en
    Février 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Transport et logistique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 57
    Points : 52
    Points
    52
    Par défaut Sémantique des connecteurs
    Je dois mettre en place une base de données qui fait référence à mes types de « Composant » (classe mère). Prenons le cas du composant « Connecteur » et « ConnecteutDeRepos ». Dans mon futur logiciel, lorsque l’utilisateur choisit un Connecteur le logiciel doit lui donner accès qu’à une sélection restreinte de ConnecteurDeRepos (qui correspond à la sélection de ConnecteurDeRepos compatible). Pour le faire un filtrage doit être fait sur les trois attributs « ClasseConnecteur », « Shell Size » et « Finish » du « Connecteur » choisit et n’afficher que les « ConnecteurDeRepos » qui possèdent les mêmes valeurs dans ses attributs respectifs.
    Mon problème est que Connecteur et ConnecteurDeRepos sont en réalité identifié par le P/N (relatif au fournisseur du composant), la question que je me pose est donc : Est-ce que je dois faire apparaitre cette notion de filtre sur mon schéma ? Et si oui est-ce que ceci est ce qu’on appelle une contrainte d’intégrité fonctionnelle ou Règle de gestion dans PowerAmc ?

    Nom : Composant.jpg
Affichages : 613
Taille : 10,4 KoNom : Connecteur.jpg
Affichages : 768
Taille : 21,2 KoNom : ConnecteurDeRepos.jpg
Affichages : 651
Taille : 16,7 Ko

    L'autre question intrinsèque qui se pose est donc : Est-ce que la sémantique de cette notion de filtre sur trois critère doit être implémenter au niveau informatique, c'est à dire en créant une association entre Connecteur et ConnecteurDeRepos ? Ou est-il préférable de traiter cette sémantique par des filtres ?



    Je vous remercie d'avance pour votre aide

  2. #2
    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 Anthony,



    Que signifie l’expression « Principe connecteur » ?

    Dans l’expression « Composant P/N », que signifie « P/N » ?

    Un connecteur est-il un composant, autrement dit si COMPOSANT est une classe, PRINCIPE_CONNECTEUR en est-elle une sous-classe ? La classe PRINCIPE_ONNECTEUR_DE_REPOS est-elle une sous-classe de PRINCIPE_CONNECTEUR ? Sinon, de COMPOSANT ? Sinon ? ...
    (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.

  3. #3
    Membre du Club
    Homme Profil pro
    Transport et logistique
    Inscrit en
    Février 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Transport et logistique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    Bonjour fsmrel,

    Dans l'expression "Principe_Connecteur" maintenant seul "Connecteur" est à retenir, j'utilisais ce préfixe dans le passé pour identifié que les composants apparaissent dans la phase d'étude à partir du schéma de principe car à l'époque j'écrivais un MCD pour chaque type de schéma. Aujourd'hui j'ai un vue bien plus globale du sujet donc je dresse le MCD de l'ensemble du système application.

    Dans "Composant_P/N" "P/N" signifie "Part Number" c'est ce qui identifie le composant, le modèle de téléviseur A de chez SAMSUNG par exemple. Lors de la phase d'étude d'une affaire lorsqu'un dessinateur va concevoir un schéma synoptique il va placer sur son schéma des EQUIPEMENT qui son identifié par le couple (FIN,Affaire) avec FIN= Functional Item Number, c'est ce qui identifie l'équipement dans l'avion, un téléviseur par exemple. Plus tard pour cet EQUIPEMENT on lui associe un seul et unique COMPOSANT, sémantiquement cela veut dire quel composant est a placé dans l'avion. En revanche à un seul COMPOSANT on associe plusieurs EQUIPEMENT. Exemple : Si dans mon avion j'ai plusieurs téléviseurs, il se peut très bien que ce soit à chaque fois le modèle A de chez SAMSUNG.

    La table CONNECTEUR est bien une sous-classe de COMPOSANT. La question que je me pose en ce moment concerne CONNECTEUR_DE_REPOS; Je sais que CONNECTEUR_DE_REPOS est au moins un COMPOSANT donc il y aurait au moins héritage depuis COMPOSANT mais étant donné qu'un CONNECTEUR_DE_REPOS est associé à un CONNECTEUR selon les trois critères : ClassConnecteur, FinishPlating et ShellSize je me demande si je dois informatiser cette interprétation avec soit:

    _Une association entre CONNECTEUR 0,n----1,1 CONNECTEUR_DE_REPOS. Donc beaucoup de travail manuel lorsqu'il faudra remplir la base de données.
    _Un héritage CONNECTEUR_DE_REPOS----->CONNECTEUR avec les attributs ClassConnecteur, FinishPlating et ShellSize dans CONNECTEUR.
    _Un système de filtre dans mon application qui, pour une CONNECTEUR choisit ne me montre que les CONNECTEUR_DE_REPOS compatible.

    Au montage, on branche un connecteur de repos sur un connecteur ce qui veut donc dire que connecteur et connecteur de repos sont forcément deux objets différents

    Nom : ConneRepos.jpg
Affichages : 731
Taille : 17,6 Ko
    Nom : connecteur.jpg
Affichages : 1397
Taille : 9,0 Ko

    Merci

  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 Anthony,


    Pour simplifier, je symboliserai par "CNR" un connecteur qui n’est pas un connecteur de repos et par "CDR" un connecteur de repos.

    Pour le moment, ce que je comprends :

    — Un CNR et un CDR dépendent d’une sous-classe C1 de la classe COMPOSANT. Un CNR fait partie d’une sous-classe C11 de C1 (en effet, un CNR a des propriétés que n’ont pas les CDR : Arrangement, Polarisation, Type) et un CDR fait donc partie d’une sous-classe C12 de C1.

    — Un CDR peut être branché sur au plus un CNR.

    — Sur un CNR on peut brancher plusieurs CDR.

    — Plusieurs CDR peuvent avoir la même valeur <c, f, s> pour le triplet {ClassConnecteur, FinishPlating et ShellSize}.

    Question : Deux CNR peuvent-ils avoir la même valeur <c, f, s> pour le triplet {ClassConnecteur, FinishPlating et ShellSize} ?

    A suivre...
    (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
    Membre du Club
    Homme Profil pro
    Transport et logistique
    Inscrit en
    Février 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Transport et logistique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    Désolé je dois revenir en arrière sur ce que j'ai dit précédemment , j'ai reçu des contenus des tables ce matin et il se trouvait qu'elles ne correspondaient pas avec la description que l'on m'avait faite. Donc en faite c'est le contraire : Pour un CDR j'ai plusieurs CNR possible mais pour un CNR il n'y a qu'un seul CDR

    Donc pour répondre à la question, deux CNR peuvent avoir la même valeur <c, f, s>
    mais deux CDR ne peuvent pas avoir le même <c, f , s>

    Ce qui est en corrélation avec la description ci-dessus.


    Niveau MCD est-ce que ça me donne quelque chose comme ça ?

    Nom : Héritages composant.jpg
Affichages : 791
Taille : 43,8 Ko


    Merci bien

  6. #6
    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 Dagobert ?
    Bonsoir Anthony,


    Pas de problème pour l’inversion des rôles ^^


    Citation Envoyé par Antonitzer Voir le message
    deux CDR ne peuvent pas avoir le même <c, f , s>
    Le triplet {ClassConnecteur, FinishPlating, ShellSize} est donc identifiant candidat de ConnecteurDeRepos.


    Citation Envoyé par Antonitzer Voir le message
    un filtrage doit être fait sur les trois attributs « ClasseConnecteur », « Shell Size » et « Finish » du « Connecteur » choisit et n’afficher que les « ConnecteurDeRepos » qui possèdent les mêmes valeurs dans ses attributs respectifs
    Autrement dit, un connecteur ne peut être en relation avec un connecteur de repos que s’il a la même valeur <c, f , s> pour le triplet {ClassConnecteur, FinishPlating, ShellSize}. C’est bien cela ?

    Si oui, on peut modéliser en évitant la redondance de <c, f , s> et forcer Connecteur à prendre sa valeur de <c, f , s> en faisant référence à « son » connecteur de repos (héritage en quelque sorte du triplet) :




    MLD correspondant

    L’attribut Con_ComposantId de la table Connecteur fait référence (clé étrangère) à l’attribut ComposantId (clé primaire) de la table ConnecteurDeRepos :




    On pourrait aussi modéliser comme ci-dessous (on retrouve votre MCD avec en plus une contrainte d’exclusion entre les sous-types (sous-classes)), mais avec le risque qu’un connecteur ne soit en relation avec aucun connecteur de repos :




    MLD




    Autrement dit, si on veut qu’un connecteur soit toujours associé à un connecteur de repos, on établit une contrainte d’inclusion, par le biais d’une association :




    Évidemment, PowerAMC n’a pas pigé qu’il s’agissait d’une contrainte d’inclusion, aussi produit-il un MLD dans lequel la table Connecteur est affublée d’un attribut Con_ComposantId qui cette fois-ci ne nous sert à rien, car ce qu’on veut c’est que le triplet {ClassConnecteur, FinishPlating, ShellSize} de cette table fasse référence à son homologue de la table ConnecteurDeRepos :




    Même en permutant le rôle des clés candidates dans la table ConnecteurDeRepos, l’AGL ne pige toujours pas et il n’y a pas moyen de lui faire comprendre ce qu’on veut, il propose seulement ceci :





    Même pas grave, on laisse tomber cette version. On revient au MLD de la figure 4 (issu de votre MCD), on génère le script SQL correspondant, en y ajoutant la contrainte sous la forme d’une clé étrangère hébergée par la (table Connecteur et référençant la clé alternative {ClassConnecteur, FinishPlating, ShellSize} de la table ConnecteurDeRepos.

    Exemple (la contrainte porte ici le nom «Connecteur_ConnecteurDeRepos_FK ») :

     
    CREATE TABLE COMPOSANT
    (
       ComposantId          INT                  NOT NULL,
       ComposantPN          VARCHAR(6)           NOT NULL,
       Etc                  VARCHAR(64)          NOT NULL,
       CONSTRAINT COMPOSANT_PK PRIMARY KEY (ComposantId),
       CONSTRAINT COMPOSANT_AK UNIQUE (ComposantPN)
    ) ;
    
    CREATE TABLE ConnecteurDeRepos 
    (
       ComposantId          INT                  NOT NULL,
       ClassConnecteur      INT                  NOT NULL,
       FinishPlating        INT                  NOT NULL,
       ShellSize            INT                  NOT NULL,
       Designation          VARCHAR(64)          NOT NULL,
       CONSTRAINT ConnecteurDeRepos_PK PRIMARY KEY (ComposantId),
       CONSTRAINT ConnecteurDeRepos_AK UNIQUE (ClassConnecteur, FinishPlating, ShellSize),
       CONSTRAINT ConnecteurDeRepos_COMPOSANT_FK FOREIGN KEY (ComposantId)
          REFERENCES COMPOSANT (ComposantId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE Connecteur 
    (
       ComposantId          INT                  NOT NULL,
       ClassConnecteur      INT                  NOT NULL,
       FinishPlating        INT                  NOT NULL,
       ShellSize            INT                  NOT NULL,
       Designation          VARCHAR(64)          NOT NULL,
       Arrangement          VARCHAR(64)          NOT NULL,
       Polarisation         VARCHAR(64)          NOT NULL,
       ConnecteurType       VARCHAR(6)           NOT NULL,
       CONSTRAINT Connecteur_PK PRIMARY KEY (ComposantId),
       CONSTRAINT Connecteur_AK UNIQUE (ClassConnecteur, FinishPlating, ShellSize),
       CONSTRAINT Connecteur_COMPOSANT_FK FOREIGN KEY (ComposantId)
          REFERENCES COMPOSANT (ComposantId) ON DELETE CASCADE,
       CONSTRAINT Connecteur_ConnecteurDeRepos_FK FOREIGN KEY (ClassConnecteur, FinishPlating, ShellSize)
          REFERENCES ConnecteurDeRepos (ClassConnecteur, FinishPlating, ShellSize) ON DELETE NO ACTION
    ) ; 
    Du fait de cette contrainte, un connecteur doit nécessairement faire référence à un connecteur de repos. Si vous jugez que cette contrainte est trop stricte, vous la supprimez...

    En passant, n’oubliez pas de définir ComposantPN comme clé alternative de la table COMPOSANT.

    Il faudrait aussi mettre en œuvre la contrainte d’exclusion entre les sous-types de COMPOSANT : mais c’est SGBD dépendant. Quel est le vôtre ?
    (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.

  7. #7
    Membre du Club
    Homme Profil pro
    Transport et logistique
    Inscrit en
    Février 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Transport et logistique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    Bonjour fsmrel,


    En effet un connecteur peut-être en relation avec un connecteur de repos que s’il a la même valeur <c, f , s> pour le triplet {ClassConnecteur, FinishPlating, ShellSize}, ça c'est bon.



    Pour ce qui est des solutions, bien sur la première (Figure 1,2) est la plus satisfaisante. Après il faut voir ce que ça donnerais au niveau de l'administration de la base.

    Sinon la seconde en proposant de rajouter la contrainte à la main est intéressante aussi car elle permet d'interpréter la semantique au niveau informatique.

    Pour élire la meilleure des deux peut-être faut-il comment cela va se dérouler au niveau de l'administration de la base ? je m'explique...

    Disons que plus tard pour ajouter un CND dans la base, avec la première solution si il faut regarder à quel CDR cela correspond pour ensuite créer un objet CND et lui attribuer en Con_ComposantId le ComposantId du CDR cela peut demander beaucoup de travail.

    D'un autre côté avec la solution 2 saisir les <c, f , s> est plus facile lors d'un ajout de Connecteur car on trouve ces informations dans la documentation de la classe du composant mais nous avons une redondance d'informations.

    Je ne sais pas trop encore comment marche ces tâches donc je ne peux me prononcer sur laquelle de ces méthodes est la meilleur.


    Merci pour le coup de main

    Question : Pourquoi ComposantPN ne devient pas un fk dans les classes héritées ?

  8. #8
    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 Anthony,



    Citation Envoyé par Antonitzer Voir le message
    Pourquoi ComposantPN ne devient pas un fk dans les classes héritées ?
    La relation entre une clé candidate K (primaire ou alternative) et une clé étrangère F qui la référence, ne doit pas subir les conséquences d’une modification affectant K.

    Yves Tabourier l’a bien montré au niveau conceptuel, je vous renvoie à ce que j’en dis ici.

    On est toujours à la merci de l’utilisateur, il a tout pouvoir sur ses données et peut les changer ad infinitum. J’ai assisté à des refontes de système provoquées par l’évolution de la structure des clés (passage à l’extension à 9, puis à 10 chiffres des numéros de téléphone, et autres facéties redoutables). Les clés omniprésentes dans les relations entre tables doivent donc être invariantes, échapper au contrôle de l’utilisateur, d’où la mise en oeuvre de l’attribut ComposantId (privé) qu’on retrouve effectivement dans toutes les tables, en tant que clé primaire et clé étrangère, tandis que l’attribut ComposantPN (public) n’est donc présent qu’une fois, dans la table Composant : si l’utilisateur le chahute, alors ça n’est pas un problème.



    Citation Envoyé par Antonitzer Voir le message
    pour ajouter un CND dans la base, avec la première solution si il faut regarder à quel CDR cela correspond pour ensuite créer un objet CND et lui attribuer en Con_ComposantId le ComposantId du CDR cela peut demander beaucoup de travail.
    En fait, avec un SGBD permettant d’affecter des triggers à des vues (DB2, Oracle, SQL Server, etc., MySQL étant pour sa part exclu...), le travail de l’utilisateur peut être très largement simplifié, en consultation et en mise à jour.

    Reprenons le MCD :



    Ainsi que le MLD correspondant :




    Script de création des tables :
    (j’ai renommé la colonne Con_ComposantId de la table Connecteur en CDR_ComposantId)

     
    CREATE TABLE Composant 
    (
       ComposantId          INT              NOT NULL  IDENTITY,
       ComposantPN          VARCHAR(64)      NOT NULL,
       Etc                  VARCHAR(64)      NOT NULL,
       CONSTRAINT Composant_PK PRIMARY KEY (ComposantId),
       CONSTRAINT Composant_AK UNIQUE (ComposantPN)
    ) ;
    
    CREATE TABLE ConnecteurDeRepos 
    (
       ComposantId          INT              NOT NULL,
       ClassConnecteur      VARCHAR(64)      NOT NULL,
       FinishPlating        VARCHAR(64)      NOT NULL,
       ShellSize            VARCHAR(64)      NOT NULL,
       Designation          VARCHAR(64)      NOT NULL,
       CONSTRAINT ConnecteurDeRepos_PK PRIMARY KEY (ComposantId),
       CONSTRAINT ConnecteurDeRepos_AK UNIQUE (ClassConnecteur, FinishPlating, ShellSize),
       CONSTRAINT ConnecteurDeRepos_Composant_FK FOREIGN KEY (ComposantId)
          REFERENCES Composant (ComposantId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE Connecteur 
    (
       ComposantId          INT              NOT NULL,
       CDR_ComposantId      INT              NOT NULL,
       Designation          VARCHAR(64)      NOT NULL,
       Arrangement          VARCHAR(64)      NOT NULL,
       Polarisation         VARCHAR(64)      NOT NULL,
       ConnecteurType       VARCHAR(64)      NOT NULL,
       CONSTRAINT Connecteur_PK PRIMARY KEY (ComposantId),
       CONSTRAINT Connecteur_ConnecteurDeRepos_FK FOREIGN KEY (CDR_ComposantId)
          REFERENCES ConnecteurDeRepos (ComposantId),
       CONSTRAINT Connecteur_Composant_FK FOREIGN KEY (ComposantId)
          REFERENCES Composant (ComposantId) ON DELETE CASCADE
    ) ;
    
    Remarque concernant l’intégrité référentielle

    (1) La contrainte Connecteur_Composant_FK présente dans la table Connecteur est dotée d’une clause « ON DELETE CASCADE ». Cela signifie que si l’on supprime dans la table Composant le composant pour lequel la colonne ComposantId prend la valeur <c>, la suppression est de facto déclenchée en plus pour la ligne la table Connecteur pour laquelle la colonne ComposantId prend aussi la valeur <c> (suppression en cascade) : cette répercussion est logique, puisqu’il n’y a en réalité qu’un seul objet Connecteur, dont les données sont réparties dans deux tables au niveau SQL.

    (2) Si la contrainte Connecteur_Composant_FK n’est pas dotée d’une clause « ON DELETE CASCADE », alors si on cherche à supprimer directement dans la table Composant, on se fera jeter tant que la valeur <c> partie prenante dans cette histoire sera présente à la fois dans les deux tables. Pour arriver à supprimer le composant, il faudra donc d’abord supprimer la ligne concernée dans la table Connecteur, suite à quoi on pourra enfin effectuer la suppression dans la table Composant.

    Dans le cas de la généralisation appliquée aux composants, il est évident qu’il est préférable de mettre en œuvre la clause « ON DELETE CASCADE » : la contrainte ConnecteurDeRepos_Composant_FK (table ConnecteurDeRepos) est donc aussi concernée par cette clause.

    Par contre, si l’on ne peut pas impunément répercuter la suppression d’un connecteur de repos sur les connecteurs qui le référencent, alors on ne doit pas utiliser la clause « ON DELETE CASCADE », cas de la contrainte Connecteur_ConnecteurDeRepos_FK (table Connecteur).


    Faciliter la tâche de l’utilisateur, tout en lui cachant l’attribut ComposantId qui ne le concerne pas :

    Plutôt que de le laisser agir sur les tables de base, on l’autorisera à seulement agir sur des tables virtuelles, c'est-à-dire des vues.

    Prenons le cas d’un connecteur de repos Cr (CDR). Pour répondre au besoin fonctionnel de visualisation, la vue ConnecteurDeReposV ci-dessous suffit (ne figurent que les attributs naturels, c'est-à-dire ceux auxquels l’utilisateur est sensible : l’attribut ComposantId est artificiel, purement technique et ne le concerne pas) :

    ConnecteurDeReposV {ComposantPN, Etc, ClassConnecteur, FinishPlating, ShellSize, Designation}

    Où :

    — ComposantPN est l’attribut qui identifie Cr dans la table Composant ;
    — Etc résume dans cette table les autres attributs de Cr ;
    — ClassConnecteur, FinishPlating, ShellSize représentent le ClassConnecteur, le FinishPlating et le ShellSize de Cr.

    Déclaration SQL de cette vue (à faire vous-même ou par votre DBA...) :

     
    CREATE VIEW ConnecteurDeReposV (ComposantPN, Etc, ClassConnecteur, FinishPlating, ShellSize, Designation)
    AS 
        SELECT x.ComposantPN, x.Etc, y.ClassConnecteur, y.FinishPlating, y.ShellSize, y.Designation
        FROM   Composant as x JOIN ConnecteurDeRepos as y on x.ComposantId = y.ComposantId
    ;
    
    Ainsi, il y a une composante publique : l’en-tête de la vue, ainsi qu’une composante privée : le SELECT. Que celui-ci soit estimé simple ou non à coder, l’utilisateur n’en a pas conscience, il ne voit que des structures classiques de tables, sans même savoir si du reste ces structures sont de base ou virtuelles, car ces concepts lui échappent totalement...


    Prenons le cas d’un connecteur Cx (CNR). Comme dans le cas du connecteur de repos Cr, pour répondre au besoin fonctionnel de visualisation, la vue ConnecteurVtout ci-dessous suffit (là encore, ne figurent que les attributs naturels, l’attribut ComposantId n’en fait donc pas partie) :

    ConnecteurVtout {ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType}

    Où :

    — ComposantPN est l’attribut qui identifie Cx dans la table Composant ;
    — Etc résume dans cette table les autres attributs de Cx ;
    — ConnecteurDeReposPN représente l’identifiant du connecteur de repos Cr référencé par Cx ;
    — ClassConnecteur, FinishPlating, ShellSize représentent le ClassConnecteur, le FinishPlating et le ShellSize du connecteur de repos Cr ;
    — Arrangement, Designation, Polarisation, ConnecteurType représentent l’arrangement, la désignation, la polarisation et le type du connecteur Cx.

    Déclaration SQL de cette vue :

     
    CREATE VIEW ConnecteurVtout (ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType)
    AS 
        SELECT x.ComposantPN, x.Etc, t.ComposantPN, z.ClassConnecteur, z.FinishPlating, z.ShellSize, y.Arrangement, y.Designation, y.Polarisation, y.ConnecteurType
        FROM   Composant as x JOIN Connecteur as y on x.ComposantId = y.ComposantId
                              JOIN ConnecteurDeRepos as z on y.CDR_ComposantId = z.ComposantId
                              JOIN Composant AS t ON z.ComposantId = t.ComposantId
    ; 
    
    Une fois de plus, l’utilisateur ne voit qu’une structure classique de table, dépourvue d’attributs artificiels qui ne le concernent pas.


    Maintenant, il faut que l’utilisateur puisse mettre à jour la base de données. Étant donné qu’il n’a accès qu’aux vues, on doit l’autoriser à mettre celles-ci à jour. Si le SGBD ne nous autorise pas la mise à jour directe des vues, mais permet de définir des triggers pour celles-ci, on s’en sortira quand même.

    Triggers pour mettre à jour les connecteurs de repos. Exemples (SQL Server) :

    Un trigger permettant de créer des connecteurs de repos :

     
    CREATE TRIGGER ConnecteurDeReposTR ON ConnecteurDeReposV INSTEAD OF INSERT
    AS
        INSERT INTO Composant (ComposantPN, Etc)
            SELECT ComposantPN, Etc
            FROM   INSERTED 
            ;
        INSERT INTO ConnecteurDeRepos (ComposantId, ClassConnecteur, FinishPlating, ShellSize, Designation)
            SELECT ComposantId, ClassConnecteur, FinishPlating, ShellSize, Designation 
            FROM INSERTED as x JOIN Composant as y ON x.ComposantPN = y.ComposantPN 
            ; 
    Un trigger pour la suppression des connecteurs de repos (on se souvient que, du fait de la clause CASCADE, la suppression portant sur la table Composant est répercutée sur la table ConnecteurDeRepos) :

    CREATE TRIGGER ConnecteurDeReposTRdel ON ConnecteurDeReposV INSTEAD OF DELETE
    AS
        DELETE FROM Composant
               WHERE ComposantPN IN (SELECT ComposantPN FROM DELETED)
     
    Un trigger pour la modification des connecteurs de repos :

     
    CREATE TRIGGER ConnecteurDeReposTRupd ON ConnecteurDeReposV INSTEAD OF UPDATE
    AS
    IF UPDATE (ComposantPN)  
        BEGIN
            IF (SELECT COUNT(ComposantPN) FROM INSERTED) > 1
                BEGIN
                    RAISERROR ('Veuillez ne modifier qu''une clé ComposantPN à la fois. ', 16, 1)
                    ROLLBACK TRAN
                    RETURN
                END
            UPDATE Composant 
               SET ComposantPN = (SELECT ComposantPN FROM INSERTED) 
               WHERE  Composant.ComposantPN = (SELECT ComposantPN FROM DELETED)
            ;
        END
    
    IF UPDATE (Etc)
        BEGIN
            UPDATE Composant
                SET Etc = (SELECT Etc
                           FROM   INSERTED
                           WHERE  Composant.ComposantPN = INSERTED.ComposantPN)
                WHERE ComposantPN IN (SELECT Composant.ComposantPN
                                      FROM   Composant JOIN INSERTED
                                             ON Composant.ComposantPN = INSERTED.ComposantPN)
            ;
        END
    
    IF UPDATE (ClassConnecteur)
        BEGIN
            UPDATE ConnecteurDeRepos
            SET ClassConnecteur = (SELECT ClassConnecteur
                                   FROM   INSERTED
                                   WHERE  ConnecteurDeRepos.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                                  ) 
            WHERE ComposantId IN (SELECT Composant.ComposantId
                                  FROM   Composant JOIN INSERTED
                                         ON Composant.ComposantPN = INSERTED.ComposantPN)
        END
    
    Je n’ai pas fait figurer la modification des colonnes FinishPlating, ShellSize et Designation, mais il suffit de recopier ce qui a été fait pour la colonne ClassConnecteur, en remplaçant le nom de cette dernière.

    Ainsi, grâce aux vues et aux triggers, le travail de l’utilisateur (développeur ou utilisateur final) est réduit au minimum, la complexité est encapsulée une bonne fois pour toutes.

    Exemple d’ajout d’un connecteur de repos :

     
    INSERT INTO ConnecteurDeReposV (ComposantPN, Etc, ClassConnecteur, FinishPlating, ShellSize, Designation) 
        VALUES ('cpn01', 'etc01', 'classe01', 'finish01', 'shell01', 'design cpn01') ;
    
    Suppression des connecteurs de repos pour lesquels ShellSize = 'shell02' :

    DELETE FROM ConnecteurDeReposV WHERE ShellSize = 'shell02' ;
    

    Modification du connecteur de repos pour lequel ComposantPN = 'cpn03'

     
    UPDATE ConnecteurDeReposV
        SET ComposantPN = 'cpn77'
          , Etc = 'cpn99'
          , ClassConnecteur = 'classe 12'
        WHERE ComposantPN = 'cpn03' ;
    
    Visualisation de l’ensemble des connecteurs de repos :

     
    SELECT ComposantPN, Etc, ClassConnecteur, FinishPlating, ShellSize, Designation
    FROM   ConnecteurDeReposV ;
    

    Ainsi, la tâche de l’utilisateur est simple, il se sert de la vue ConnecteurDeReposV comme d’une table banale, sans même qu’il ait à savoir que sous le capot les données sont en réalité réparties dans les deux tables de base Composant et ConnecteurDeRepos, tandis que les triggers interceptent les opérations de mise à jour appliquées à la vue et ventilent dans les deux tables les données déclarées dans la vue.


    Triggers pour mettre à jour les connecteurs CNR

    On a vu que la vue ConnecteurVtout permet de visualiser non seulement les données du connecteur Cx, mais aussi celles de son connecteur de repos Cr :

     
    CREATE VIEW ConnecteurVtout (ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType)
    AS 
        SELECT x.ComposantPN, x.Etc, t.ComposantPN, z.ClassConnecteur, z.FinishPlating, z.ShellSize, y.Arrangement, y.Designation, y.Polarisation, y.ConnecteurType
        FROM   Composant as x JOIN Connecteur as y on x.ComposantId = y.ComposantId
                              JOIN ConnecteurDeRepos as z on y.CDR_ComposantId = z.ComposantId
                              JOIN Composant AS t ON z.ComposantId = t.ComposantId
    

    On peut aussi se contenter de la vue ConnecteurV ci-dessous :

    ConnecteurV {ComposantPN, Etc, ConnecteurDeReposPN, Designation, Arrangement, Polarisation, ConnecteurType}

    Où, je le rappelle :

    — ComposantPN est l’attribut qui identifie le connecteur Cx dans la table Composant ;
    — Etc résume dans cette table les autres attributs de Cx ;
    — ConnecteurDeReposPN est l’identifiant (naturel) du connecteur de repos Cr auquel fait référence Cx ;
    — Designation, Arrangement, Polarisation, ConnecteurType représentent la désignation, l’arrangement et le type de connecteur de Cx.

    Comme dans le cas des connecteurs de repos, l’utilisateur utilisera des vues pour mettre à jour la base de données, d’où la nécessité de coder les triggers interceptant les opérations de mise à jour, quand le SGBD les rejette.

    Exemple :

     
    CREATE TRIGGER ConnecteurTR ON ConnecteurV INSTEAD OF INSERT
    AS
    INSERT INTO Composant (ComposantPN, Etc)
        SELECT ComposantPN, Etc
        FROM   INSERTED 
    ;
    INSERT INTO Connecteur (ComposantId, CDR_ComposantId, Designation, Arrangement, Polarisation, ConnecteurType)
        SELECT y.ComposantId, z.ComposantId, Designation, Arrangement, Polarisation, ConnecteurType 
        FROM INSERTED AS x JOIN Composant AS y on x.ComposantPN = y.ComposantPN
                           JOIN composant AS z on x.ConnecteurDeReposPN = z.ComposantPN
    ; 
    Un insert :

    INSERT INTO ConnecteurV (ComposantPN, Etc, ConnecteurDeReposPN, Designation, Arrangement, Polarisation, ConnecteurType)
        VALUES ('cpn33', 'etc33', 'cpn03', 'design33', 'arr33', 'polar33', 'conntype33') ;
    
    On peut du reste effectuer des inserts avec la vue ConnecteurVtout :

     
    INSERT INTO ConnecteurVtout (ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType)
        VALUES ('cpn34', 'etc34', 'cpn01', '', '', '', 'arr34', 'design34', 'polar34', 'conntype34') ;
    
    Mais bien sûr, cette vue doit elle aussi faire l’objet d’un trigger :

     
    CREATE TRIGGER ConnecteurToutTR ON ConnecteurVtout INSTEAD OF INSERT
    AS
    INSERT INTO ConnecteurV (ComposantPN, Etc, ConnecteurDeReposPN,  Arrangement, Designation, Polarisation, ConnecteurType)
        SELECT ComposantPN, Etc, ConnecteurDeReposPN,  Arrangement, Designation, Polarisation, ConnecteurType
        FROM   INSERTED 
    ;
    
    Je vous sous-traite les triggers pour les suppressions et modifications...

    Tout ce que j’ai développé dans ce message est un peu long, mais a pour but de montrer que le travail de l’utilisateur peut être rendu simple, à condition que nous prenions pour notre part en charge la création des vues et des triggers.

    Je vais m'occuper du 2e scénario.


    En passant, vous ne votez plus ?
    (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.

  9. #9
    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 Anthony,


    Passons au 2e scénario.

    Citation Envoyé par Antonitzer Voir le message
    D'un autre côté avec la solution 2 saisir les <c, f , s> est plus facile lors d'un ajout de Connecteur car on trouve ces informations dans la documentation de la classe du composant mais nous avons une redondance d'informations.
    Il y a redondance et redondance... Ici elle est sans risque, car complètement contrôlée grâce à la contrainte référentielle Connecteur_ConnecteurDeRepos_FK FOREIGN KEY établie entre les tables Connecteur et ConnecteurDeRepos, faisant qu’une valeur <c, f, s> du triplet {ClassConnecteur, FinishPlating, ShellSize} ne peut exister dans la table Connecteur s’il existe pas d’abord dans la table ConnecteurDeRepos. Par ailleurs, n’oubliez la spécificité du modèle relationnel de données (synonyme de théorie relationnelle) : on doit pouvoir comparer les données d’une table avec les données d’une autre table à partir des valeurs prises par de leurs colonnes (de même type) et non pas en effectuant des explorations à coups de pointeurs comme on le faisait dans les systèmes pré-relationnels. Du point de vue de la théorie, déclarer le triplet {ClassConnecteur, FinishPlating, ShellSize} à la fois pour les tables ConnecteurDeRepos et Connecteur est parfaitement licite.

    Voyons voir maintenant le 2e scénario. Toujours dans la série attributs naturels (publics) et artificiels, techniques (privés), on peut une fois de plus utiliser des vues :

    — Concernant les connecteurs de repos, on peut reprendre la vue ConnecteurDeReposV ainsi que les triggers qui l’accompagnent (ConnecteurDeReposTR, ConnecteurDeReposTRdel et ConnecteurDeReposTRupd).

    — Concernant les autres connecteurs, on peut reprendre la vue ConnecteurVtout, mais en modifiant le SELECT (partie privée).

    Considérons à nouveau les tables de base de la 2e version :

     
    CREATE TABLE COMPOSANT
    (
       ComposantId          INT                  NOT NULL,
       ComposantPN          VARCHAR(6)           NOT NULL,
       Etc                  VARCHAR(64)          NOT NULL,
       CONSTRAINT COMPOSANT_PK PRIMARY KEY (ComposantId),
       CONSTRAINT COMPOSANT_AK UNIQUE (ComposantPN)
    ) ;
    
    CREATE TABLE ConnecteurDeRepos 
    (
       ComposantId          INT                  NOT NULL,
       ClassConnecteur      INT                  NOT NULL,
       FinishPlating        INT                  NOT NULL,
       ShellSize            INT                  NOT NULL,
       Designation          VARCHAR(64)          NOT NULL,
       CONSTRAINT ConnecteurDeRepos_PK PRIMARY KEY (ComposantId),
       CONSTRAINT ConnecteurDeRepos_AK UNIQUE (ClassConnecteur, FinishPlating, ShellSize),
       CONSTRAINT ConnecteurDeRepos_COMPOSANT_FK FOREIGN KEY (ComposantId)
          REFERENCES COMPOSANT (ComposantId) ON DELETE CASCADE
    ) ;
    
    CREATE TABLE Connecteur 
    (
       ComposantId          INT                  NOT NULL,
       ClassConnecteur      INT                  NOT NULL,
       FinishPlating        INT                  NOT NULL,
       ShellSize            INT                  NOT NULL,
       Designation          VARCHAR(64)          NOT NULL,
       Arrangement          VARCHAR(64)          NOT NULL,
       Polarisation         VARCHAR(64)          NOT NULL,
       ConnecteurType       VARCHAR(6)           NOT NULL,
       CONSTRAINT Connecteur_PK PRIMARY KEY (ComposantId),
       CONSTRAINT Connecteur_AK UNIQUE (ClassConnecteur, FinishPlating, ShellSize),
       CONSTRAINT Connecteur_COMPOSANT_FK FOREIGN KEY (ComposantId)
          REFERENCES COMPOSANT (ComposantId) ON DELETE CASCADE,
       CONSTRAINT Connecteur_ConnecteurDeRepos_FK FOREIGN KEY (ClassConnecteur, FinishPlating, ShellSize)
          REFERENCES ConnecteurDeRepos (ClassConnecteur, FinishPlating, ShellSize) ON DELETE NO ACTION
    ) ; 
    Le code de la création de la vue ConnecteurVtout devient le suivant :

    
    CREATE VIEW ConnecteurVtout (ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType)
    AS 
        SELECT x.ComposantPN, x.Etc, t.ComposantPN, z.ClassConnecteur, z.FinishPlating, z.ShellSize, y.Arrangement, y.Designation, y.Polarisation, y.ConnecteurType
        FROM   Composant as x JOIN Connecteur as y on x.ComposantId = y.ComposantId
                              JOIN ConnecteurDeRepos as z on y.ClassConnecteur  = z.ClassConnecteur AND y.FinishPlating = z.FinishPlating AND y.ShellSize = z.ShellSize
                              JOIN Composant AS t ON z.ComposantId = t.ComposantId
    ;
    

    Un trigger pour intercepter les inserts affectant la vue ConnecteurVtout et créer les connecteurs :

     
    CREATE TRIGGER ConnecteurTR ON ConnecteurVtout INSTEAD OF INSERT
    AS
    INSERT INTO Composant (ComposantPN, Etc)
        SELECT ComposantPN, Etc
        FROM   INSERTED 
    ;
    INSERT INTO Connecteur (ComposantId, ClassConnecteur, FinishPlating, ShellSize, Designation, Arrangement, Polarisation, ConnecteurType)
        SELECT y.ComposantId, ClassConnecteur, FinishPlating, ShellSize, Designation, Arrangement, Polarisation, ConnecteurType 
        FROM INSERTED AS x JOIN Composant AS y on x.ComposantPN = y.ComposantPN
    ;
    
    Un trigger pour la suppression des connecteurs :

    CREATE TRIGGER ConnecteurTRdel ON ConnecteurVtout INSTEAD OF DELETE
    AS
        DELETE FROM Composant
            WHERE ComposantPN IN (SELECT ComposantPN FROM DELETED)
    ;
    
    Un trigger pour la modification des connecteurs :

    CREATE TRIGGER ConnecteurTRupd ON ConnecteurVtout INSTEAD OF UPDATE
    AS
    IF UPDATE (ComposantPN)  
        BEGIN
            IF (SELECT COUNT(ComposantPN) FROM INSERTED) > 1
                BEGIN
                    RAISERROR ('Veuillez ne modifier qu''une clé ComposantPN à la fois. ', 16, 1)
                    ROLLBACK TRAN
                    RETURN
                END
            UPDATE Composant 
               SET ComposantPN = (SELECT ComposantPN FROM INSERTED) 
               WHERE  Composant.ComposantPN = (SELECT ComposantPN FROM DELETED)
            ;
        END
    IF UPDATE (Etc)
        BEGIN
            UPDATE Composant
                SET Etc = (SELECT Etc
                           FROM   INSERTED
                           WHERE  Composant.ComposantPN = INSERTED.ComposantPN)
                WHERE ComposantPN IN (SELECT Composant.ComposantPN
                                      FROM   Composant JOIN INSERTED
                                             ON Composant.ComposantPN = INSERTED.ComposantPN)
            ;
        END
    IF UPDATE (ClassConnecteur) or UPDATE (FinishPlating) or UPDATE (Shellsize)
        BEGIN
            UPDATE Connecteur
                SET ClassConnecteur = (SELECT ClassConnecteur
                                       FROM   INSERTED
                                       WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                                      )
                  , FinishPlating = (SELECT FinishPlating
                                     FROM   INSERTED
                                     WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                                    ) 
                  , Shellsize = (SELECT Shellsize
                                 FROM   INSERTED
                                 WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                                )
                WHERE ComposantId IN (SELECT Composant.ComposantId
                                      FROM   Composant JOIN INSERTED
                                             ON Composant.ComposantPN = INSERTED.ComposantPN)      
        END
    
    IF UPDATE  (Arrangement)
        BEGIN
            UPDATE Connecteur
            SET Arrangement = (SELECT Arrangement
                               FROM   INSERTED
                               WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                              )
            WHERE ComposantId IN (SELECT Composant.ComposantId
                                  FROM   Composant JOIN INSERTED
                                         ON Composant.ComposantPN = INSERTED.ComposantPN)      
        END
    IF UPDATE  (Designation)
        BEGIN
            UPDATE Connecteur
            SET Designation = (SELECT Designation
                               FROM   INSERTED
                               WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                              )	
            WHERE ComposantId IN (SELECT Composant.ComposantId
                                  FROM   Composant JOIN INSERTED
                                         ON Composant.ComposantPN = INSERTED.ComposantPN)
        END
    IF UPDATE  (Polarisation)
        BEGIN
            UPDATE Connecteur
            SET Polarisation = (SELECT Polarisation
                                FROM   INSERTED
                                WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                               )
            WHERE ComposantId IN (SELECT Composant.ComposantId
                                  FROM   Composant JOIN INSERTED
                                         ON Composant.ComposantPN = INSERTED.ComposantPN) 
        END
    IF UPDATE  (ConnecteurType)
        BEGIN
            UPDATE Connecteur
            SET ConnecteurType = (SELECT ConnecteurType
                                  FROM   INSERTED
                                  WHERE  Connecteur.ComposantId = (SELECT ComposantId FROM composant WHERE composantPN = INSERTED.ComposantPN)
                                 )
            WHERE ComposantId IN (SELECT Composant.ComposantId
                                  FROM   Composant JOIN INSERTED
                                         ON Composant.ComposantPN = INSERTED.ComposantPN)
        END
    ;
    
    Exemple d’ajout d’un connecteur :

    
    INSERT INTO ConnecteurVtout (ComposantPN, Etc, ConnecteurDeReposPN, ClassConnecteur, FinishPlating, ShellSize, Arrangement, Designation, Polarisation, ConnecteurType)
        VALUES ('cpn33', 'etc33', '', 'classe03', 'finish03', 'shell03', 'arr33', 'design33', 'polar33', 'conntype33') 
    ;
    
    A noter qu’on ne fournit pas de valeur pour l’attribut ConnecteurDeReposPN, car il ne participe en rien à la création du connecteur 'cpn33'.

    Exemple de modification d’un connecteur :

    Connecteur 'cpn31' : on remplace la valeur prise par les attributs suivants : ComposantPN, Etc, ClassConnecteur, FinishPlating, ShellSize, ConnecteurType.

     
    SELECT * FROM ConnecteurVtout WHERE ComposantPN = 'cpn31'
    
    =>
    
    ComposantPN    Etc    ConnecteurDeReposPN    ClassConnecteur    FinishPlating    ShellSize    Arrangement    Designation    Polarisation    ConnecteurType
    cpn31          etc31  cpn03                  classe03           finish03         shell03      arr31          design31       polar31         conntype31
    
    ----------------------------------------------------------------------------------
    
    UPDATE ConnecteurVtout 
        SET ComposantPN = 'cpn77'
          , Etc = 'etc98'
          , ClassConnecteur = 'classe04'
          , FinishPlating = 'finish04'
          , ShellSize = 'shell04'
    	  , ConnecteurType = 'contype99'
        WHERE ComposantPN = 'cpn31' ;
    
    ----------------------------------------------------------------------------------
    
    SELECT * FROM ConnecteurVtout WHERE ComposantPN = 'cpn77'
    
    =>
    
    ComposantPN    Etc    ConnecteurDeReposPN    ClassConnecteur    FinishPlating    ShellSize    Arrangement    Designation    Polarisation    ConnecteurType
    cpn77          etc98  cpn04                  classe04           finish04         shell04      arr31          design31       polar31         contype99 
     
    
    Supprimer les connecteurs de la classe classe04 :

    DELETE FROM ConnecteurVtout WHERE ClassConnecteur = 'classe04' 
    ;
    
    Pour conclure, sur la base des vues, les deux scénarios étudiés se valent. A vous de voir celui qui a votre faveur.
    (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.

  10. #10
    Membre du Club
    Homme Profil pro
    Transport et logistique
    Inscrit en
    Février 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Transport et logistique
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    Bonjour fsmrel,

    Je vous prie de m'excuser pour cette réponse un peu tardive, la raison étant qu'entre temps d'autre tâches jugées plus urgente ont fait leur apparition et nous avons dû nous en charger pendant le mois d'Avril afin d'avancer au plus vite.

    J'ai bien regardé et analysé vos propositions, maintenant je comprends; l'utilisateur à l'impression de manipuler les objets tels quel via les vues sauf que derrière tout ça il y a des opérations de contrôle. Ainsi avec les requêtes que vous me proposez la cohérence et cohésion des informations est maintenue à chaque instant.

    Maintenant je vais, grâce à vos propositions proposer deux solutions au client et à l'éditeur, ce sera au final ce dernier qui décidera le type de la solution. Puis par rapport à ce choix ce sera à moi de préparer ce travail des vues pour les autres associations entre les composants, et il y en a beaucoup donc ça me fait du pain sur la planche... Il faut déjà que je me forme un peu plus sur le langage sql car j'ai un peu de mal à comprendre les "x.ComposantId, etc" dans les SELECT mais j'ai d'ores et déjà compris dans l'idée les deux solutions.

    Je vous remercie encore fsmrel vous m'avez été d'une grande aide comme toujours. Je ne clôture pas le sujet car j'aurais surement d'autres questions qui me viendront à l'esprit

    Soit dit au passage, je vote

    Anthony

  11. #11
    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
    Bonjour Anthony,


    Les bases sont posées. Vous n’avez plus qu’à croiser les doigts et retrousser vos manches. Pour SQL, c’est comme la mayonnaise, une fois que ça a pris, c’est tout bon...Autrement dit, Alea jacta est !

    Bonne route
    (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.

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

Discussions similaires

  1. Plusieurs connections Oracle avec des connecteurs différents
    Par ToxiZz dans le forum Accès aux données
    Réponses: 0
    Dernier message: 31/10/2008, 11h57
  2. Origine et cible des connecteurs entre figures
    Par Gautheron dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 13/09/2008, 21h56
  3. [Etat-Transition] Sémantique des instructions entry, exit, on et do
    Par nikles007 dans le forum Autres Diagrammes
    Réponses: 4
    Dernier message: 10/10/2006, 18h32
  4. Sens des connecteurs sur carte mère
    Par SteelBox dans le forum Composants
    Réponses: 2
    Dernier message: 04/01/2006, 13h00
  5. Réponses: 4
    Dernier message: 04/08/2004, 13h26

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