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 :

Gestion des câbles électriques [MCD]


Sujet :

Schéma

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut Gestion des câbles électriques
    Bonjour,


    Je suis débutant en création de MCD / MLD / MPD et je dois réaliser pour un projet d'entreprise ces trois modèles conceptuels dans le but de créer proprement une base de données. J'ai lu plusieurs documents à ce sujet, j'en ai réalisé quelques uns au cours de mes études, mais là j'ai vraiment du mal.


    Énoncé :

    La base de données créée doit être adaptée à la gestion des lignes électriques.
    Les câbles sont portés par les pylônes (supports). La végétation croît en fonction de différents éléments (soleil, température, eau, etc).

    Pour cela j'ai créé plusieurs entités (conférer image):

    - Entité câble
    - Entité Support
    - Entité Végétation
    - Entité Zone de la végétation


    J'ai déjà réalisé un MCD mais je pense qu'il est rempli de fautes.

    Pouvez-vous le regarder et m'aider à le concrétiser ?


    Que pensez-vous des clés primaires?

    Pour moi les verbes d'associations ne sont pas vraiment pertinents, je n'ai mis de données portées dans ces associations, et j'ai des difficultés à établir les cardinalités... Je pense également à changer le type des attributs (text, numeric, ...).

    Je suis preneur de tout conseil pour l'améliorer ou le modifier.

    Je vous remercie d'avance,

    Cordialement,

    Loic


  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 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Message #2
    Bonsoir Loïc,


    Voilà un modèle bien étudié et intéressant.


    Citation Envoyé par LoicL89
    Je suis débutant en création de MCD / MLD / MPD et je dois réaliser pour un projet d'entreprise ces trois modèles conceptuels.
    Bon début donc, mais on verra que techniquement, sur le fond, il y aura des aménagements à prévoir, en tout cas, pas de panique...

    En attendant, un seul des trois modèles est conceptuel, comme son nom l’indique, c’est le modèle conceptuel des données (MCD). Bien sûr, les deux autres ont un côté conceptuel, mais l’usage établi est de les qualifier de «*logique*» (modèle logique des données) et de « physique » (modèle physique des données).


    Citation Envoyé par LoicL89
    Pour moi les verbes d'associations ne sont pas vraiment pertinents.
    Ça n’est pas bien grave, ne perdez pas votre temps dans une quête pour laquelle on n’est jamais satisfait, tout le monde n’est pas Victor Hugo ou Paul Verlaine...


    Sur la forme :

    Évidemment, comme vous le subodorez, déjà sur la forme il y a à redire.

    1) Il est préférable que le nom de chaque type d’entité (ou entité-type) soit au singulier. En effet, une entité-type fait l’objet d’un prédicat (un énoncé vérifonctionnel, c'est-à-dire pouvant prendre la valeur de vérité vrai ou faux ) :

    Si le prédicat CAPITALE a la structure suivante :

    La ville Ville est la capitale du pays Pays

    Ce prédicat est vrai pour la proposition suivante : La ville 'Paris' est la capitale du pays 'France' ;

    Il est faux pour la proposition suivante : La ville 'Paris' est la capitale du pays 'Italie'.

    2) Je vous laisse le choix des propositions, qu’on retrouvera sous forme de lignes dans des tables SQL...

    3) Pour éviter des problèmes syntaxiques idiots au niveau SQL, évitez les espaces dans les noms des entités-types*: écrivez «*Adresse_Client*» plutôt que «*Adresse Client*», même principe pour les noms d’attributs : « Nom_Client » plutôt que « Nom Client ». (Notez qu’il est aussi préférable d’éviter les accents aigus et autres*:*Categorie*» plutôt que «*Catégorie*» , même chose, évitons les cédilles et autres symboles graphiques pouvant faire tousser le SGBD).

    4) Distinguons le concept de « type d’entité » (alias entité-type) de celui d’« entité » : une entité est une instance, une occurrence (en Merise) d’un type d’entité. Le type d’entité fait l’objet d’un prédicat, alors qu’une entité fait l’objet d’une proposition.

    5) Personnellement j’écris en lettres capitales (non accentuées) les noms des entités-types parce que je m’y retrouve mieux, ainsi, j’écris «*ADRESSE_CLIENT*»plutôt que «*Adresse_Client*»mais faites à votre convenance.


    Sur le fond :

    Citation Envoyé par LoicL89
    Pensez-vous que les attributs caractérisent bien les différentes entités ?
    Nous ne connaissons pas votre métier, nous ne sommes que des profanes, donc c’est vous qui savez...


    Remarque (Q1) : Je note dans telle entité-type X un attribut A « Appartient à Y » : si cet attribut A est un des attributs de l’entité-type Y, alors cet attribut A est redondant et doit être éliminé de X.



    Citation Envoyé par LoicL89
    j'ai des difficultés à établir les cardinalités.
    D'accord. Pour chaque association R entre les entités-types E1 et E2, vous pouvez vous inspirer de ceci :

    Une occurrence de E1 peut être associée à plusieurs occurrence de E2

    =>

    [ E1 ]----0,N--------(R)


    Une occurrence de E1 est associée à au moins une occurrence de E2

    =>

    [ E1 ]----1,N--------(R)


    Une occurrence de E1 peut être associée à au plus une occurrence de E2

    =>

    [ E1 ]----0,1--------(R)


    Une occurrence de E1 est associée à au moins une et au plus une occurrence de E2

    =>

    [ E1 ]----1,1--------(R)

    (one and only one comme disent les anglophones).



    Question (Q2) : d’après le MCD, une végétation est associée à au moins une dynamique de la végétation et une dynamique de la végétation est associée à au moins et au plus une végétation. Est-ce bien ce que vous avez voulu modéliser ?



    Citation Envoyé par LoicL89
    Que pensez-vous des clés primaires ?
    Une clé primaire doit être invariante, non significative, cachée à l’utilisateur qui ne doit connaître que les clés «*naturelles*». Autrement dit, toutes vos clés étant naturelles, elles deviennent alternatives et chaque entité-type doit être dotée d’un attribut « artificiel » répondant aux critères que j’ai mentionnés. Je vous invite à parcourir le billet que j’ai commis à ce sujet.


    En passant : dans un MCD on n’utilise pas le concept de « clé primaire », mais celui d’« identifiant ». L’auteur de l’outil que vous utilisez s’est planté.

    Quoi qu'il en soit, remontons au niveau conceptuel et prenons l’exemple de l’entité-type CLIENT : elle doit être dotée d’un identifiant « artificiel », inodore et sans saveur, à savoir un attribut ClientId (choisissez le nom qui vous convient), de type entier, devenant clé primaire au niveau SQL et y faisant l’objet d’un auto-incrément si vous souhaitez vous décharger sur votre SGBD de l’affectation des valeurs pour cet attribut.


    Question (Q3) : au fait, quel est (ou sera) votre SGBD ?


    Il y aura quelques entités-types de référence à prévoir. Par exemple, une entité-type des communes, à laquelle seront associées les entités-types concernées (CABLE, SUPPORT, etc.)


    Allez, on y arrivera, bon courage !
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut Message #3
    Bonjour fsmrel,


    Tout d'abord merci beaucoup pour votre aide ! J'ai déjà mieux compris certains éléments de conception d'un MCD*

    Sur la forme, j'ai suivi vos conseils : nom de chaque type d'entité au singulier, suppression des espaces dans les noms des attributs et des entités-types, suppression des accents, etc.


    Sur le fond maintenant :

    Question Q1 : Je ne comprends pas trop comment sait-on à quelle autre entité appartient un point (XYZ) de l'entité-type VEGETATION s'il n'y a pas la présence de cet attribut ?


    Question Q2 : Je voulais faire l'inverse ! Une végétation est associée à une seule dynamique de végétation (donc cardinalité 1,1) et une dynamique de végétation peut être associée à plusieurs végétations (cardinalité 1,n). J'ai modifié le MCD pour que cela convienne.


    Pour les autres cardinalités:

    - Un câble est porté uniquement par deux supports : cardinalité (1,1) et le support peut porter un ou plusieurs câbles : cardinalité (1,n), il y a au moins une occurrence de support qui est associé à une occurrence de câble.

    - Une occurrence de l'entité-type CABLE peut être associée à plusieurs occurrences de l'entité-type VEGETATION, et inversement : cardinalité (0,n) dans les deux sens.


    Ok pour l'identifiant des entités-types, j'ai mieux compris et changé les identifiants pour chacune des entités-types.


    Question Q3 : J'utiliserai Access comme SGBD. M'en conseillez-vous un autre qui soit non payant?


    J'ai également rajouté une entité-type COMMUNE comme conseillé.


    Les cardinalités pour l'entité-type COMMUNE : les câbles et les supports peuvent se trouver sur une ou plusieurs communes (s'ils sont en limite) donc cardinalité (1,n), et une commune est associée à au moins une et au plus une occurrence de chaque autre entité-type donc cardinalité (1,1).

    Pour finir deux petites questions supplémentaires : Lorsque je crée un attribut, la case "null" est cochée, je n'arrive pas bien à saisir son utilité et son intérêt ?

    Je vous remercie encore pour votre aide,

    Cordialement,

    Loic


  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 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #4
    Bonsoir Loïc,



    Citation Envoyé par LoicL89
    Je ne comprends pas trop comment sait-on à quelle autre entité appartient un point (XYZ) de l'entité-type VEGETATION s'il n'y a pas la présence de cet attribut ?
    Disons que pour le moment (mais ça ne durera pas^^), vous mélangez les modes de fonctionnement du MCD et du MLD.

    Supposons que je modélise une entité-type ARBRE caractérisée par une ou plusieurs végétations, au niveau MCD j’aurais quelque chose comme ceci*:


    MCD



    Alors, selon l’association CARACTERISER, une occurrence de l’entité-type VEGETATION fait référence à exactement une occurrence de l’entité-type ARBRE, en conséquence de quoi, lors de la dérivation du MCD en MLD tabulaire, la règle est que l’attribut ArbreId de la table ARBRE sera recopié dans la table VEGETATION. En effet, on déboule alors dans l’univers relationnel (qui est l’objet de la théorie relationnelle), qui fonctionne par association des valeurs des attributs. Dans le diagramme (MLD) ci-dessous, la flèche (source VEGETATION, portée ARBRE) symbolise le fait qu’une valeur de l’attribut ArbreId de la table VEGETATION est aussi (nécessairement) une valeur de l’attribut ArbreId de la table ARBRE (principe de l’intégrité référentielle). Si un attribut est souligné, c’est qu’il participe à la clé primaire (singleton dans l’exemple) : deux arbres ne peuvent pas avoir la même valeur pour l’attribut ArbreId (intégrité d’entité). De la même façon, deux végétations ne peuvent pas avoir la même valeur pour l’attribut VegetationId (mais peuvent avoir même valeur pour l’attribut ArbreId : ce sont alors des végétations caractérisant un même arbre).

    MLD




    Au stade SQL, pour connaître la hauteur de l’arbre référencé par la végétation 123, on effectuera la jointure des deux tables en fonction de l’attribut ArbreId :

    En SQL :

    
    SELECT ArbreNo, Hauteur
    FROM   ARBRE JOIN VEGETATION ON ARBRE.ArbreId = VEGETATION.ArbreId
    WHERE  VegetationId = 123 ;
    
    
    Un francophone doit lire à l’envers (de bas en haut) : Pour la végétation 123, joignons les tables VEGETATION et ARBRE en fonction de l’attribut ArbreId pour récupérer le numéro de l’arbre concerné et sa hauteur.

    N.B. Faites moi penser à commenter la présence des mickeys <ak> et <fk> dans les diagrammes ci-dessus.



    Citation Envoyé par LoicL89
    (Q2) Une végétation est associée à une seule dynamique de végétation (donc cardinalité 1,1) et une dynamique de végétation peut être associée à plusieurs végétations (cardinalité 1,n). J'ai modifié le MCD pour que cela convienne.
    Soit vous écrivez : une dynamique de végétation peut être associée à plusieurs végétations (cardinalité 0,n) ;

    Soit vous écrivez : une dynamique de végétation est associée à au moins une végétation (cardinalité 1,n).



    Citation Envoyé par LoicL89
    (Q4) Un câble est porté uniquement par deux supports : cardinalité (1,1).
    Ben non, s’il y a deux supports, soit c’est une cardinalité 2,2, soit il y a deux associations à cardinalité 1,1...
    En l’occurrence, on va privilégier la 2e solution, ne serait-ce que parce qu’au niveau SQL c’est incomparablement plus simple à gérer.


    MCD




    MLD




    Citation Envoyé par LoicL89
    (Q3) J'utiliserai Access comme SGBD. M'en conseillez-vous un autre qui soit non payant ?
    Quand j'étais opérationnel, j’utilisais DB2 (payant, du lourd !) Dans les gratuits, il y a PostgreSQL que j’ai un peu chahuté et a très bonne réputation, il est nettement supérieur à MySQL que j’utilise à l’occasion pour traiter des questions posées dans les forums de Developpez.com. Par exemple, PostgreSQL offre des options de contrôle intra table absentes chez MySQL, il permet de mettre à jour les vues via des triggers, alors que MySQL ne sait pas faire, etc. Pour sa part, ACCESS m’énerve un peu (euphémisme)...



    Citation Envoyé par LoicL89
    Pour l'entité-type TYPE DE VEGETATION, je n'en ai pas créé.
    Je vous engage à le faire quand même, comme on procède traditionnellement pour les typologies (type de quelque chose).


    Citation Envoyé par LoicL89
    Quote=LoicL89]Les cardinalités pour l'entité-type COMMUNE : les câbles, les supports peuvent se trouver sur une ou plusieurs communes (s'ils sont en limite) donc cardinalité (1,n), et une commune est associée à au moins une et au plus une occurrence de chaque autre entité-type donc cardinalité (1,1).
    J’ai du mal à saisir... Quand je passe dans telle commune, voisine de la mienne, j’y observe quelques pylônes, bien alignés (avec des maisons pratiquement sous les câbles)...

    En passant, l’attribut Commune doit disparaître des entités-types où il figure.

    Un support peut être à cheval sur combien de communes ?



    Citation Envoyé par LoicL89
    Pour finir deux petites questions supplémentaires : Lorsque je crée un attribut, la case "null" est cochée, je n'arrive pas bien à saisir son utilité et son intérêt ?
    Le bonhomme Null est l’ennemi des bases de données, il faut à tout prix l’empêcher de se manifester : dans les scripts SQL, en regard de chaque attribut, on doit trouver le bouclier « NOT NULL ». On en reparlera plus tard, car on entre dans l’univers de la logique ternaire, laquelle à suscité bien des bagarres chez les théoriciens.
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #5
    Bonjour fsmrel,


    Oui je crois que je confonds MCD et MLD, voir MPD. D'accord, c'est donc lors de la conception du MLD que les attributs sont recopiés dans les tables concernés.


    Pouvez-vous m'expliquer les "mickeys" <ak>, <fk>, <ai>, <pi> etc. que vous avez inscrit dans les MCD/MLD ?


    Q2*: Ok pour les phrases, une dynamique de végétation peut en effet être associée à plusieurs végétations (cardinalité 0,n).


    Q4 : C'est bien ce que je pensais mais je croyais qu'on ne pouvait pas affecter de cardinalité 2,2 dans un MCD. J'ai opté pour la deuxième solution.


    Q3 : Ok pour PostgreSQL, j'essaierai selon le temps que j'ai lorsque j'en serai au SGBD, sinon je resterai sur Access que je connais un peu. PostgreSQL est-il facile à prendre en main? Ou faut-il de bonnes connaissances en SGBD?


    Pour les cardinalités de l'entité-type COMMUNE, un câble (étant donnée la longueur) peut se situer sur une ou plusieurs communes (bien que le cas soit rare).


    D'accord pour la case "null", j'ai donc décoché la case pour chaque attribut.


    Merci pour votre aide,

    Cordialement,

    Loic


  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 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #6
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    Oui je crois que je confonds MCD et MLD, voir MPD. D'accord, c'est donc lors de la conception du MLD que les attributs sont recopiés dans les tables concernés. Il s'agira ensuite de réaliser des jointures par attribut si j'ai bien compris.
    Oui. Cf. la requête que j’avais proposée pour récupérer la hauteur de l’arbre auquel fait référence la végétation 123 :

    
    SELECT ArbreNo, Hauteur
    FROM   ARBRE JOIN VEGETATION ON ARBRE.ArbreId = VEGETATION.ArbreId
    WHERE  VegetationId = 123 ;
    
    

    Citation Envoyé par LoicL89
    Pouvez-vous m'expliquer les "mickeys" <ak>, <fk>, <ai>, <pi> etc. que vous avez inscrit dans les MCD/MLD ?
    Dans les diagrammes que je vous ai présentés, j’ai utilisé PowerAMC. Y relèvent du MCD les mickeys suivants : <pi> et <ai>.

    Relèvent du MLD (MPD pour PowerAMC, mais peu importe) les mickeys <pk>, <ak>, <fk>.

    En préambule, je rappelle que, pour deux occurrences d’une entité-type donnée, la valeur de l’identifiant doit être différente (contrainte d’unicité).

    < pi> est l’abréviation de « primary identifier », il s’agit donc de l’identifiant principal d’une entité-type. L’outil que vous utilisez (JMerise) utilise pour sa part le mickey <PrK>, abréviation de « primary key », mais c’est une erreur, car qui dit MCD en Merise dit identifiant d’entité-type et non pas clé primaire, terme inconnu au niveau MCD et qui relève du MLD et de SQL.

    < ai> est l’abréviation de « alternate identifier », il s’agit d’un identifiant alternatif, ayant les mêmes propriétés que l’identifiant principal (conformité à la contrainte d’unicité) mais jugé « moins égal »... Disons (au moins dans propre système) que l’identifiant principal est artificiel, invariant, sans signification et sans intérêt pour l’utilisateur qui n’a accès qu’aux attributs « naturels » : par exemple l’attribut SupportId est identifiant principal de SUPPORT, tandis que l’attribut Numero, dédié à l’utilisateur, est identifiant alternatif (l’utilisateur, peut en changer les valeurs si ça lui chante, peu me chaut).

    N.B. Il y a 20 ans, bien des théoriciens de Merise refusaient le concept même d’identifiant alternatif : «*il y a un identifiant, point barre*». Mais si je définis une entité-type ELEMENT à partir du tableau ci-dessous (cf. Wikipedia), n’y a-t-il pas quelques identifiants candidats à être alternatifs ? (y-compris le numéro atomique !) Je pense qu’aujourd’hui les mentalités ont évolué...




    < pk> est l’abréviation de « primary key », il s’agit donc de la clé primaire d’une table. En général, la clé primaire est issue :

    — De l’identifiant primaire d’une entité-type ;

    — De l’union des identifiants primaires des entités-types connectées par une association de plusieurs à plusieurs : par exemple, l’association AMORCER connecte les entités-types VEGETATION et CABLE, elle donne donc lieu à la table AMORCER ayant pour clé primaire la paire {VegetationId, CableId}.

    < ak> est l’abréviation de « alternate key » : une clé alternative d’une table est issue d’un identifiant alternatif d’entité-type.

    < fk> (FrK pour votre outil) est l’abréviation de « foreign key » (clé étrangère). Une clé étrangère n’a pas à respecter la contrainte d’unicité des clés, le terme « foreign key » est donc impropre, mais il est passé dans l’usage il y a 45 ans, on ne reviendra donc pas dessus... Plus important, une clé étrangère permet de garantir l’intégrité référentielle. Il s’agit là d’un point capital, à défaut on peut par exemple trouver des câbles «*orphelins*» de supports. A l’occasion des nombreux audits que j’ai effectués, j’ai mis en évidence des contrats d’assurance faisant référence à des clients inexistants, même chose pour des prêts financiers, ou, dans le monde de la cotisation pour la retraite, des périodes de carrière faisant référence à des cotisants devenus inconnus, donc en réalité lésés (avec un grand B...), etc., etc.

    N.B. Une clé candidate (c'est-à-dire primaire ou alternative) peut être simultanément clé étrangère.

    A cette occasion, revoyez le billet traitant de tout ça, et méditez ce qu’écrivit Yves Tabourier.



    Citation Envoyé par LoicL89
    Q3 : Ok pour PostgreSQL, j'essaierai selon le temps que j'ai lorsque j'en serai au SGBD, sinon je resterai sur Access que je connais un peu. PostgreSQL est-il facile à prendre en main? Ou faut-il de bonnes connaissances en SGBD ?
    Disons qu’il faut connaître SQL, mais ça n’est pas un langage bien compliqué à apprendre. ACCESS est pour sa part basé sur QBE (Query By Example), mais je le trouve bridant... Un SGBD comme PostgreSQL est quand même plus convaincant.


    Citation Envoyé par LoicL89
    Pour les cardinalités de l'entité-type commune, un câble (étant donnée la longueur) peut se situer sur une ou plusieurs communes (bien que le cas soit rare).
    Admettons, mais on reviendra sans doute plus tard sur ce point. Lorsque je vois que dans une commune on ne peut trouver qu’un câble, je me demande : mais de quel type de câble s’agit-il donc pour qu’existe une telle contrainte ?


    Êtes-vous sûr de la règle qui me fait tousser :

    Un support se situe dans au moins une commune ; une commune héberge un et un seul support.


    Citation Envoyé par LoicL89
    Pensant que le MCD était quasiment fini, j'ai essayé de réaliser le MLD (à l'aide du logiciel, JMerise qui le fait automatiquement).
    Disons que les assises du MCD ont l’air d’être correctes, mais Paris ne s’est pas fait en un jour, et on peut toujours découvrir des loups (c’est même la loi du genre !) Nonobstant, rien n’empêche de produire un MLD et le script SQL de création des tables, quitte à itérer N fois sur la génération du MCD, donc de ses dérivés.



    Citation Envoyé par LoicL89
    Il me reste donc le Modèle physique de données pour pouvoir créer ma table dans Access si je comprends bien les étapes.
    Si vous voulez, mais plus prosaïquement, disons qu’il s’agit du script SQL de création des tables, mais n'oubliez pas qu'on aura certainement à itérer la dérivation, suite aux aménagements successifs du MCD...

    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.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #7
    Bonjour fsmrel,


    D'accord j'ai compris pour l'identifiant principal et l'identifiant alternatif. Votre exemple sur le tableau des éléments atomiques est très clair, comme ce qu'écrit Yves Tabourier.


    Je voulais donc définir le nom de la commune dans l'entité-type COMMUNE, le numéro du support dans l'entité-type SUPPORT en identifiant alternatif mais je n'arrive pas à le régler dans JMerise... J'ai le choix entre PRIMARY KEY, UNIQUE ou INDEX...


    Vous avez raison, la règle "Un support se situe dans au moins une commune ; une commune héberge un et un seul support" est fausse. Un support se situe dans au moins une commune, une commune peut héberger plusieurs supports, donc cardinalités (0,n) (raisonnement identique pour les câbles). J'ai donc modifié ces éléments dans le MCD.


    Voyez-vous encore d'autres améliorations à apporter au MCD? Il faut également que j'arrive à fixer ces identifiants alternatifs... (MCD joint).


    D'accord, oui je comprends bien que plusieurs itérations seront nécessaires avant d'arriver au résultat final.


    Merci pour votre réponse,

    Cordialement,

    Loic


  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 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #8
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    Je voulais donc définir le nom de la commune dans l'entité-type COMMUNE, le numéro du support dans l'entité-type SUPPORT en identifiant alternatif mais je n'arrive pas à le régler dans JMerise... J'ai le choix entre PRIMARY KEY, UNIQUE ou INDEX...
    Les différents outils n’utilisent pas forcément les mêmes noms et symboles...

    Peut-être que JMerise utilise déjà pour le MCD la batterie des termes qui valent au niveau SQL. Comme je l’ai signalé, son abréviation « PrK » veut manifestement dire « primary key », terme qu’on n’emploie pas dans Merise au stade conceptuel (MCD), mais au niveau SQL. Restons donc un moment en SQL et traduisons dans ce langage la structure suivante*: une table CARRE des carrés de mon potager et une table PLANTE des plantes que ma femme y a plantées et qu’elle entretient avec amour, et que mes fils taillent quand elles deviennent un peu trop exubérantes*:





    Dans le style PostgreSQL :

    
    CREATE TABLE CARRE 
    (
            CarreId                      SERIAL
          , Nom                          VARCHAR(32)       NOT NULL
        , CONSTRAINT CARRE_PK PRIMARY KEY (CarreId)
    ) ;
    
    CREATE TABLE PLANTE 
    (
            PlanteId                     SERIAL
          , Numero_Plante                INTEGER           NOT NULL
          , Hauteur                      DECIMAL(4,2)      NOT NULL
          , Annee_Plantation             SMALLINT          NOT NULL
          , CarreId                      INTEGER           NOT NULL
        , CONSTRAINT PLANTE_PK PRIMARY KEY (PlanteId) 
        , CONSTRAINT PLANTE_AK UNIQUE (Numero_Plante) 
        , CONSTRAINT PLANTE_CARRE_FK FOREIGN KEY (CarreId)
              REFERENCES CARRE (CarreId) ON DELETE CASCADE
    ) ;
    
    
    Observations :

    (1) Le langage SQL utilise le terme (la clause) PRIMARY KEY pour la clé primaire d’une table, mais pour les clés alternatives, c’est le terme UNIQUE (cas de l’attribut Numero_Plante).

    (2) Je sous-traite au SGBD l’affectation des valeurs prises par l’attribut PlanteId : c’est un auto-incrément.

    (3) Je fournis le nom des contraintes (par défaut, je ne sais pas quels noms sont donnés...)

    (4) Le type DOUBLE (virgule flottante) n’est pas trop recommandé : pour la hauteur des plantes, à mon sens la virgule fixe s’impose (DECIMAL).

    (5) L’attribut Age pose un problème, car pour chaque plante il faut penser à le modifier annuellement : il est préférable de le remplacer par la date de plantation. Pour connaître l’âge d’une plante, PostgreSQL fournit la fonction permettant de connaître la date du jour ou le mois, etc. Par exemple, pour obtenir l’année en cours : EXTRACT (ISOYEAR FROM CURRENT_DATE), et pour l’âge disons qu’il n’y a plus qu’à soustraire l’année de plantation.

    Pour illustrer, créons un micro jeu d’essai :

    
    INSERT INTO CARRE (Nom) VALUES  ('carré 01') ;
    INSERT INTO CARRE (Nom) VALUES  ('carré 02') ;
    
    SELECT * FROM CARRE ;
    
    
    =>

    
    CarreId    Nom
    -------    --------
          1    carré 01
          2    carré 02
    
    
    
    INSERT INTO PLANTE (Numero_Plante, Hauteur, Annee_Plantation, CarreId) 
        VALUES  (25, 12.5, 1980, 2) ;
    INSERT INTO PLANTE (Numero_Plante, Hauteur, Annee_Plantation, CarreId) 
        VALUES  (28, 10.5, 1982, 1) ;
    
    SELECT * FROM PLANTE ;
    
    
    =>

    
    PlanteId    Numero_Plante    Hauteur    Annee_Plantation    CarreId
    --------    -------------    -------    ----------------    -------
           1               25      12.50    1980                      2
           2               28      10.50    1982                      1
    
    
    Pour l’utilisateur que les attributs PlanteId et CarreId n’intéressent pas, mais qui veut connaître l’âge des plantes et le nom du carré où elles vivent :

    
    SELECT Numero_Plante, Hauteur, EXTRACT (ISOYEAR FROM CURRENT_DATE) - Annee_Plantation AS Age, Nom AS Nom_Carre 
    FROM   PLANTE AS x JOIN CARRE AS y ON x.CarreId = y.CarreId ;
    
    
    =>

    
    Numero_Plante    Hauteur    Age    Nom_Carre
    -------------    -------    ---    ---------   
               25      12.50     35    carré 02
               28      10.50     33    carré 01
    
    
    C’est-y pas beau comme l’antique ? Reste à savoir si de son côté JMerise génère la clause UNIQUE lors de la production des scripts de CREATE TABLE, vous me direz...


    (6) Notez la clause CASCADE : elle permet de sous-traiter un certain métabolisme des données au SGBD, du fait des stimuli émis par les carrés et dont les liens clé étrangère - clé primaire (ou alternative) entre les tables sont les vecteurs. Cette clause signifie ceci :

    « Si quelqu’un détruit le carré où nous vivons, alors, nous, les plantes qui y poussons, acceptons de disparaître avec lui, car nous n’avons aucune possibilité de nous y opposer »...
    (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
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #9
    Bonjour fsmrel,


    Quelques remarques et questions en attendant la suite de votre réponse*:


    (3) Je fournis le nom des contraintes (par défaut, je ne sais pas quels noms sont donnés...)
    Je ne vois pas à quoi correspondent ces "contraintes", pour moi une contrainte correspond à définir s'il s'agit d'une clé primaire, alternative ou étrangère, par exemple dans la table PLANTE, vous avez appelé les contraintes "PLANTE_PK", PLANTE_AK" et "PLANTE_CARRE_FK" :

    
        , CONSTRAINT PLANTE_PK PRIMARY KEY (PlanteId) 
        , CONSTRAINT PLANTE_AK UNIQUE (Numero_Plante) 
        , CONSTRAINT PLANTE_CARRE_FK FOREIGN KEY (CarreId) 
              REFERENCES CARRE (CarreId) ON DELETE CASCADE
    
    
    Les attributs sur lesquels les contraintes sont appliquées (clé primaire, alternative ou étrangère) sont déjà définis par PlanteId, Numero_Plante, CarreId ?*


    (6) Notez la clause CASCADE : elle permet de sous-traiter un certain métabolisme des données au SGBD, du fait des stimuli émis par les carrés et dont les liens clé étrangère - clé primaire (ou alternative) entre les tables sont les vecteurs. Cette clause signifie ceci*:

    « Si quelqu’un détruit le carré où nous vivons, alors, nous, les plantes qui y poussons, acceptons de disparaître avec lui, car nous n’avons aucune possibilité de nous y opposer »...
    Très intéressante cette clause, elle s'applique parfaitement pour la situation.


    Une dernière question, non vraiment en rapport avec le MCD ou MLD, mais savez-vous comment à partir de données linéaires peut-on joindre une table contenant les attributs du câble? Pour moi l'identifiant CableID doit se retrouver dans un fichier dessin pour par la suite réaliser une jointure par attribut, mais je ne vois pas comment affecter les ID dans le fichier dessin.


    Merci pour vos réponses,

    Cordialement

    Loic

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #11
    Bonjour fsmrel,


    Pour ne plus avoir de problèmes d'interprétation j'ai changé les cardinalités des entités-types SUPPORT et CABLE vers l'entité type Commune en (1,1), le cas où un support se situe sur plusieurs communes reste rare.


    Lorsque j'édite le code SQL dans JMerise, comment l'intégrer dans Access par la suite ?


    Cordialement,

    Loic

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #14
    Bonjour fsmrel,


    Un autre souci en essayant de remplir les tables : la table CABLE possède désormais SupportID et SupportID_Support (en raison des associations portée départ, portée arrivée), je ne peux pas renommer les attributs sinon il y a perte de lien entre les tables?


    Et pour finir : comment remplir la table Amorcer ? Elle ne doit pas se remplir automatiquement en raison des relations fixées?
    Parce que je ne vois pas comment la remplir.


    Cordialement,

    Loic

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #13
    Bonjour fsmrel,


    Quelques changements ont eut lieu dans le MCD*:

    - ajout/suppression de quelques attributs dans différentes entités-types

    - ajout de l'entité-type LIGNE


    Citation Envoyé par fsmrel
    (Rcsc) Un câble est porté par un support de départ et un support d’arrivée. Si ces supports sont situés dans la même commune, par transitivité, le câble est situé dans cette commune. Si ces supports sont situés dans deux communes distinctes, du fait de la transitivité, le câble est « à cheval » sur ces communes.
    Comment dans une table Access indiquer qu'un câble est sur deux communes? Il faut créer deux lignes décrivant ce câble?


    Citation Envoyé par fsmrel
    mais alors reste quand même à régler le cas des communes sur lesquelles passent des câbles mais dont les supports ne sont pas dans ces communes.
    N.B. On pourra réglera le problème des cas exceptionnels des supports et arbres à cheval sur deux communes par des associations ad-hoc, on pourra en reparler.
    Qu'est-ce qu'une association ad-hoc?


    Merci pour votre explication pour Access, je cherchais à faire toutes les étapes d'un seul coup en chargeant le fichier .sql mais je n'ai pas trouvé. J'ai donc suivi votre méthode.

    Voyez-vous des incohérences dans ce nouveau MCD*?

    Cordialement,

    Loic


  13. #13
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #12
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    Pour ne plus avoir de problèmes d'interprétation j'ai changé les cardinalités des entités-types SUPPORT et CABLE vers l'entité type Commune en (1,1), le cas où un support se situe sur plusieurs communes reste rare.
    D’accord. On part donc sur les règles suivantes*:

    (Ras) Un support est situé dans une seule commune et une commune peut avoir plusieurs supports.

    (Rcsc) Un câble est porté par un support de départ et un support d’arrivée. Si ces supports sont situés dans la même commune, par transitivité, le câble est situé dans cette commune. Si ces supports sont situés dans deux communes distinctes, du fait de la transitivité, le câble est «*à cheval*» sur ces communes. Quoi qu’il en soit, on peut supprimer l’association (devenue redondante) connectant CABLE et COMMUNE, mais alors reste quand même à régler le cas des communes sur lesquelles passent des câbles mais dont les supports ne sont pas dans ces communes.

    N.B. On pourra réglera le problème des cas exceptionnels des supports et arbres à cheval sur deux communes par des associations ad-hoc, on pourra en reparler.


    Citation Envoyé par LoicL89
    Lorsque j'édite le code SQL dans JMerise, comment l'intégrer dans Access par la suite?
    Pour importer le texte d’un CREATE TABLE dans ACCESS (j’utilise ici la version 2013, en langue étrangère)*:

    Prenons l’exemple d’une table TYPE_VEGETATION associée à une table ARBRE. On passe par l’onglet CREATE du menu, et on clique sur l’icône «*Query Design*»*:





    ACCESS ouvre la fenêtre «*Show Table*», dont on se contrefout ici, par contre l’icône «*SQL*» nous intéresse vivement*:





    On ferme donc la fenêtre «*Show Table*» pour avoir accès à l’icône «*SQL*». Au résultat, on a droit à une instruction SELECT, modifiable*:





    On peut maintenant saisir le texte qu’on veut, on va donc remplacer par un copier/coller le texte proposé («*SELECT*») par le CREATE TABLE de la table qu’on veut déclarer (l’auto-incrémentation fait l’objet du type AUTOINCREMENT)*:





    On ferme la fenêtre, qui pour le moment s’appelle «*Query1*». Quand ACCESS demande si on veut enregistrer ce qu’on a fait, on lui répond «*Un peu mon neveu*! » en cliquant sur le bouton «*YES*»*:





    Nommons la requête, par exemple « CREATE_TABLE_TYPE_VEGETATION » (mnémonique oblige ) :





    On sauvegarde la requête «*CREATE_TABLE_TYPE_VEGETATION. Au résultat*:





    Un clic droit sur le nom de la requête pour en voir la structure ACCESS (via «*Design View)*:





    Au résultat*:





    On peut maintenant créer les lignes de la table.



    On procède de la même façon avec la table ARBRE*:




    N.B. J’ai remplacé le type DECIMAL par le type DOUBLE, car ce chameau d’ACCESS le rejette.

    Sauvegardons la déclaration*:





    N.B. A propos de la clé étrangère (contrainte ARBRE_TYPE_VEGETATION_FK)*: vous pouvez omettre la déclaration de la contrainte et l’implémenter plus tard par ALTER TABLE.

    Quoi qu’il en soit, au résultat, la table ARBRE existe*:





    Et les associations sont en place*:





    Y a plus qu’à...
    (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.

  14. #14
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #10
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    Citation Envoyé par fsmrel
    (3) Je fournis le nom des contraintes (par défaut, je ne sais pas quels noms sont donnés...)
    J e ne vois pas à quoi correspondent ces "contraintes", pour moi une contrainte correspond à définir s'il s'agit d'une clé primaire, alternative ou étrangère, par exemple dans la table PLANTE, vous avez appelé les contraintes "PLANTE_PK", PLANTE_AK" et "PLANTE_CARRE_FK":

    
        , CONSTRAINT PLANTE_PK PRIMARY KEY (PlanteId)
        , CONSTRAINT PLANTE_AK UNIQUE (Numero_Plante)
        , CONSTRAINT PLANTE_CARRE_FK FOREIGN KEY (CarreId)
               REFERENCES CARRE (CarreId) ON DELETE CASCADE
    
    
    Certes, définir une clé primaire, une clé alternative, une clé étrangère c’est définir une contrainte. Supposons maintenant que je nomme pas les contraintes :

    
        , PRIMARY KEY (PlanteId) 
        , UNIQUE (Numero_Plante) 
        , FOREIGN KEY (CarreId)
    
    
    Si par mégarde je tente de créer une ligne dont la valeur viole une des contraintes, le SGBD me rappellera à l’ordre en précisant le nom de la contrainte en cause :

    «*Violation of UNIQUE KEY constraint 'UQ__PLANTE__C28CD6E0EC03422D'. Cannot insert duplicate key in object PLANTE.*»

    En considérant le début du nom de la contrainte : "UQ", je peux en déduire que c’est la clé alternative dont il s’agit.

    Mais si je code

    
    CREATE TABLE ELEMENT
    (
            NoAtomique           INT                  NOT NULL
          , Nom                  VARCHAR(16)          NOT NULL
          , Symbole              VARCHAR(3)           NOT NULL
          , MasseAtomique        DECIMAL(10,6)        NOT NULL
          , MasseVolumique20d    DECIMAL(6,2)         NOT NULL
          , PointFusion          DECIMAL(6,2)         NOT NULL
          , PointEbullition      DECIMAL(6,2)         NOT NULL
          , AnneeDecouverte      SMALLINT             NOT NULL
          , Decouvreur           VARCHAR(32)          NOT NULL   
        , PRIMARY KEY (NoAtomique)
        , UNIQUE (Nom)
        , UNIQUE (Symbole)
        , UNIQUE (MasseAtomique)
        , UNIQUE (MasseVolumique20d)
        , UNIQUE (PointFusion)
        , UNIQUE (PointEbullition)
    ) ;
    
    
    Et si j’ai droit à la remontrance :

    «*Violation of UNIQUE KEY constraint 'UQ__ELEMENT__3EBEC7448FFF07E2'. Cannot insert duplicate key in object 'ELEMENT'.*»

    Alors cette fois-ci j’ai bonne mine, il va falloir que je passe un peu de temps pour isoler la contrainte touchée...

    Mais tout ceci est assez secondaire. Il y a surtout que les noms des contraintes (et bien entendu toutes leurs caractéristiques) sont engrangés dans le catalogue relationnel (la métabase) et cette fois-ci, en tant que DBA (administrateur de la base de données), j’ai besoin de maîtriser ces noms selon une grammaire définie par l’équipe des DBA de l’entreprise où je sévis. Ne serait-ce que d’un point de vue mnémo(tech)nique, faire participer le nom de la table SQL (c'est-à-dire le nom de l’entité-type du MCD) ainsi que le type de la contrainte m’a toujours bien servi depuis 30 ans que je pratique SQL... Si donc je code :

    CONSTRAINT ELEMENT_AK_MasseAtomique UNIQUE (MasseAtomique)

    Mes collègues DBA n’y verront certes aucun inconvénient, bien au contraire...

    Même principe pour chaque clé étrangère : je fais intervenir en plus le nom de la table cible.



    Citation Envoyé par LoicL89
    Un support se situe dans au moins une commune, une commune peut héberger plusieurs supports, donc cardinalités (0,n) J'ai donc modifié ces éléments dans le MCD.
    D’accord. Il faudra trouver un moyen de s’assurer que, dans la base de données, un support ne pourra pas se situer à la fois à Arles, Brest, Colmar et Lille...

    Par ailleurs, un lecteur attentif pourra objecter que, selon le MCD, rien n’empêche que, selon l’association SITUER2, un support <s1> soit associé à un ensemble (a priori légal) de communes EC1, mais que via les associations PORTER A et PORTER B, <s1> soit associé à un ensemble (a priori légal lui aussi !) de communes EC2, tel que EC1 ∩ EC2 = ∅ ou bien EC1 ⊄ EC2 (genre d’anomalie que j’ai débusquée dans bien des bases de données...)


    Citation Envoyé par LoicL89
    Une dernière question, non vraiment en rapport avec le MCD ou MLD, mais savez-vous comment à partir de données linéaires peut-on joindre une table contenant les attributs du câble? Pour moi l'identifiant CableID doit se retrouver dans un fichier dessin pour par la suite réaliser une jointure par attribut, mais je ne vois pas comment affecter les ID dans le fichier dessin.
    Je ne suis pas bien sûr d’avoir compris votre problème.

    S’il s’agit d’affecter automatiquement les valeurs des clés, les SGBD prennent en charge l’auto-incrémentation (type SERIAL dans le cas de PostgreSQL). Mais ce ne fut pas toujours le cas et, il y a 20 ans (cas de DB2 for MVS/ESA, version 4 que j’utilisais à l’époque), on se débrouillait quand même, grâce à la fonction MAX, épaulée par la fonction COALESCE.

    Par exemple, commençons par définir la structure (simplifiée) de la table PLANTE :

    
    CREATE TABLE PLANTE 
    ( 
            PlanteId                  INTEGER             NOT NULL 
          , Numero_Plante             INTEGER             NOT NULL 
          , Hauteur                   DECIMAL(4,2)        NOT NULL 
          , Annee_Plantation          SMALLINT            NOT NULL 
        , CONSTRAINT PLANTE_PK PRIMARY KEY (PlanteId)
    
    
    Pour créer une ligne de la table, avec Numero_Plante = 25, Hauteur = 12.5 et Annee_Plantation = 1980, on peut coder :

    
    INSERT INTO PLANTE (PlanteId, Numero_Plante, Hauteur, Annee_Plantation)
       SELECT COALESCE(MAX(PlanteId) + 1, 1), 25, 12.5, 1980
       FROM   PLANTE ;
    
    
    La fonction COALESCE affectera à l’attribut PlanteId soit la valeur maximale PlanteId + 1 si cet attribut n’est pas marqué NULL (on « auto-incrémente » donc), soit la valeur 1 si l’attribut PlanteId est marqué NULL (c'est-à-dire si la table est vide).

    Dans cet exemple, l’attribut PlanteId prendra successivement les valeurs 1, 2, 3, ..., i, i + 1, ....

    Si on souhaite commencer avec la valeurs 100, et un pas d’incrément valant 10, on remplace la requête INSERT par la suivante :

    
    INSERT INTO PLANTE (PlanteId, Numero_Plante, Hauteur, Annee_Plantation)
       SELECT COALESCE(MAX(PlanteId) + 10, 100) , 25, 12.5, 1980
       FROM   PLANTE ;
    
    
    Évidemment c’est moins léger que lorsque le SGBD s'en occupe, mais ça fonctionne... Maintenant, j’ai peut-être mal interprété le sens de votre question, mais ce qui précède est toujours bon à savoir. Si votre problème est d’arriver à effectuer des jointures entre des fichiers externes et des tables SQL (mariage de la carpe et du lapin ?) j’ai besoin d’en savoir plus. A quoi ressemble la structure d’un tel fichier ? Le logiciel connaît-il l’algèbre relationnelle ?
    (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.

  15. #15
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #15
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    ajout de l'entité-type LIGNE.
    Je suppose qu’une ligne est un ensemble de câbles et de supports, mais pouvez-vous en dire plus au profane ? Une ligne peut-elle être vue comme une chaîne, une succession, une séquence déterminée de câbles ?


    Citation Envoyé par fsmrel
    J’ai remplacé le type DECIMAL par le type DOUBLE, car ce chameau d’ACCESS le rejette.
    En fait, pour que ça marche, il me suffisait de faire : ACCESS OPTIONS > OBJECT DESIGNERS et cocher « SQL Server Compatible Syntax (Ansi92) ». Mais je n’utilise ACCESS qu’occasionnellement, et vous me donnez ici l’occasion de m’entraîner ^^


    Citation Envoyé par LoicL89
    Citation Envoyé par fsmrel
    Rcsc) Un câble est porté par un support de départ et un support d’arrivée. Si ces supports sont situés dans la même commune, par transitivité, le câble est situé dans cette commune. Si ces supports sont situés dans deux communes distinctes, du fait de la transitivité, le câble est « à cheval » sur ces communes.
    Comment dans une table Access indiquer qu'un câble est sur deux communes? Il faut créer deux lignes décrivant ce câble?
    Citation Envoyé par LoicL89
    Un autre souci en essayant de remplir les tables : la table CABLE possède désormais SupportID et SupportID_Support (en raison des associations portée départ, portée arrivée), je ne peux pas renommer les attributs sinon il y a perte de lien entre les tables?
    On peut nommer les attributs comme bon nous chante. Les liens ne sont pas perdus, voyez les contraintes CONSTRAINT CABLE_SUPPORT_DEPART et CONSTRAINT CABLE_SUPPORT_ARRIVEE ci-dessous.

    Allons-y pour coder :

    TABLE COMMUNE :

    
    CREATE TABLE COMMUNE
    (
            CommuneId            SERIAL
          , CommuneInsee         INTEGER                 NOT NULL
          , CommuneNom           VARCHAR(32)             NOT NULL
        , CONSTRAINT COMMUNE_PK PRIMARY KEY (CommuneId)
        , CONSTRAINT COMMUNE_AK UNIQUE (CommuneInsee) 
    ) ;
    

    TABLE SUPPORT :

    
    CREATE TABLE SUPPORT 
    (
            SupportId                SERIAL
          , SupportNo                INTEGER                NOT NULL
          , CommuneId                INTEGER                NOT NULL
        , CONSTRAINT SUPPORT_PK PRIMARY KEY (SupportId) 
        , CONSTRAINT SUPPORT_NO_AK UNIQUE (SupportNo) 
        , CONSTRAINT SUPPORT_COMMUNE_FK FOREIGN KEY (CommuneId)  
              REFERENCES COMMUNE (CommuneId)  
    ) ;
    

    TABLE CABLE :

    
    CREATE TABLE CABLE
    (
            CableId             SERIAL
          , SupportDepartId     INTEGER            NOT NULL
          , SupportArriveeId    INTEGER            NOT NULL
        , CONSTRAINT CABLE_PK PRIMARY KEY (CableId)
        , CONSTRAINT CABLE_SUPPORT_DEPART FOREIGN KEY (SupportDepartId)  
              REFERENCES SUPPORT (SupportId)
        , CONSTRAINT CABLE_SUPPORT_ARRIVEE FOREIGN KEY (SupportArriveeId)  
              REFERENCES SUPPORT (SupportId)
    ) ;
    

    Un micro jeu d’essai :

    
    INSERT INTO COMMUNE (CommuneInsee, CommuneNom) VALUES (56061, 'La Gacilly') ;
    INSERT INTO COMMUNE (CommuneInsee, CommuneNom) VALUES (35328, 'Sixt-sur-Aff') ;
    INSERT INTO COMMUNE (CommuneInsee, CommuneNom) VALUES (35168, 'Maure-de-Bretagne') ;
    
    
    =>

    
    CommuneId    CommuneInsee    CommuneNom
    ---------    -----------     ----------
            1    56061           La Gacilly
            2    35328           Sixt-sur-Aff
            3    35168           Maure-de-Bretagne
    
    
    
    INSERT INTO SUPPORT (SupportNo, CommuneId) VALUES (123, 1) ;
    INSERT INTO SUPPORT (SupportNo, CommuneId) VALUES (234, 2) ;
    INSERT INTO SUPPORT (SupportNo, CommuneId) VALUES (456, 3) ;
    
    

    =>

    
    SupportId    SupportNo    CommuneId
    ---------    ---------    ---------
            1          123            1
            2          234            2
            3          456            3
    
    

    
    INSERT INTO CABLE (SupportDepartId, SupportArriveeId) VALUES (1, 2) ;
    INSERT INTO CABLE (SupportDepartId, SupportArriveeId) VALUES (2, 3) ;
    
    

    =>

    
    CableId    SupportDepartId    SupportArriveeId
    -------    ---------------    ----------------
          1                  1                   2
          2                  2                   3
    
    

    Pour poser la question : de quelle commune part le câble 1 et où aboutit-il :

    
      SELECT 'a : Départ' AS Support, CableId, CommuneInsee, CommuneNom
      FROM (CABLE INNER JOIN SUPPORT ON CABLE.SupportDepartId = SUPPORT.SupportId) 
           INNER JOIN COMMUNE ON SUPPORT.CommuneId = COMMUNE.CommuneId
      WHERE CableId  = 1
    UNION 
      SELECT 'b : Arrivée', CableId, CommuneInsee, CommuneNom
      FROM (CABLE INNER JOIN SUPPORT ON CABLE.SupportArriveeId = SUPPORT.SupportId) 
           INNER JOIN COMMUNE ON SUPPORT.CommuneId = COMMUNE.CommuneId
      WHERE CableId = 1 ;
    
    

    Le 1er SELECT permet de récupérer la ville de départ du câble 1 et le 2e SELECT permet de récupérer la ville d’arrivée de ce câble 1. Par UNION on obtient :

    
    Support      CableId    CommuneInsee    CommuneNom 
    -----------  -------    ------------    ----------- 
    a : Départ         1    56061           La Gacilly
    b : Arrivée        1    35328           Sixt-sur-Aff
    
    
    Manifestement, le câble 1 a bien un support de départ dans une commune et un support d’arrivée dans une autre.



    Citation Envoyé par LoicL89
    Comment remplir la table Amorcer ? Elle ne doit pas se remplir automatiquement en raison des relations fixées?
    C’est l’utilisateur qui sait quelles sont les associations à établir entre les tables CABLE et VEGETATION. On a un échantillon ci-dessus du contenu de la table CABLE.

    Supposons que la table VEGETATION ait la structure (simplifiée) définie par l’instruction suivante :

    
    CREATE TABLE VEGETATION
    (
            VegetationId          SERIAL
          , DateReleve            DATE
          , DynamiqueId           INTEGER
        , CONSTRAINT VEGETATION_PK PRIMARY KEY (VegetationId)
        , CONSTRAINT VEGETATION_DYNAMIQUE_FK FOREIGN KEY (DynamiqueId) 
              REFERENCES DYNAMIQUE_VEGETATION (DynamiqueVegetationId)
    ) ;
    
    
    Créons un échantillon pour cette table :

    
    VegetationId    DateReleve    DynamiqueId
    ------------    ----------    -----------
               1    03/06/2015              1
               2    03/06/2015              1
               3    04/06/2015              1
               4    04/06/2015              2
    
    
    Définition de la structure (simplifiée) de la table AMORCER :

    
    CREATE TABLE AMORCER
    (
            VegetationId            INTEGER           NOT NULL
          , CableId                 INTEGER           NOT NULL
        , CONSTRAINT AMORCER_PK PRIMARY KEY (VegetationId, CableId)
        , CONSTRAINT AMORCER_VEGETATION_FK FOREIGN KEY (VegetationId) 
              REFERENCES VEGETATION (VegetationId)
        , CONSTRAINT AMORCER_CABLE_FK FOREIGN KEY (CableId) REFERENCES CABLE (CableId)
    ) ;
    
    
    Associons la végétation 1 (attribut VegetationId) au câble 2 (attribut CableId) :

    
    INSERT INTO AMORCER (VegetationId, CableId) VALUES (1, 2) ;
    
    
    =>

    
    VegetationId    CableId 
    ------------    ------- 
               1          2 
    
    
    A cette occasion, je rappelle qu’en principe l’utilisateur n’a pas accès aux attributs identifiants (artificiels et invariants, je le rappelle). Ainsi, devrait-il disposer d’un attribut (par exemple NumeroCable) lui permettant d’identifier à sa façon, « naturellement », une entité-type telle que CABLE. Même principe pour VEGETATION. Maintenant si l’utilisateur n’éprouve pas le besoin de disposer d’un identifiant naturel pour ses câbles, et si CableId lui suffit, alors d’accord, on lui montre cet attribut, mais qu’il sache qu’il n’a aucunement le pouvoir de l’altérer.



    Citation Envoyé par LoicL89
    Qu'est-ce qu'une association ad-hoc?
    Partons de la situation la plus courante : un support est localisé dans une seule commune :




    Supposons qu’un support soit à cheval sur deux communes, ce qui est très rare d’après ce que j’ai compris. Si vous avez besoin d’en tenir compte, une association de secours, ad-hoc peut faire l’affaire :

    Les supports supplémentaires seront associés aux communes correspondantes au moyen de l’association CAS_RARE :




    En passant, un point déjà effleuré : est-il réaliste qu’un câble partant d’un support situé dans une commune A, aboutisse directement à un support situé dans une commune Z tout en passant « au-dessus » d’une commune M sans support intermédiaire dans M ?



    Citation Envoyé par LoicL89
    Merci pour votre explication pour Access, je cherchais à faire toutes les étapes d'un seul coup en chargeant le fichier .sql mais je n'ai pas trouvé. J'ai donc suivi votre méthode.
    Si vous connaissez VBA, vous pouvez tout faire d’un coup.


    On aura à reparler des contraintes de chemin, de l’entité-type LIGNE, de l’association SITUER1.
    (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.

  16. #16
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #16
    Bonjour fsmrel et merci pour vos réponses.


    Citation Envoyé par fsmrel
    Je suppose qu’une ligne est un ensemble de câbles et de supports, mais pouvez-vous en dire plus au profane ? Une ligne peut-elle être vue comme une chaîne, une succession, une séquence déterminée de câbles ?
    C'est bien ça : une ligne est un ensemble de câbles + supports, il s'agit juste d'un nom la désignant.

    Ok pour les tables AMORCER, SITUER et CABLE, je reviendrais vers vous si j'ai des problèmes (en espérant que non et que tout fonctionne !*)


    Citation Envoyé par fsmrel
    En passant, un point déjà effleuré : est-il réaliste qu’un câble partant d’un support situé dans une commune A, aboutisse directement à un support situé dans une commune Z tout en passant « au-dessus » d’une commune M sans support intermédiaire dans M ?
    Oui cette situation est possible.


    Citation Envoyé par fsmrel
    On aura à reparler des contraintes de chemin, de l’entité-type LIGNE, de l’association SITUER1.
    Qu'appelez-vous contraintes de chemin ? Les différentes relations entre entité-type ?
    L'association SITUER 1 pose problème ?

    Merci,

    Cordialement,

    Loic

  17. #17
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #17
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    Qu'appelez-vous contraintes de chemin ?
    Prenons le cas du câble C1, ayant pour support de départ le support S1 et pour support d’arrivée le support S2. Selon le MCD, rien n’interdit que S1 fasse référence à la ligne L1 et que S2 fasse référence à la ligne L2, auquel cas, par transitivité, le câble C1 ferait référence à deux lignes distinctes, et tant qu'à faire, possiblement différentes de la ligne L3 directement référencée par C1 (c'est-à-dire par l’association APPARTENIR connectant LIGNE et CABLE)...

    En effet, on a trois « chemins » possibles pour « aller » d’un câble à une ligne :

    Le 1er via l’association APPARTENIR connectant LIGNE et CABLE ;

    Le 2e via l’association PORTER_A puis l’association APPARTENIR connectant SUPPORT et LIGNE ;

    Le 3e via l’association PORTER_B puis l’association APPARTENIR connectant SUPPORT et LIGNE.


    Dans un tel contexte, par contrainte de chemin, j’entends ceci :

    (a) Si C1 a pour support de départ S1 et pour support d’arrivée S2, alors S1 et S2 sont contraints à appartenir à la même ligne, disons L1. A défaut, C1 ne peut pas être créé dans la base de données.

    (b) La ligne à laquelle C1 fait directement référence (via l’association APPARTENIR), doit être L1 elle aussi.

    En fait, l’association APPARTENIR connectant LIGNE et CABLE doit disparaître, car la ligne à laquelle appartient un câble ne peut être que celle de ses supports, autrement dit cette association est redondante, et comme vous le savez, la redondance a une fâcheuse tendance à ficher la patouille dans les bases de données. En plus, évitons de dire deux fois la même chose, quand une fois suffit.

    Dans ces conditions, une fois supprimée l’association redondante APPARTENIR, il reste à faire respecter la contrainte de chemin faisant l’objet du point (a).

    Le défi est de ne pas avoir à garantir cette contrainte par du code développé dans l’application, car la base de données et le code applicatif peuvent évoluer chacun de leur côté. La norme SQL permet à cet effet que l’on définisse une contrainte au moyen de l’instruction CREATE ASSERTION et c’est alors à la charge du SGBD de faire respecter la loi. De leur côté, les éditeurs de SGBD renâclent et ne nous proposent pas cette instruction : on pallie par des triggers, à savoir du code qu’on développe soi–même, mais qui devient un composant du moteur relationnel, il en fait désormais partie intégrante.

    Pour voir les choses de plus près, considérons les structures suivantes pour les tables LIGNE, SUPPORT, CABLE et COMMUNE (pour changer un peu de PostgreSQL et d’ACCESS (lequel est bogué quant aux triggers et nous prend en plus pour des demeurés), je passe à MySQL...) :


    
    CREATE TABLE COMMUNE
    (
            CommuneId            INTEGER                 NOT NULL   AUTO_INCREMENT
          , CommuneInsee         INTEGER                 NOT NULL
          , CommuneNom           VARCHAR(32)             NOT NULL
        , CONSTRAINT COMMUNE_PK PRIMARY KEY (CommuneId)
        , CONSTRAINT COMMUNE_AK UNIQUE (CommuneInsee) 
    ) ;
    
    
    CREATE TABLE LIGNE 
    (
            LigneId                  INTEGER                NOT NULL   AUTO_INCREMENT
          , LigneNom                 VARCHAR(32)            NOT NULL
          , Tension                  INTEGER                NOT NULL
        , CONSTRAINT LIGNE_PK PRIMARY KEY (LigneId) 
    ) ;
    
    
    CREATE TABLE SUPPORT 
    (
            SupportId                INTEGER                NOT NULL   AUTO_INCREMENT
          , SupportNo                INTEGER                NOT NULL
          , CommuneId                INTEGER                NOT NULL
          , LigneId                  INTEGER                NOT NULL
        , CONSTRAINT SUPPORT_PK PRIMARY KEY (SupportId) 
        , CONSTRAINT SUPPORT_NO_AK UNIQUE (SupportNo) 
        , CONSTRAINT SUPPORT_COMMUNE_FK FOREIGN KEY (CommuneId)  
              REFERENCES COMMUNE (CommuneId)  
        , CONSTRAINT SUPPORT_LIGNE_FK FOREIGN KEY (LigneId)  
              REFERENCES LIGNE (LigneId) 
    ) ;
    
    
    CREATE TABLE CABLE
    (
            CableId             INTEGER            NOT NULL   AUTO_INCREMENT
          , CableCode           CHAR(5)            NOT NULL
          , SupportDepartId     INTEGER            NOT NULL
          , SupportArriveeId    INTEGER            NOT NULL
        , CONSTRAINT CABLE_PK PRIMARY KEY (CableId)
        , CONSTRAINT CABLE_AK UNIQUE (CableCode)    
        , CONSTRAINT CABLE_SUPPORT_DEPART FOREIGN KEY (SupportDepartId)  
              REFERENCES SUPPORT (SupportId)
        , CONSTRAINT CABLE_SUPPORT_ARRIVEE FOREIGN KEY (SupportArriveeId)  
              REFERENCES SUPPORT (SupportId)
    ) ;
    
    
    Allons-y pour créer un trigger affecté aux ajouts (il en faudrait un autre pour les modifications), opération réalisée au moyen de l’instruction CREATE TRIGGER :

    
    CREATE TRIGGER CABLE_LIGNE_COHERENCE BEFORE INSERT ON CABLE 
    FOR EACH ROW
    BEGIN 
        IF 1 < (
                SELECT COUNT(*) 
                FROM (SELECT x.LigneId
                      FROM   SUPPORT AS x JOIN LIGNE AS y ON x.LigneId = y.LigneId
                      WHERE  new.SupportDepartId = x.SupportId
                      UNION
                      SELECT x.ligneid
                      FROM   SUPPORT AS x JOIN LIGNE AS y ON x.LigneId = y.LigneId
                      WHERE  new.SupportArriveeId = x.SupportId
                     ) AS t
                )  
            THEN 
                SET @Err = CONCAT ('CableCode = ', new.CableCode, ' : La ligne du support de départ est différente de celle du support d''arrivée.') ;
                SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @Err ;
        END IF ;
    END 
    
    
    Bon d’accord, ça n’est pas intuitif, mais on s’y met assez vite, et surtout ça permet de garantir que les supports de départ et d’arrivée d’un câble appartiennent bien à la même ligne. Si on tente des ajouts délinquants, ils seront rejetés, avec un message d’erreur à la clé. Maintenant, avec ACCESS et ses triggers foireux, il faudra peut-être en passer par VBA, mais ça n’est pas sain, puisqu’on se rabat sur du code applicatif échappant à la surveillance du SGBD.


    Passons à l’association SITUER1. Maintenant, c’est l’entité-type COMMUNE qui est partie prenante. Le problème est cette-fois-ci que, non seulement SITUER1 doit connecter un câble aux communes hébergeant son support de départ et son support d’arrivée, mais en plus cette association doit permettre de connecter un câble et les communes qu’il traverse sans pour autant que ces communes hébergent des supports...

    Déclarons la table SITUER1 :

    
    CREATE TABLE SITUER1
    (
            CableId             INTEGER            NOT NULL
          , CommuneId           INTEGER            NOT NULL
        , CONSTRAINT SITUER1_PK PRIMARY KEY (CableId, CommuneId)  
        , CONSTRAINT SITUER1_CABLE_FK FOREIGN KEY (CableId)  
              REFERENCES CABLE (CableId) ON DELETE CASCADE
        , CONSTRAINT SITUER1_COMMUNE_FK FOREIGN KEY (CommuneId)  
              REFERENCES COMMUNE (CommuneId)
    ) ;
    
    On définit le trigger qui, une fois créé un câble C1, permet d’ajouter automatiquement dans la table SITUER1 les deux paires de valeurs <C1, K1> et <C1, K2> correspondant aux communes K1 et K2 hébergeant les supports de départ et d’arrivée du câble C1 (si c’est la même commune qui héberge les supports, c'est-à-dire si K1 = K2, seule sera ajoutée la valeur <C1, K1>).

    Pour les communes traversées par C1 mais n’hébergeant pas de support, ça sera à l’application d’effectuer les ajouts <Cx, Kx>.
    .

    
    CREATE TRIGGER CABLE_LIGNE_SITUER1 AFTER INSERT ON CABLE 
    FOR EACH ROW
        BEGIN 
            INSERT INTO SITUER1 (CableId, CommuneId)
                SELECT new.CableId, y.CommuneId
                FROM   SUPPORT AS y    
                WHERE  new.SupportDepartId = y.SupportId ;
                
            INSERT INTO SITUER1 (CableId, CommuneId)
                SELECT new.CableId, y.CommuneId
                FROM   SUPPORT AS y    
                WHERE  new.SupportArriveeId = y.SupportId 
                  AND  NOT EXISTS (SELECT ''
                                   FROM   SITUER1 AS z
                                   WHERE  new.CableId = z.CableId 
                                     AND  y.CommuneId = z.CommuneId) ;
        END
    
    
    (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.

  18. #18
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #18
    Bonjour fsmrel, et encore merci pour votre aide !*

    Concernant l'association AMORCER entre l'entité-type VEGETATION et CABLE, la végétation peut affecter désormais un seul câble, changeant ainsi la cardinalité en 1,1. En effet nous décidons pour l'instant de considérer un seul câble entre deux supports pour faciliter les traitements. (voir MCD ci-joint, quelques changements d'attributs ont également étaient effectués).


    Citation Envoyé par fsmrel
    En effet, on a trois « chemins » possibles pour « aller » d’un câble à une ligne :

    Le 1er via l’association APPARTENIR connectant LIGNE et CABLE ;
    Le 2e via l’association PORTER_AU_DEPART puis l’association APPARTENIR connectant SUPPORT et CABLE ;
    Le 3e via l’association PORTER_A_L_ARRIVEE puis l’association APPARTENIR connectant SUPPORT et CABLE.
    Effectivement, j'ai donc supprimé dans un premier temps l'association appartenir.


    Citation Envoyé par fsmrel
    (Rcsc) Un câble est porté par un support de départ et un support d’arrivée. Si ces supports sont situés dans la même commune, par transitivité, le câble est situé dans cette commune. Si ces supports sont situés dans deux communes distinctes, du fait de la transitivité, le câble est « à cheval » sur ces communes. Quoi qu’il en soit, on peut supprimer l’association (devenue redondante) connectant CABLE et COMMUNE, mais alors reste quand même à régler le cas des communes sur lesquelles passent des câbles mais dont les supports ne sont pas dans ces communes.
    J'ai supprimé l'association SITUER1 pour faciliter le traitement, et je n'utilise pas ainsi le trigger, seuls les supports permettront de connaître la commune. Ca devenait un peu trop compliqué... Par contre le trigger permettant de satisfaire la condition suivante sera bien conservé.


    Citation Envoyé par fsmrel
    Si C1 a pour support de départ S1 et pour support d’arrivée S2, alors S1 et S2 sont contraints à appartenir à la même ligne, disons L1. A défaut, C1 ne peut pas être créé dans la base de données.
    Je n'ai pas eu l'occasion de l'essayer encore, je reviendrais vers vous si je n'y arrive pas.


    Citation Envoyé par fsmrel
    Le bonhomme Null est l’ennemi des bases de données, il faut à tout prix l’empêcher de se manifester : dans les scripts SQL, en regard de chaque attribut, on doit trouver le bouclier « NOT NULL ». On en reparlera plus tard, car on entre dans l’univers de la logique ternaire, laquelle à suscité bien des bagarres chez les théoriciens.
    Pouvez-vous m'en dire plus sur ce fameux "Null"?


    Citation Envoyé par fsmrel
    On peut nommer les attributs comme bon nous chante. Les liens ne sont pas perdus, voyez les contraintes CONSTRAINT CABLE_SUPPORT_DEPART et CONSTRAINT CABLE_SUPPORT_ARRIVEE ci-dessous.
    Je suis complètement perdu sur ce point. J'ai effectué votre méthode :

    
    CREATE TABLE public.CABLE(
            CableID                 SERIAL,
            Support_arriereID       INT  NOT NULL ,
            Support_avantID         INT  NOT NULL ,
            SupportID               INT  NOT NULL ,
            SupportID_SUPPORT       INT  NOT NULL ,
          CONSTRAINT prk_constraint_CABLE PRIMARY KEY (CableID) ,
          CONSTRAINT CABLE_SUPPORT_DEPART FOREIGN KEY (Support_arriereID)  
                REFERENCES public.SUPPORT(SupportId) ,
          CONSTRAINT CABLE_SUPPORT_ARRIVEE FOREIGN KEY (Support_avantID) 
               REFERENCES public.SUPPORT(Supportid)
    )WITHOUT OIDS;
    
    
    Alors que je ne veux plus les attributs : supportid et supportid_support... Je ne vois pas trop, malgré votre exemple, comment on peut reconnaître le support arrivée et le support départ...


    Finalement, je me suis mis à PostgreSQL car Access m'a également légèrement agacé.

    Je pense que le MCD joint est la version finale, qu'en pensez-vous? Voyez-vous encore des défauts ou améliorations?

    Cordialement,

    Loic


  19. #19
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    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 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut #19
    Bonsoir Loïc,


    Citation Envoyé par LoicL89
    J'ai supprimé l'association SITUER1 pour faciliter le traitement, et je n'utilise pas ainsi le trigger, seuls les supports permettront de connaître la commune.
    Et il reste facile de connaître la (ou les deux) communes d’un câble en fonction de ses supports :

    
    SELECT DISTINCT CableId, t.CommuneNom As CommuneNomDepart, u.CommuneNom AS CommuneNomArrivee
    FROM CABLE AS x   INNER JOIN SUPPORT AS y ON x.SupportDepartId = y.SupportId
                      INNER JOIN SUPPORT AS z ON x.SupportArriveeId = z.SupportId
                      INNER JOIN COMMUNE AS t ON y.CommuneId = t.CommuneId
                      INNER JOIN COMMUNE AS u ON z.CommuneId = u.CommuneId ;
    
    


    Citation Envoyé par LoicL89
    Je rappelle qu’en principe l’utilisateur n’a pas accès aux attributs identifiants (artificiels et invariants, je le rappelle). Ainsi, devrait-il disposer d’un attribut (par exemple NumeroCable) lui permettant d’identifier à sa façon, « naturellement », une entité-type telle que CABLE. Maintenant si l’utilisateur n’éprouve pas le besoin de disposer d’un identifiant naturel pour ses câbles, et si CableId lui suffit, alors d’accord, on lui montre cet attribut, mais qu’il sache qu’il n’a aucunement le pouvoir de l’altérer.
    Quelle est votre position à ce sujet ?



    Citation Envoyé par LoicL89
    Je pense que le MCD joint est la version finale, qu'en pensez-vous? Voyez-vous encore des défauts ou améliorations?
    Votre MCD a bien maigri, mais il reste évolutif, je ne trouve rien à redire.

    Un point de détail : quand je vois : Longueur_portee DECIMAL (15,2)

    Alors je dis que vous prévoyez large, ça permet d’avoir des câbles faisant un paquet de fois la distance de notre vieille Terre à Pluton !



    Citation Envoyé par LoicL89
    Finalement, je me suis mis à PostgreSQL car Access m'a également légèrement agacé.
    Dont acte !



    Citation Envoyé par LoicL89
    Citation Envoyé par fsmrel
    On peut nommer les attributs comme bon nous chante. Les liens ne sont pas perdus, voyez les contraintes CONSTRAINT CABLE_SUPPORT_DEPART et CONSTRAINT CABLE_SUPPORT_ARRIVEE ci-dessous.
    Je suis complètement perdu sur ce point. J'ai effectué votre méthode :

    
    CREATE TABLE public.CABLE(
            CableID                 SERIAL,
            Support_arriereID       INT  NOT NULL ,
            Support_avantID         INT  NOT NULL ,
            SupportID               INT  NOT NULL ,
            SupportID_SUPPORT       INT  NOT NULL ,
          CONSTRAINT prk_constraint_CABLE PRIMARY KEY (CableID) ,
          CONSTRAINT CABLE_SUPPORT_DEPART FOREIGN KEY (Support_arriereID)  
              REFERENCES public.SUPPORT(SupportId) ,
          CONSTRAINT CABLE_SUPPORT_ARRIVEE FOREIGN KEY (Support_avantID) 
              REFERENCES public.SUPPORT(Supportid)
    )WITHOUT OIDS; 
    
    
    A lieu d’écrire : « On peut nommer les attributs comme bon nous chante », j’aurais dû écrire : « On peut renommer les attributs comme bon nous chante »...

    Je suppose que vous avez ajouté manuellement les attributs Support_arriereID et Support_avantID dans le script. C’est cela ?

    Si oui, ils font double emploi avec ceux qui ont été générés par JMerise, à savoir SupportID et SupportID_SUPPORT qui sont moins « causants » et c’est eux qui dans mon esprit devaient faire l’objet d’un renommage en Support_arriereID et Support_avantID.

    Dans ces conditions, après ménage et renommage, le script devrait ressembler à ceci :

    
    CREATE TABLE public.CABLE
    (
            CableID                 SERIAL,
            Support_arriereID       INT  NOT NULL ,
            Support_avantID         INT  NOT NULL ,
            CONSTRAINT prk_constraint_CABLE PRIMARY KEY (CableID) ,
            CONSTRAINT CABLE_SUPPORT_DEPART FOREIGN KEY (Support_arriereID)  
                REFERENCES public.SUPPORT(SupportId) ,
            CONSTRAINT CABLE_SUPPORT_ARRIVEE FOREIGN KEY (Support_avantID) 
                REFERENCES public.SUPPORT(Supportid)
    ) ;
    
    

    Une contrainte à ajouter, et qui peut être utile, on n’est jamais trop prudent : pour un câble donné, le support de départ doit être différent du support d’arrivée :

    CONSTRAINT CABLE_SUPPORT_COHERENT CHECK (Support_arriereID <> Support_avantID)



    Citation Envoyé par LoicL89
    Pouvez-vous m'en dire plus sur ce fameux "Null"?
    Voyez par exemple ici ou encore ici.

    En cherchant dans les forums de DVP les mots-clés « bonhomme », « null », vous devriez dénicher des variations sur ce thème...
    (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.

  20. #20
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2015
    Messages : 44
    Points : 11
    Points
    11
    Par défaut #20
    Bonjour fsmrel,


    Citation Envoyé par fsmrel
    Une contrainte à ajouter, et qui peut être utile, on n’est jamais trop prudent : pour un câble donné, le support de départ doit être différent du support d’arrivée :

    CONSTRAINT CABLE_SUPPORT_COHERENT CHECK (Support_arriereID <> Support_avantID)
    Oui cette contrainte est intéressante. J'aimerais également en ajouter une qui oblige à ce que la distance cumulée (dans la table support) d'un support n + 1 soit forcément supérieure à la distance cumulée d'un support n.



    Citation Envoyé par fsmrel
    Allons-y pour créer un trigger affecté aux ajouts (il en faudrait un autre pour les modifications), opération réalisée au moyen de l’instruction CREATE TRIGGER :

    
    CREATE TRIGGER CABLE_LIGNE_COHERENCE BEFORE INSERT ON CABLE
    FOR EACH ROW
    BEGIN
        IF 1 < (
                SELECT COUNT(*)
                FROM (SELECT x.LigneId
                      FROM   SUPPORT AS x JOIN LIGNE AS y ON x.LigneId = y.LigneId
                      WHERE  new.SupportDepartId = x.SupportId
                      UNION
                      SELECT x.ligneid
                      FROM   SUPPORT AS x JOIN LIGNE AS y ON x.LigneId = y.LigneId
                      WHERE  new.SupportArriveeId = x.SupportId
                     ) AS t
                )
            THEN
                SET @Err = CONCAT ('CableCode = ', new.CableCode, ' : La ligne du support de départ est différente de celle du support d''arrivée.') ;
                SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @Err ;
        END IF ;
    END
    
    
    Bon d’accord, ça n’est pas intuitif, mais on s’y met assez vite, et surtout ça permet de garantir que les supports de départ et d’arrivée d’un câble appartiennent bien à la même ligne. Si on tente des ajouts délinquants, ils seront rejetés, avec un message d’erreur à la clé.
    Je ne comprends pas vraiment ce trigger que vous avez écrit pour s'assurer que les supports de départ et d’arrivée d’un câble appartiennent bien à la même ligne...


    Cordialement,

    Loic

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [reseaux] Gestion des threads en perl
    Par totox17 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 28/11/2002, 09h40
  2. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44
  3. Réponses: 4
    Dernier message: 04/07/2002, 12h31
  4. c: gestion des exceptions
    Par vince_lille dans le forum C
    Réponses: 7
    Dernier message: 05/06/2002, 14h11

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