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 :

Base de données de contacts


Sujet :

Schéma

  1. #1
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut Base de données de contacts
    Bonjour,

    je suis en train de modéliser une base de données permettant de stocker des coordonnées de personnes, maintenir un fichier Excel est trop laborieux à plusieurs.

    L'objectif est de :
    Stocker des coordonnées de personnes avec :
    - Adresse email
    - Nom et prénom (facultatif), certains mails sont génériques et peuvent être partagés par plusieurs contacts
    - Numéros de téléphone - VARCHAR puisque +[Code pays][Numéro] - peut parois être partagé par plusieurs personnes (service d'une entreprise)
    - Table TYPE_CONTACT : poste occupé en entreprise

    Les lacunes du MCD jusqu'à présent :
    - Manque de numéro de fax
    - Incohérences sur certains 0,N

    Ce que je souhaite aussi implémenter :
    - Historisation des modifications. Qui a effectué des modifications sur les tables ORGANISATION et CONTACT, à quelle heure et pourquoi ? J'avoue ne pas avoir eu le temps de me pencher sur la question. En l'état, c'est un premier jet.

    Vous en pensez quoi ? C'est surtout la structure qui m'intéresse.

    Conventions de nommage (pas totalement respecté dans mon schéma) :
    - T_ : Table
    - T_J : Table de jointure

    Nom : CONTACTS.png
Affichages : 4031
Taille : 34,4 Ko

    EDIT 16/03/2015 :

    Structure correcte ou non ?
    Images attachées Images attachées  
    Exprimer une différence d'opinion vaut mieux que :

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Aizen64 Voir le message
    Structure correcte ou non ?
    Non, vous n'avez pas typé les FAX; Une télécopie est un type de FAX !

    Inspirez vous de ce que j'ai donné ici :
    http://blog.developpez.com/exercices...n_de_personnes
    Vous n'êtes pas obligé d'aller jusqu"au niveau de détail concernant les prénoms.

    Si vous avez en sus besoin des adresses, voici le complément :
    http://blog.developpez.com/exercices..._d_une_adresse

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Exact. Je l'ai ajouté dans la nouvelle version de mon modèle.

    J'ai mis le schéma créé sous MySQL Workbench en pièce jointe.

    En l'état, il y a plusieurs choses qui sont incorrectes dans ma modélisation et je ne serai pas contre un avis pour ne pas me tromper :
    - La table_T_ORGANISATION peut aussi contenir d'autres organisations, association réflexive donc. Comment le tout se traduit par le SGBDR en pratique ?
    - La table T_ADRESSE contient un code postal. Ce qui est potentiellement inexact comme tous les pays n'ont pas de codes postaux.
    - La table T_PAYS .

    D'ailleurs, y a t-il quelques sites avec certaines bases de données génériques ? Par exemple, un pays appartient à une région du monde, pourquoi faire ces choses manuellement ?

    J'insiste parce que la BDD est le coeur de l'appli, une erreur de conception peut se payer cher ensuite, le modèle doit être bon.

    Voilà à quoi ça ressemble :
    Nom : DB.png
Affichages : 4689
Taille : 85,0 Ko
    Exprimer une différence d'opinion vaut mieux que :

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

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

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



    Citation Envoyé par Aizen64 Voir le message
    Le modèle doit être bon.
    Concernant votre diagramme MySQL Workbench il y a à redire, je vous renvoie à l’article que je lui ai consacré.



    Citation Envoyé par Aizen64 Voir le message
    La table_T_ORGANISATION peut aussi contenir d'autres organisations, association réflexive donc.
    Dans ce même article, vous pourrez vous inspirer de la partie consacrée aux nomenclatures et hiérarchies.


    Au sujet du bonhomme NULL

    Considérons votre table T_TELEPHONE :



    Le losange blanc accompagnant l’attribut TEL signifie que cet attribut peut être marqué NULL : c’est à changer. Je recopie ici la figure 3.5 de l’article, où l’on voit les losanges virer au bleu :



    Cette remarque vaut pour tous les losanges blancs de votre diagramme, ils doivent eux aussi virer au bleu.


    Il y a des cardinalités (multiplicités) 1..* à remplacer par des 0..*. Par exemple, il est douteux que pour chaque profession appartenant à la table T_PROFESSION_CONTACT, il y ait impérativement au moins un contact exerçant cette profession.

    Pour obtenir la cardinalité minimum 0, voyez la figure 4.5 de l’article :




    Question : Quelle valeur ajoutée y a-t-il à préfixer le nom des tables par la lettre T ? Une requête doit-elle nécessairement savoir qu’elle manipule une table plutôt qu’une vue ? Quelle part vous perdez en indépendance.


    Il y a d’autres choses à dire, mais je dois m’interrompre. Je reprendrai le fil plus tard.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

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

  5. #5
    Expert é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
    Suite,


    Dans le cadre des représentations graphiques avec MySQL Workbench, il faudrait que vous utilisiez l’icône permettant de mettre en œuvre une relation non identifiante (Non-Identifying Relationship) quand celle-ci s’impose. Ainsi, dans le cas de la table T_CONTACT, vous avez utilisé l’icône servant à mettre en œuvre une relation identifiante (Identifying Relationship) pour mettre en relation la table T_CONTACT avec la table T_ORGANISATION d’une part et avec la table T_PPROFESSION_CONTACT d’autre part. Il s’ensuit que la clé primaire de la table T_CONTACT est le triplet {ID INT, T_ORGANISATION_ID et T_PROFESSION_CONTACT_ID}, ce qui revient à dire qu’un contact peut changer de nom selon les organisations auxquelles il est rattaché et au gré des professions qu’il exerce...

    La table T_J_T_CONTACT_T_CIVILITE hérite triplet {ID INT, T_ORGANISATION_ID et T_PROFESSION_CONTACT_ID}. Les autres tables T_J_T_xxx ont été épargnées, vraisemblablement parce qu’elles ont été modélisées avant la mise en relation de la table T_CONTACT avec les tables T_ORGANISATION et T_PPROFESSION_CONTACT.


    Pour mémoire, du fait du mauvais choix de l’icône en question, dans l’en-tête de la table T_CONTACT, les attributs T_ORGANISATION_ID et T_PROFESSION_CONTACT_ID sont affectés d’une clé rougeâtre au lieu d’un losange de cette couleur : le losange rougeâtre symbolise la participation à une clé étrangère, tandis que la clé ainsi colorée symbolise non seulement la participation à une clé étrangère, mais aussi à la clé primaire de la table. A votre décharge, il faut reconnaître qu’il faut une loupe pour distinguer sur l’icône elle-même les pointillés caractéristiques de la relation non identifiante...




    Divers

    Selon votre diagramme, un même fax peut être partagé par plusieurs contacts, d’accord. Un même téléphone peut être partagé par plusieurs contacts, encore d’accord. Une même adresse de courriel peut être partagée par plusieurs contacts : bizarre. Est-ce bien ce que vous avez voulu modéliser ? De la même façon, un contact peut avoir plus d’un titre de civilité : bizarre autant qu’étrange...

    Qu’est-ce qu’un « alias » d’organisation ? (Et qu’est-ce qu’une organisation ? Le contraire d’une désorganisation ?) Pour le moment, je note qu’une organisation peut avoir plusieurs « alias » et qu’un « alias » peut être utilisé par plusieurs organisations. Il est difficile en l'état de donner un avis.

    Selon votre diagramme, à une même adresse (ligne 1, ligne 2, etc.) on peut trouver plus d’une organisation, soit. Mais une adresse a une ligne 1, et la ligne 1 d’adresse identifie le destinataire. Même chose pour la ligne 2. Qu’en est-il pour vous ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

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

  6. #6
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Merci fsmrel.

    - Champs non null : corrigé.
    - Tables d'association entre T_CONTACT et T_TELEPHONE, T_FAX, j'ai défini les champs comme facultatifs (décoché Mandatory) dans la mesure où un contact n'a pas nécessairement de numéro de téléphone ou fax d'enregistré.

    Pour le reste, j'ai besoin de sommeil dans l'immédiat, ça attendra quelques heures.
    Exprimer une différence d'opinion vaut mieux que :

  7. #7
    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
    D'accord, d'autant plus que la nuit porte conseil !
    (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.

  8. #8
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Alors pour répondre aux questions posées :

    - Alias d’organisation : ex. Médecins sans Frontières : MSF. C'est un exemple parmi d'autres, c'est surtout pour répertorier des diminutifs pour faciliter des recherches.

    - Adresses email qui appartiennent à plusieurs destinataires : dans certains cas, j'ai des adresses email communes génériques. Je n'ai pas vu d'autre façon de modéliser cette problématique mais je suis ouvert à des suggestions.

    - Les 3 lignes d'adresse : avec seulement 2 lignes d'adresse, il existe peut-être une possibilité de manquer de place (encore que) pour noter certaines informations complémentaires. Je suppose que je peux le réduire à 2 champs. J'ai aussi évité de mettre des champs trop précis (ex. Num. voie, voie, complément d'adresse... parce que mon expérience m'a montré que peu de gens respectaient ce modèle dans la pratique.

    Pour les relations non-identifiantes, je n'ai pas bien compris la distinction, un ou deux exemples concrets seraient les bienvenus.

    EDIT :
    J'ai mis à jour mon MCD :
    - Retiré les champs non nuls, une adresse doit au moins contenir une ligne, un code postal et une ville

    - Créé une association réflexive sur la table 'T_ORGANISATION', la nouvelle clé créée a été renommée de 'T_ORGANISATION_ID' à 'ID_ORGANISATION_PARENTE'. D'ailleurs, ce champ doit autoriser les valeurs nulles dans le cas où une organisation n'aurait pas de 'petits' donc mon screenshot est certainement faux. Screenshot (le principe d'Adam/Eve décrit ici ne s'applique pas puisque j'aurai déjà toutes les informations dans la base de données
    Nom : Association reflexive.PNG
Affichages : 2232
Taille : 45,2 Ko

    - Changé les relations en non identifiantes entre 'T_CONTACT' et 'T_PROFESSION_CONTACT' / 'T_ORGANISATION'

    Voilà ce que donne la nouvelle version :
    Nom : Db - v2.png
Affichages : 2540
Taille : 83,2 Ko
    Exprimer une différence d'opinion vaut mieux que :

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



    Citation Envoyé par Aizen64 Voir le message
    J'ai mis à jour mon MCD :
    - Retiré les champs non nuls
    Hum... Il reste des colonnes pouvant être marquées NULL.

    Table CONTACT : colonnes NOM, PRENOM, NOTE.
    Table ORGANISATION : colonnes DESCRIPTION et SITE_WEB.
    Table ADRESSE : colonne LIGNE2
    Table PAYS : à part l’identifiant...

    Pour la colonne SITE_WEB, si vous souhaitez vous placer au niveau sémantique, pour signifier qu’une organisation n’a pas forcément de site web, vous pouvez définir une table ad-hoc :



    Sinon, vous pouvez vous contenter de ne pas chahuter votre diagramme actuel, mais en faisant quand même virer au bleu le losange (désespérément blanc) qui accompagne le nom de la colonne SITE_WEB de la table ORGANISATION.

    Remarques :

    — MCD signifie Modèle Conceptuel des Données, mais un diagramme MySQL Workbench n’et pas un MCD (dans un MCD, le concept de clé étrangère n’existe pas, ce sont les associations 1,x qui seront la source des clés étrangères pour les modèles logiques des données, façon MySQL Workbench).

    — Le terme « champ » ne vaut que pour les enregistrements des fichiers et des bases de données prérelationnelles (systèmes IMS/DB, IDMS, etc.) Avec SQL, on parle de colonnes, même chose avec MySQL Workbench ,bien que pour ma part, dans ce dernier cas il m’arrive de parler d’attributs. En évitant de parler de champs, vous ferez plaisir à CinePhil qui a un avis tranché sur ce point... ^^



    Citation Envoyé par Aizen64 Voir le message
    Alias d’organisation : ex. Médecins sans Frontières : MSF. C'est un exemple parmi d'autres, c'est surtout pour répertorier des diminutifs pour faciliter des recherches.
    Je comprends mieux ce que vous entendez par « organisation ». Cela dit, si l’on en croit votre diagramme, une organisation peut avoir plusieurs alias, est-ce bien ce qui se passe dans la réalité ?



    Citation Envoyé par Aizen64 Voir le message
    Adresses email qui appartiennent à plusieurs destinataires : dans certains cas, j'ai des adresses email communes génériques. Je n'ai pas vu d'autre façon de modéliser cette problématique mais je suis ouvert à des suggestions.
    Comment déterminez-vous la partie spécifique d’une telle adresse ?



    Citation Envoyé par Aizen64 Voir le message
    Les 3 lignes d'adresse : avec seulement 2 lignes d'adresse, il existe peut-être une possibilité de manquer de place (encore que) pour noter certaines informations complémentaires. Je suppose que je peux le réduire à 2 champs. J'ai aussi évité de mettre des champs trop précis (ex. Num. voie, voie, complément d'adresse... parce que mon expérience m'a montré que peu de gens respectaient ce modèle dans la pratique.
    Va pour deux lignes d’adresse. A moins de travailler pour le Trésor public et autres « organismes » du même tonneau, il est un fait que modéliser réglementairement des informations comme la voie et le numéro dans la voie n’apporte guère. Ainsi, quand Stéphane Mallarmé écrivait à un ami, il remplaçait les 4 lignes d’adresse par un quatrain, ce qui gênait nullement le facteur, lequel déposait le courrier dans la bonne boîte à lettres (heureuse époque...)





    Je repose quand même ma question : quelles colonnes de quelle tables sont utilisées pour le destinataire ? (lignes 1 et 2 réglementaires...)


    Relations (associations) identifiantes

    La relation identifiante permet de modéliser les propriétés multivaluées d’une entité-type. Supposons que l’on ait à modéliser les éditions successives d’un livre : celui-ci à un titre, un auteur (ou plusieurs, mais pour simplifier, on va en rester à un), un éditeur (Addison-Wesley est devenue Pearson Addison-Wesley, mais bon, j’ai la nostalgique de cette maison...) Chaque édition a un numéro (1re édition, 2e édition, ...), une année de parution, un ISBN, une préface, des chapitres, etc.

    OUVRAGE  OuvrageId    Auteur        Titre                                        Langue    Editeur
                   123    C. J. Date    An Introduction to Database Systems          anglais   Addison-Wesley 
                   456    E. F. Codd    The Relational Model for Database Systems    anglais   Addison-Wesley
                  6789    M. Diviné     Parlez-vous Merise ?                         français  Eyrolles
    
    
    EDITION  OuvrageId  EditionId  AnneeParution  ISBN        Preface     
                   123          1  1975           0201144522  Computers have already had a considerable impact...
                   123          2  1977           0201144565  Many changes have occurred in the field of database development...
                   123          3  1981           0201144395  The field of database technology continues to evolve...
                   ...
                   123          8  2004           0321189566  This book is a comprehensive introduction...
                   456          1  1990           0201141922  Today, if you have a well-designed database management system, you have the keys to the kingdom... 
                  6789          1  1989           2212041071  Il manquait dans la littérature consacrée à Merise... 
    La clé primaire de la table OUVRAGE est le singleton {OuvrageId} et celle de la table EDITION est la paire {OuvrageId, EditionId}. La relation entre ces deux tables, c’est à la vie à la mort : si on supprime un ouvrage, les éditions sont elles aussi supprimées, de facto. Au niveau conceptuel, on dit que l’entité-type EDITION est une entité-type faible (weak entity-type). Dans un diagramme de classes (UML), on dit encore qu’il y a une relation de composition entre les classes OUVRAGE et EDITION. De même, si on supprime une commande, ses lignes disparaissent (la suppression d’une commande peut être refusée, mais en tout cas ce ne sont pas ses lignes qui peuvent s’opposer, puisqu’une ligne de commande n’est qu’une propriété d’une commande).

    Avec MySQL Workbench, une association représentée par des traits pleins correspond à une relation entre une entité-type faible (EDITION) et une entité-type plus forte (OUVRAGE). Les autres associations sont représentées par des traits en pointillés. Si par exemple un ouvrage rentre dans une certaine catégorie (informatique, littérature, science fiction, etc.), il est évident que la suppression d’une catégorie ne peut pas entraîner celle des ouvrages qui en font partie : une catégorie ne peut être supprimée que si aucun ouvrage n’y fait référence.




    Comme je l’ai déjà signalé, Je note qu’il y a des clés rouges (attributs participant à la fois à une clé primaire et à une clé étrangère) qui doivent devenir des losanges rouges (attributs seulement clés étrangères).


    Je reviendrai sur la réflexive un peu plus tard.

    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.

  10. #10
    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,


    A propos de la réflexive.

    Selon votre représentation, et malgré les apparences, on est en fait en présence d’un cycle de plusieurs à plusieurs (je n’ai pas fait figurer les colonnes de la table qui n’apportent rien pour le sujet traité) :




    En effet, dans le diagramme, l’association réflexive est représentée par un trait continu, ce qui fait que l’attribut ID_ORGANISATION_PARENTE entre dans la composition de la clé primaire de la table, d’où le code SQL suivant produit par MySQL Workbench (lequel laisse passer l’incohérence patente) :

     
    -- -----------------------------------------------------
    -- Table ORGANISATION
    -- -----------------------------------------------------
    CREATE TABLE ORGANISATION
    (
            ID                         INT              NOT NULL,
            ID_ORGANISATION_PARENTE    INT              NOT NULL,
            DESCRIPTION                VARCHAR(64)      NOT NULL,
        CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID, ID_ORGANISATION_PARENTE),
        CONSTRAINT ORGANISATION_ORGANISATION_FK FOREIGN KEY (ID_ORGANISATION_PARENTE)
            REFERENCES ORGANISATION (ID)
    ) ; 
    Autrement dit, au lieu d’une hiérarchie (un à plusieurs), vous avez produit une nomenclature (plusieurs à plusieurs).

    Pour vous limiter à une hiérarchie, le trait plein doit être remplacé par un trait en pointillés (la clé rougeâtre se transforme alors en losange de la même couleur) :




    Cette fois-ci, l’attribut ID_ORGANISATION_PARENTE n’entre pas dans la composition de la clé primaire de la table, d’où le code SQL suivant produit par MySQL Workbench et correspondant bien à une hiérarchie :


     
    -- -----------------------------------------------------
    -- Table ORGANISATION
    -- -----------------------------------------------------
    CREATE TABLE ORGANISATION
    (
            ID                         INT              NOT NULL,
            ID_ORGANISATION_PARENTE    INT              NOT NULL,
            DESCRIPTION                VARCHAR(64)      NOT NULL,
        CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID),
        CONSTRAINT ORGANISATION_ORGANISATION_FK FOREIGN KEY (ID_ORGANISATION_PARENTE)
            REFERENCES ORGANISATION (ID)
    ) ; 

    Selon cette structure, chaque organisation est rattachée à (au moins et au plus) une organisation. Pour éviter de déclencher des boucles infinies lors de l’exécution des requêtes, si l’organisation o01 est réalité au sommet d’une hiérarchie, le moins pire est de la rattacher à elle-même (auto-référence), au même titre que les organisations o03 et o04, lesquelles sont des « enfants légitimes » de o01 :

     
        ID    ID_ORGANISATION_PARENTE    DESCRITION
         1                          1    organisation o01
         2                          2    organisation o02
         3                          1    organisation o03
         4                          1    organisation o04
         5                          3    organisation o05
         6                          5    organisation o06
         7                          5    organisation o07
    
    
    Évidemment, lorsque vous rechercherez les enfants de o01, il faudra coder les requêtes en veillant à ce que o01 soit exclue des résultats (c’est de la bidouille, mais bon...) même vigilance si vous recherchez la maman de o01, puisqu’en réalité elle n’en a pas.


    Maintenant, vous pouvez opter pour cette structure :



    D’où le code SQL :

     
    -- -----------------------------------------------------
    -- Table ORGANISATION
    -- -----------------------------------------------------
    CREATE TABLE ORGANISATION
    (
            ID                      INT                 NOT NULL,
            DESCRIPTION             VARCHAR(64)         NOT NULL,
        CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID)
    ) ;
    
    -- -----------------------------------------------------
    -- Table HIERARCHIE
    -- -----------------------------------------------------
    CREATE TABLE HIERARCHIE
    (
            ID_ORGANISATION           INT                NOT NULL,
            ID_ORGANISATION_PARENTE   INT                NOT NULL,
        CONSTRAINT HIERARCHIE_PK PRIMARY KEY (ID_ORGANISATION),
        CONSTRAINT HIERARCHIE_ORGANISATION_FK FOREIGN KEY (ID_ORGANISATION) 
            REFERENCES ORGANISATION (ID)
            ON DELETE CASCADE,
        CONSTRAINT HIERARCHIE_ORGANISATION_PARENTE_FK FOREIGN KEY (ID_ORGANISATION_PARENTE)
            REFERENCES ORGANISATION (ID)
    ) ;
    
    Exemple. L’auto-référence a été évacuée (au moins pour les organisations o01 et o02, mais rien n'empêche de rattacher o03 à elle-même, sauf à mettre en oeuvre un trigger empêchant la chose, mais des boucles sont encore évidemment possibles) :

     
    
        ID    DESCRITION
         1    organisation o01
         2    organisation o02
         3    organisation o03
         4    organisation o04
         5    organisation o05
         6    organisation o06
         7    organisation o07
    
        ID    ID_ORGANISATION_PARENTE 
         3                          1 
         4                          1 
         5                          3 
         6                          5 
         7                          5 
    
    Pour ma part, il s’agit là de la structure que j’utilise pour les hiérarchies.
    (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.

  11. #11
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Pour les colonnes nulles, je règlerai le problème, le vocabulaire... le problème vient du fait de ne pas avoir pratiqué pendant trop longtemps. Et en effet, le schéma de MySQL Workbench est un MLD comme il a des clés étrangères.

    Les alias ont pour objectif de faciliter des recherches, un peu comme un système de tag, s'il existe une autre méthode je suis prêt à la prendre. En avoir plusieurs est une façon de prendre en compte le changement de nom et donc un autre diminutif.

    Je n'ai pas bien compris la question sur la partie spécifique de l'adresse email.

    Je devrai aussi revenir sur la partie entité faible et donc revenir sur ce que j'avais appris à l'école mais pas maintenant. Écrire avec 2 doigts non opérationnels à une main est fastidieux, continuer à coder l'est tout autant.
    Exprimer une différence d'opinion vaut mieux que :

  12. #12
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Je reviens sur la réflexive, le fait est que j'ai du mal à poser des mots sur la problématique ce qui me pose des soucis de compréhension.

    Ce que je comprends :
    - Si une organisation est parente, ses enfants doivent être supprimés lors de sa suppression ce qui explique le ON DELETE CASCADE.

    Le contraire n'est pas valable, forcément. Une organisation fille supprimée n'a aucune incidence sur la parente.

    Ce que donne mon schéma maintenant :
    Nom : Contraintes.png
Affichages : 3362
Taille : 66,3 Ko

    Quelque peu sceptique sur le SQL généré et mon modèle mis en pièce jointe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    CREATE TABLE `T_HIERACHIE` 
    (
      `ORGANISATION_ID` INT NOT NULL,
      `TYPE_ORGANISATION_ID` INT NOT NULL,
      `ORGANISATION_PARENTE_ID` INT NOT NULL,
      `TYPE_ORGANISATION_ID` INT NOT NULL,
      PRIMARY KEY (`ORGANISATION_ID`, `TYPE_ORGANISATION_ID`),
      CONSTRAINT `fk_T_HIERACHIE_T_ORGANISATION1`
        FOREIGN KEY (`ORGANISATION_ID` , `TYPE_ORGANISATION_ID`)
        REFERENCES `T_ORGANISATION` (`ID` , `T_TYPE_ORGANISATION_ID`)
        ON DELETE CASCADE
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_T_HIERACHIE_T_ORGANISATION2`
        FOREIGN KEY (`ORGANISATION_PARENTE_ID` , `TYPE_ORGANISATION_ID`)
        REFERENCES `T_ORGANISATION` (`ID` , `T_TYPE_ORGANISATION_ID`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
    )
    Je m'embrouille avec les clés étrangères.
    Exprimer une différence d'opinion vaut mieux que :

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


    J’ai été bien occupé avec vos camarades supras31 et Antonitzer, mais maintenant je vais regarder vos problèmes avant de revenir aux leurs

    Une question : quel est votre SGBD ?

    A bientôt, donc
    (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
    Membre confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Bonjour Fsmrel,

    MySQL 5.6.17.
    Exprimer une différence d'opinion vaut mieux que :

  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 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 De l'auto-référence
    Bonsoir Aizen,



    Comme vous utilisez MySQL et parce que vous voulez que la suppression d’une organisation entraîne celle de sa descendance, vous avez en fait intérêt à utiliser une auto-référence, avec CASCADE :




     
    CREATE TABLE ORGANISATION 
    (
      ID                                INT               NOT NULL,
      NOM                               VARCHAR(64)       NOT NULL,
      ID_ORGANISATION_PARENTE           INT               NOT NULL,
      CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID),
      CONSTRAINT ORGANISATION_ORGANISATION_FK FOREIGN KEY (ID_ORGANISATION_PARENTE)
        REFERENCES ORGANISATION (ID) ON DELETE CASCADE  
    ) ;
    

    Un jeu d’essai pour vérifier :

     
    INSERT INTO ORGANISATION VALUES (1, 'org 1', 1) ;
    INSERT INTO ORGANISATION VALUES (11, 'org 11', 1) ;
    INSERT INTO ORGANISATION VALUES (111, 'org 111', 11) ;
    INSERT INTO ORGANISATION VALUES (112, 'org 112', 11) ;
    INSERT INTO ORGANISATION VALUES (113, 'org 113', 11) ;
    INSERT INTO ORGANISATION VALUES (12, 'org 11', 1) ;
    INSERT INTO ORGANISATION VALUES (121, 'org 111', 12) ;
    INSERT INTO ORGANISATION VALUES (122, 'org 112', 12) ;
    INSERT INTO ORGANISATION VALUES (123, 'org 113', 12) ;
      
    INSERT INTO ORGANISATION VALUES (2, 'org 2', 2) ;
    INSERT INTO ORGANISATION VALUES (21, 'org 21', 2) ;
    INSERT INTO ORGANISATION VALUES (211, 'org 211', 21) ;
    INSERT INTO ORGANISATION VALUES (212, 'org 212', 21) ;
    INSERT INTO ORGANISATION VALUES (213, 'org 213', 21) ;
    INSERT INTO ORGANISATION VALUES (22, 'org 22', 2) ;
    INSERT INTO ORGANISATION VALUES (221, 'org 221', 22) ;
    INSERT INTO ORGANISATION VALUES (222, 'org 222', 22) ;
    INSERT INTO ORGANISATION VALUES (223, 'org 223', 22) ;
    
    

    Visualisation du contenu de la table :

     
     ID    NOM            ID_ORGANISATION_PARENTE
     --    ----------     -----------------------
      1    org 1                                1
     11    org 11                               1
    111    org 111                             11
    112    org 112                             11
    113    org 113                             11
     12    org 12                               1
    121    org 121                             12
    122    org 122                             12
    123    org 123                             12
      2    org 2                                2
     21    org 21                               2
    211    org 211                             21
    212    org 212                             21
    213    org 213                             21
     22    org 22                               2
    221    org 221                             22
    222    org 222                             22
    223    org 223                             22
    
    

    En passant, attention aux effets secondaires de l’auto-référence. Par exemple, si l’utilisateur veut savoir quelles sont les organisations qui dépendent de 'org 1', la requête suivante :

     
    SELECT y.*
    FROM   ORGANISATION as x JOIN ORGANISATION as y on x.ID = y.ID_ORGANISATION_PARENTE
    WHERE  x.NOM = 'org 1' ;  
    
    
    Donnera le résultat suivant, comme quoi l’organisation 'org 1 est mère et fille de l’organisation 'org 1' ! (donc sœur de 'org 11' et 'org 12'...) :

     
    ID     NOM            ID_ORGANISATION_PARENTE
     --    -----------    -----------------------
      1    org 1                                1
     11    org 11                               1
     12    org 12                               1
    
    

    De même, si l’on compte le nombre d’enfants de 'org 1' :

     
    SELECT COUNT(*) FROM ORGANISATION WHERE ID_ORGANISATION_PARENTE = 1 ; 
    
    
    La requête ci-dessus donnera 3 comme résultat au lieu de 2...

    Autrement dit, à chaque fois il faut veiller à la pertinence des résultats. Ainsi, la requête précédente est à enrichir :

     
    SELECT COUNT(*) FROM ORGANISATION WHERE ID_ORGANISATION_PARENTE = 1 AND ID_ORGANISATION_PARENTE  <> ID ; 
    
    

    On peut aussi choisir de dériver de Charybde vers Scylla, c'est-à-dire ouvrir la porte au redoutable petit bonhomme Null...

     
    CREATE TABLE ORGANISATION 
    (
      ID                                INT               NOT NULL,
      NOM                               VARCHAR(64)       NOT NULL,
      ID_ORGANISATION_PARENTE           INT                       ,
      CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID),
      CONSTRAINT ORGANISATION_ORGANISATION_FK FOREIGN KEY (ID_ORGANISATION_PARENTE)
        REFERENCES ORGANISATION (ID) ON DELETE CASCADE
    ) ;
    
    INSERT INTO ORGANISATION VALUES (1, 'org 1', NULL) ;
    INSERT INTO ORGANISATION VALUES (11, 'org 11', 1) ;
    INSERT INTO ORGANISATION VALUES (111, 'org 111', 11) ;
    INSERT INTO ORGANISATION VALUES (112, 'org 112', 11) ;
    INSERT INTO ORGANISATION VALUES (113, 'org 113', 11) ;
    INSERT INTO ORGANISATION VALUES (12, 'org 12', 1) ;
    INSERT INTO ORGANISATION VALUES (121, 'org 121', 12) ;
    INSERT INTO ORGANISATION VALUES (122, 'org 122', 12) ;
    INSERT INTO ORGANISATION VALUES (123, 'org 123', 12) ;
      
    INSERT INTO ORGANISATION VALUES (2, 'org 2', NULL) ;
    INSERT INTO ORGANISATION VALUES (21, 'org 21', 2) ;
    INSERT INTO ORGANISATION VALUES (211, 'org 211', 21) ;
    INSERT INTO ORGANISATION VALUES (212, 'org 212', 21) ;
    INSERT INTO ORGANISATION VALUES (213, 'org 213', 21) ;
    INSERT INTO ORGANISATION VALUES (22, 'org 22', 2) ;
    INSERT INTO ORGANISATION VALUES (221, 'org 221', 22) ;
    INSERT INTO ORGANISATION VALUES (222, 'org 222', 22) ;
    INSERT INTO ORGANISATION VALUES (223, 'org 223', 22) ;
    
    

    Quels que soient nos choix, tentons maintenant de supprimer l’organisation 'org 1' :

    DELETE FROM ORGANISATION WHERE ID = 1 ;

    Au résultat, on constate que 'org 1' et sa descendance ont disparu de la table, on ne trouve plus que les lignes suivantes :

     
     ID    NOM            ID_ORGANISATION_PARENTE
     --    -----------    -----------------------
      2    org 2                                2
     21    org 21                               2
    211    org 211                             21
    212    org 212                             21
    213    org 213                             21
     22    org 22                               2
    221    org 221                             22
    222    org 222                             22
    223    org 223                             22
    
    
    Ce résultat est conforme à votre attente.


    Notez à toutes fins utiles que si vous voulez connaître la descendance complète d’une organisation, vous n’échapperez pas à la mise en œuvre d’une procédure récursive, voyez par exemple le comptage des rivets par aile d’avion...



    Passons au problème que vous posent les clés étrangères :

    Citation Envoyé par Aizen64 Voir le message
    Je reviens sur la réflexive, le fait est que j'ai du mal à poser des mots sur la problématique ce qui me pose des soucis de compréhension.

    Ce que je comprends :
    - Si une organisation est parente, ses enfants doivent être supprimés lors de sa suppression ce qui explique le ON DELETE CASCADE.
    Le contraire n'est pas valable, forcément. Une organisation fille supprimée n'a aucune incidence sur la parente.
    [...] Je m'embrouille avec les clés étrangères.

    On est d’accord. Mais les SGBD ne nous facilitent pas la tâche, parce qu’ils n’ont pas tous le même comportement..

    Revenons sur l’organisation des structures hiérarchiques, et supposons qu’on modélise une hiérarchie de la façon suivante, comme on vient de le faire ci-dessus :




    Je me souviens des années quatre-vingt-dix, quand je « bouffais » du DB2 à longueur de temps : lorsque, comme ci-dessus, une table s’auto-référençait, il y avait un diktat (contestable, plus ou moins justifié), CASCADE était obligatoire, ce qui était fort gênant quand justement on ne voulait pas que la suppression d’une organisation entraînât celle de sa descendance ! Et puis DB2 (à partir de sa version 5) s’est conformé à la norme SQL, c'est-à-dire que la règle a été adoucie, on a pu aussi coder NO ACTION en plus de CASCADE.

    Mais, vérité en deçà du territoire d’un SGBD, erreur au-delà... Si l’on passe à SQL Server, on se fait jeter si on code CASCADE dans le cas de l’auto-référence ! Encore un diktat, aussi contestable, et aussi peu justifié que dans le cas de DB2 !

    Pour en revenir à DB2, avant la V5, si l’on ne voulait pas de la suppression en cascade d’une hiérarchie ou d’une nomenclature, la structure suivante s’imposait donc :




    Mais, pour les contraintes correspondant respectivement aux rôles « organisation parente » et « organisation fille », si l’on codait CASCADE d’un côté, on devait aussi coder CASCADE de l’autre, et si l’on codait NO ACTION d’un côté, on devait aussi coder NO ACTION de l’autre. Et bien entendu, pour confirmer le dicton « vérité en deçà du territoire d’un SGBD, erreur au-delà » : en passant à SQL Server, à nouveau une surprise, interdiction de coder CASCADE des deux côtés à la fois ! (Ce qui ne ferait pas votre affaire... )


    Mais puisque vous utilisez MySQL, voyons voir ce qui se passe avec ce SGBD et laissons des deux autres se contredire mutuellement, à coups d'arguments spécieux...

    Partons du script SQL suivant (analogue au vôtre quant au choix des clauses CASCADE et NO ACTION) :

     
    CREATE TABLE ORGANISATION 
    (
      ID                         INT            NOT NULL,
      NOM                        VARCHAR(64)    NOT NULL,
      CONSTRAINT ORGANISATION_PK PRIMARY KEY (ID)
    ) ;
    
    CREATE TABLE HIERARCHIE 
    (
      ID_ORGANISATION            INT            NOT NULL,
      ID_ORGANISATION_PARENTE    INT            NOT NULL,
      CONSTRAINT HIERARCHIE_PK PRIMARY KEY (ID_ORGANISATION),
      CONSTRAINT HIERARCHIE_ORGANISATION_FK
        FOREIGN KEY (ID_ORGANISATION) REFERENCES ORGANISATION (ID)
        ON DELETE CASCADE,
      CONSTRAINT HIERARCHIE_ORGANISATION_PARENTE_FK
        FOREIGN KEY (ID_ORGANISATION_PARENTE) REFERENCES ORGANISATION (ID)
         ON DELETE NO ACTION
    ) ; 
    
    

    Analysons les effets de la clause CASCADE.

    (1) En ce qui concerne a contrainte HIERARCHIE_ORGANISATION_FK, on code « ON DELETE CASCADE », ce qui est logique, puisque si l’on veut supprimer l’organisation 'org 1', elle ne peut pas s’opposer par elle-même à sa destruction.

    (2) A supposer qu’on ait voulu empêcher la suppression d’une organisation parce que d’autres organisations en dépendent, pour la contrainte HIERARCHIE_ORGANISATION_PARENTE_FK, on aurait dû alors coder « ON DELETE NO ACTION » (ce qui est du reste la clause par défaut).

    (3) En fait, comme vous voulez que la suppression d’une organisation entraîne celle de sa descendance, alors pour la contrainte HIERARCHIE_ORGANISATION_PARENTE_FK, en toute logique « ON DELETE CASCADE » s’impose, 'org 11', 'org 12' ne peuvent pas s’opposer à leur propre suppression quand leur mère 'org 1' doit être supprimée.

    Rien de tel qu’un bon coup d’œil plutôt qu’une mauvaise impasse, voyons voir ce qui se passe réellement avec « ON DELETE CASCADE »...

    Créons un certain nombre d’organisations :

    INSERT INTO ORGANISATION VALUES (1, 'org 1') ;
    INSERT INTO ORGANISATION VALUES (11, 'org 11') ;
    INSERT INTO ORGANISATION VALUES (111, 'org 111') ;
    INSERT INTO ORGANISATION VALUES (112, 'org 112') ;
    INSERT INTO ORGANISATION VALUES (113, 'org 113') ;
    INSERT INTO ORGANISATION VALUES (12, 'org 12') ;
    INSERT INTO ORGANISATION VALUES (121, 'org 121') ;
    INSERT INTO ORGANISATION VALUES (122, 'org 122') ;
    INSERT INTO ORGANISATION VALUES (123, 'org 123') ;
      
    INSERT INTO ORGANISATION VALUES (2, 'org 2') ;
    INSERT INTO ORGANISATION VALUES (21, 'org 21') ;
    INSERT INTO ORGANISATION VALUES (211, 'org 211') ;
    INSERT INTO ORGANISATION VALUES (212, 'org 212') ;
    INSERT INTO ORGANISATION VALUES (213, 'org 213') ;
    INSERT INTO ORGANISATION VALUES (22, 'org 22') ;
    INSERT INTO ORGANISATION VALUES (221, 'org 221') ;
    INSERT INTO ORGANISATION VALUES (222, 'org 222') ;
    INSERT INTO ORGANISATION VALUES (223, 'org 223') ;
        
    SELECT * FROM  ORGANISATION ;
    
    

    Et créons les liens pour constituer une hiérarchie de ces organisations :

    INSERT INTO HIERARCHIE VALUES (11, 1) ;
    INSERT INTO HIERARCHIE VALUES (111, 11) ;
    INSERT INTO HIERARCHIE VALUES (112, 11) ;
    INSERT INTO HIERARCHIE VALUES (113, 11) ;
    INSERT INTO HIERARCHIE VALUES (12, 1) ;
    INSERT INTO HIERARCHIE VALUES (121, 12) ;
    INSERT INTO HIERARCHIE VALUES (122, 12) ;
    INSERT INTO HIERARCHIE VALUES (123, 12) ;
    
    INSERT INTO HIERARCHIE VALUES (21, 2) ;
    INSERT INTO HIERARCHIE VALUES (211, 21) ;
    INSERT INTO HIERARCHIE VALUES (212, 21) ;
    INSERT INTO HIERARCHIE VALUES (213, 21) ;
    INSERT INTO HIERARCHIE VALUES (22, 2) ;
    INSERT INTO HIERARCHIE VALUES (221, 22) ;
    INSERT INTO HIERARCHIE VALUES (222, 22) ;
    INSERT INTO HIERARCHIE VALUES (223, 22) ;
    
    

    Visualisons le contenu de la table HIERARCHIE :

     
    ID_ORGANISATION    ID_ORGANISATION_PARENTE
    ---------------    -----------------------
                 11                          1    
                111                         11    
                112                         11    
                113                         11    
                 12                          1    
                121                         12    
                122                         12    
                123                         12    
                 21                          2    
                211                         21    
                212                         21    
                213                         21    
                 22                          2    
                221                         22    
                222                         22    
                223                         22    
    

    Supprimons maintenant l’organisation 'org 1' :

    DELETE FROM ORGANISATION WHERE ID = 1 ;


    Au résultat :

     
    ID_ORGANISATION    ID_ORGANISATION_PARENTE
    ---------------    -----------------------
                111                         11    
                112                         11    
                113                         11    
                121                         12    
                122                         12    
                123                         12    
                 21                          2    
                211                         21    
                212                         21    
                213                         21    
                 22                          2    
                221                         22    
                222                         22    
                223                         22
        
    
    Aïe! Seules les lignes correspondant aux filles 'org 11' et 'org 12' de 'org 1' ont été supprimées de la hiérarchie (à savoir les couples <11, 1> et <12, 1>). Qui plus est, 'org 11' et 'org 12' sont bien évidemment toujours présentes dans la table ORGANISATION : si les stimuli émis par 'org 1' à l’occasion de sa suppression sont bien parvenus à destination de la table HIERARCHIE, cette table n’étant référencée par aucune autre, la suppression des couples <11, 1> et <12, 1> ne déclenche aucun stimulus particulier...


    Avec cette structure, dans le cas de DB2 et SQL Server, on s’en sort sans problème avec une jointure récursive. MySQL n’offrant pas cette possibilité, vouloir supprimer la descendance de 'org 1', nécessite que l’on sorte l’artillerie lourde, à savoir une procédure stockée récursive...


    En ce qui vous concerne, l’auto-référence s’impose donc, avec, comme on l’a vu, toutes les précautions à prendre pour qu’une organisation ne soit pas considérée comme étant sa propre fille...

    En passant, expulsez l’attribut TYPE_ORGANISATION_ID de la clé primaire de votre table ORGANISATION, sinon cela veut dire, très formellement, qu’une organisation peut avoir plus d’un type...

    Je vais essayer de regarder vos autres problèmes.


    N.B. Si d’aventure telle ou telle réponse a pu vous aider, n’hésitez pas à voter...
    (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 confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    En passant, expulsez l’attribut TYPE_ORGANISATION_ID de la clé primaire de votre table ORGANISATION, sinon cela veut dire, très formellement, qu’une organisation peut avoir plus d’un type...
    Donc que la relation entre la table ORGANISATION et TYPE_ORGANISATION soit non identifiante ?

    C'est fait pour la reflexive sur la table ORGANISATION.
    Exprimer une différence d'opinion vaut mieux que :

  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 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 Identification relative
    Bonsoir Aizen,


    Je suis désolé de ce retard, je vous avais perdu de vue...

    Pour répondre à votre question, une relation identifiante traduit le plus souvent la dépendance d’une entité-type « faible » relativement à une entité-type plus forte. Une entité-type faible n’a pas d’autonomie, elle n’a d’existence que par son attachement à une entité-type plus forte. Pour sa part, une organisation est une entité forte, qui se contente de faire référence à un type d’organisation et je ne vois pas de motif valable pour identifier l’entité-type ORGANISATION relativement à l’entité-type TYPE_ORGANISATION.


    A l’opposé, pour prendre l’exemple des commandes, l’existence d’une ligne de commande dépend de celle de la commande qui la porte : si on supprime une commande, les lignes dont celle-ci est porteuse disparaissent avec elle.

    Par contre, une commande est une entité-type forte : si on cherche à supprimer un type de commande, les commandes faisant référence à ce type refuseront de disparaître.

    Il n’est pas interdit qu’une entité-type forte dépende d’une autre entité-type forte : ainsi une commande est rattachée à un client, mais elle refusera de disparaître si on tente de supprimer ce client, lequel sera contraint à survivre tant que des commandes lui seront rattachées. Maintenant, rien n’empêche qu’une commande soit identifiée relativement à un client, mais c’est en général pour résoudre une contrainte de chemin, pour améliorer la performance des traitements, que sais-je, et il m’arrive le plus souvent d’identifier effectivement les commandes relativement aux clients. Par contre, je ne vois aucun motif pour identifier une organisation relativement à un type d’organisation.

    Ai-je répondu à votre interrogation ?
    (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 confirmé Avatar de Aizen64
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 561
    Points : 462
    Points
    462
    Par défaut
    Partiellement.

    J'essaie de comprendre comment le SGBDR gère en interne les relations identifiantes/non-identifiantes. Est ce que c'est lié à ON DELETE CASCADE si la relation est identifiante et ON DELETE NO ACTION si la relation est non-identifiante ?
    Exprimer une différence d'opinion vaut mieux que :

  19. #19
    Membre expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2013
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 563
    Points : 3 404
    Points
    3 404
    Par défaut
    Citation Envoyé par Aizen64 Voir le message
    Partiellement.

    J'essaie de comprendre comment le SGBDR gère en interne les relations identifiantes/non-identifiantes. Est ce que c'est lié à ON DELETE CASCADE si la relation est identifiante et ON DELETE NO ACTION si la relation est non-identifiante ?
    Si je ne me trompe pas, une relation identifiante veut dire que la clef primaire d'une entité sera intégré dans une autre entité en tant que clef primaire/clef étrangère. Une relation non identifiante inclue la clef primaire d'une entité en tant que simple clef étrangère de l'autre entité.

    L'histoire des CASCADE est, me semble-t-il, une règle de gestion proposée par le SGBD et ne dépend donc pas du modèle.

  20. #20
    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 Aizen,



    Le concept de relation identifiante nous vient indirectement des modèles de niveau sémantique, calés (pour faire court) sur l’approche entité/relation définie par Peter Chen en 1976 (voir son article The Entity-Relationship Model - Toward a Unified View of Data. Avant Chen, d’autres auteurs, tels que Schmid & Swenson (On the Semantics of the Relational Data Model ), ou Abrial (Data Semantics) ont planché sur la modélisation sémantique, ce fut aussi, bien entendu, le cas de l’équipe du CETE d'Aix en Provence (cf. la FAQ Merise), mais il est de tradition d’attribuer la paternité de la modélisation sémantique à Chen.

    Chez Chen, on fait le distinguo entre l’entité forte (regular entity) et l’entité faible (weak entity). Pour reprendre l’exemple des commandes, une ligne de commande (si tant est qu’on puisse en faire une entité) est une entité faible, dont la vie dépend viscéralement de celle de l’entité plus forte qu’est la commande qui la porte.

    Pour en revenir à Merise, dans le document résumant les travaux des merisiens (Afcet – Le formalisme de données Merise - Extensions du pouvoir d’expression - Journée d’étude organisée par le Groupe de Travail 135 « Conception des systèmes d’information » (Collège AFCET-GID) - Jeudi 15 novembre 1990, Paris.), l’identifiant relatif est officiellement caractérisé cette fois-ci par le fait qu’il « comprend » au moins une relation (association) :




    Il est évident que si on démolit un hôtel, il ne reste plus rien de ses chambres...

    Quant à tenter de supprimer un type d’organisation, il est hors de question que cela soit possible tant que des organisations y font référence...

    Maintenant, vous écrivez :

    Citation Envoyé par Aizen64 Voir le message
    J'essaie de comprendre comment le SGBDR gère en interne les relations identifiantes/non-identifiantes.
    Un SGBD n’a pas de connaissance formelle de ce qu’est une relation identifiante au sens où on l'entend au niveau E/R, pas plus de ce qu’est une entité-type forte ou faible.

    C’est à vous (manuellement, ou au moyen d’un AGL comme DB-MAIN, WinDesign, PowerAMC, voire MySQL Workbench et autres) de traduire l’identification relative en quelque chose qui réponde au besoin, disons à l’occasion d’un CREATE TABLE (SQL).

    Exemple des commandes des clients :

     
    
    CREATE TABLE PRODUIT
    (
            ProduitId           INT            NOT NULL 
          , ProduitCode         CHAR(12)       NOT NULL
          , ProduitNom          VARCHAR(64)    NOT NULL
          , ...                 ...            ...
        , CONSTRAINT PRODUIT_PK PRIMARY KEY (ProduitId) 
        , CONSTRAINT PRODUIT_AK UNIQUE (ProduitCode)
    ) ;
    
    CREATE TABLE CLIENT
    (
            ClientId            INT            NOT NULL 
          , ClientCode          CHAR(12)       NOT NULL
          , ClientNom           VARCHAR(64)    NOT NULL
          , ...                 ...            ...
        , CONSTRAINT CLIENT_PK PRIMARY KEY (ClientId) 
        , CONSTRAINT CLIENT_AK UNIQUE (ClientCode)
    ) ;
    
    CREATE TABLE COMMANDE
    (
            CommandeId          INT            NOT NULL
          , CommandeNumero      CHAR(10)       NOT NULL
          , CommandeDate        DATE           NOT NULL
          , ClientId            INT            NOT NULL 
          , ...                 ...            ...
        , CONSTRAINT COMMANDE_PK PRIMARY KEY (CommandeId) 
        , CONSTRAINT COMMANDE_AK UNIQUE (CommandeNumero)
        , CONSTRAINT COMMANDE_CLIENT_FK FOREIGN KEY (ClientId) REFERENCES CLIENT (ClientId)
    ) ;
    
    CREATE TABLE LIGNE_COMMANDE
    (
            CommandeId          INT            NOT NULL
          , LigneId             INT            NOT NULL
          , ProduitId           INT            NOT NULL
          , Quantite            INT            NOT NULL 
        , CONSTRAINT LIGNE_COMMANDE_PK PRIMARY KEY (CommandeId, LigneId) 
        , CONSTRAINT LIGNE_COMMANDE_COMMANDE_FK FOREIGN KEY (CommandeId) REFERENCES COMMANDE (CommandeId)
        , CONSTRAINT LIGNE_COMMANDE_PRODUIT_FK FOREIGN KEY (ProduitId) REFERENCES PRODUIT (ProduitId)
    ) ;
    
    
    Notre souci de traduire l’identification relative en SQL a fait qu’on a mis en œuvre pour la table LIGNE_COMMANDE (manuellement ou par le truchement de l’AGL si celui-ci sait de quoi il s’agit), les deux contraintes suivantes :

    LIGNE_COMMANDE_PK PRIMARY KEY (CommandeId, LigneId)
    LIGNE_COMMANDE_COMMANDE_FK FOREIGN KEY (CommandeId) REFERENCES COMMANDE (CommandeId)

    Où l’attribut CommandeId est « hérité » de la table COMMANDE.

    De son côté, SQL n’a pas d’état d’âme... Il garantira l’intégrité des données en fonction des contraintes qu’on aura bien voulu lui déclarer...



    Citation Envoyé par Aizen64 Voir le message
    Est ce que c'est lié à ON DELETE CASCADE si la relation est identifiante et ON DELETE NO ACTION si la relation est non-identifiante ?
    Comme je l’ai déjà dit, c’est nous qui décidons si la suppression d’une entité faible est la conséquence de celle d’une entité plus forte, indépendamment de la façon dont nous avons rédigé le CREATE TABLE.

    Que l’on ait utilisé l’identification relative :

    CONSTRAINT LIGNE_COMMANDE_PK PRIMARY KEY (CommandeId, LigneId)

    Ou l’identification absolue :

    CONSTRAINT LIGNE_COMMANDE_PK PRIMARY KEY (CommandeId)

    Dans les deux cas, si nous jugeons que la suppression d’une commande doit entraîner celle de ses lignes, on complétera ainsi la contrainte LIGNE_COMMANDE_COMMANDE_FK :

    LIGNE_COMMANDE_COMMANDE_FK FOREIGN KEY (CommandeId) REFERENCES COMMANDE (CommandeId) ON DELETE CASCADE

    En rappelant que, par défaut, l’option est NO ACTION.

    Cela dit, si vous codiez

    CONSTRAINT LIGNE_COMMANDE_PRODUIT_FK FOREIGN KEY (ProduitId) REFERENCES PRODUIT (ProduitId) ON DELETE CASCADE

    Le SGBD tentera (avec succès !) de supprimer les lignes de commande référençant un produit qu’on supprime. Qu’en penseront les utilisateurs ? C’est une autre paire de manches, mais on remonte alors à un niveau plus sémantique que technique, et celui qui aura codé le malencontreux ON DELETE CASCADE se fera sérieusement remonter les bretelles...
    (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.

Discussions similaires

  1. [AC-2010] Base de données de contacts: importer plusieurs fichiers Excel de suite
    Par Venentius dans le forum VBA Access
    Réponses: 4
    Dernier message: 12/05/2015, 14h14
  2. Réponses: 1
    Dernier message: 27/04/2015, 11h06
  3. Réponses: 6
    Dernier message: 04/11/2014, 15h41
  4. [AC-2010] Modifier la base de données Web-Contact
    Par ClaireAl dans le forum Access
    Réponses: 1
    Dernier message: 22/03/2012, 15h32
  5. Base de données Contacts
    Par flaca dans le forum Access
    Réponses: 2
    Dernier message: 05/05/2008, 17h25

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