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 :

Meilleures méthode pour une table de liaison


Sujet :

Schéma

  1. #1
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut Meilleures méthode pour une table de liaison
    Bonjour.

    Je dispose de 4 tables :

    T_CLIENTS
    CLI_ID
    etc

    T_EMPLOYES
    EMP_ID
    etc

    T_FOURNISSEURS
    FOU_ID
    etc

    T_TRANSPORTEURS
    TRA_ID
    etc

    J'ai 3 tables communes :

    T_ADRESSES
    ADR_ID
    etc

    T_TELEPHONES
    TEL_ID
    etc

    T_EMAILS
    EMA_ID
    etc

    Note : ces 3 tables sont reliées à d'autres tables, comme les localités, les types de téléphone (fixe, portable, fax), les types d'adresses email... mais ne posent aucun problème.

    Les 4 premières tables sont donc composées de personnes. Ce que je cherche, c'est trouver la meilleure façon d'intercaler une table de liaison entre elles et les 3 tables communes.

    Pour le moment, j'ai créé une table T_GROUPES avec GRO_ID comme clé primaire, reliée :

    - D'un côté à une clé étrangère GRO_ID dans T_ADRESSES, T_TELEPHONES et T_EMAILS (relation 1:n).
    - De l'autre côté à CLI_ID, EMP_ID, FOU_ID et TRA_ID (relation 1:1).

    Techniquement ça semble fonctionner mais je voudrais savoir si il n'y a pas une méthode plus académique.

    Merci.

  2. #2
    Modérateur

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

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

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Voici la méthode pour modéliser correctement.

    Dans votre cas...
    Les 4 premières tables sont donc composées de personnes.
    Les employés sont des personnes physiques mais les clients, par forcément et les fournisseurs et transporteurs sont des personnes morales, mêmes si certaines peuvent aussi être des personnes physiques (travailleurs indépendants).

    Il convient donc de commencer par faire un héritage...

    Règles de gestion :
    R1 : Une personne physique est une personne et une personne peut être une personne physique.
    R2 : Une personne morale est une personne et une personne peut être une personne morale.
    R3 : Un employé est une personne physique et une personne physique peut être un employé.
    R4 : Un fournisseur est une personne morale et une personne morale peut être un fournisseur.
    R5 : Un transporteur est une personne morale et une personne morale peut être un transporteur.

    Pour les clients, s'ils peuvent être personne physique ou morale alors il faut associer à personne ; si ce ne sont que des clients physiques alors il faut associer à personne physique et si ce ne sont que les entreprises ou autres personnes morales alors il faut associer à personne morale. Je vous laisse faire l'exercice selon votre cas.

    MCD :
    employe -(1,1)----être----0,1- personne_physique -(1,1)----être----0,1- personne
    fournisseur -(1,1)----être----0,1- personne_morale -(1,1)----être----0,1-------|
    transporteur -(1,1)----être----0,1----------|

    Tables :
    T_PERSONNE (prs_id, prs_nom_usuel...)
    TH_PERSONNE_PHYSIQUE (pph_id_personne, pph_id_civilite, pph_prenom...)
    TH_EMPLOYE (emp_id_personne_physique, emp_nom_naissance, emp_matricule, emp_date_naissance, emp_date_entree...)
    TH_PERSONNE_MORALE (pmr_id_personne, pmr_raison_sociale, pmr_siret...)
    TH_FOURNISSEUR (fou_id_personne_morale, fou_echeance_paiement, fou_jour_fin_mois...)
    TH_TRANSPORTEUR (trn_id_personne_morale, trn_volume_max_transportable...)

    => Dans chaque table d'héritage, on ne met que les colonnes spécifiques à ce que représente la table + l'identifiant du bon niveau de personne qui est à la fois clé primaire et clé étrangère.

    Passons à la suite...
    Ce que je cherche, c'est trouver la meilleure façon d'intercaler une table de liaison entre elles et les 3 tables communes.
    Règles de gestion :
    R6 : Une personne peut résider à plusieurs adresses et une adresse peut voir résider plusieurs personnes.
    R7 : Une personne peut avoir plusieurs téléphones et un téléphone appartient à une seule personne.
    R8 : Une personne peut avoir plusieurs emails et un email appartient à une seule personne.

    MCD :
    personne -0,n----resider----1,n- adresse
    |-------------0,n----posséder----1,1- telephone
    |-------------0,n----posseder----1,1- email

    Tables :
    T_ADRESSE (adr_id, adr_id_ville, adr_code_postal, adr_localite, adr_precision_geographique, adr_precision_exterieure, adr_precision_interieure)
    TJ_PRS_RESIDER_ADR (pra_id_personne, pra_id_adresse...)
    T_TELEPHONE (tel_id, tel_id_personne, tel_numero...)
    T_EMAIL (ema_id, ema_id_personne, ema_email...)
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 130
    Points : 38 543
    Points
    38 543
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Je suis d'accord avec ce qui précède, à une correction près : en cas d'héritage, sauf intervention manuelle dans le script, la table fille (le sous-type) hérite de l'identifiant de la table mère (le surtype). La ou les colonnes qui servent d'identifiant portent donc le même nom.

    Donc, dans l'exemple ci-dessus, si l'identifiant de la table des personne T_PERSONNE est PRS_id, alors c'est ce même nom qu'on doit retrouver dans les tables TH_PERSONNE_PHYSIQUE et TH_PERSONNE_MORALE
    Il en va de même bien sûr pour les fournisseurs et transporteurs s'ils sont des sous-types des personnes morales
    D'ailleurs, un transporteur peut être considéré comme un fournisseur (éventuellement un sous-type si ses attributs ou des associations particulières le justifient)

    Même combat pour les clients qui n'ont pas été évoqués dans l'exemple qui précède.

  4. #4
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Merci déjà pour cette réponse qui m'a l'air bien complexe.

    Alors, j'entends par personnes, soit des individus (employés, clients) soit encore des individus qui travaillent au sein de sociétés tierces, les fournisseurs et les transporteurs (un champ "contact", donc une personne, est prévu dans chaque table).

    Chaque individu (client, employé) ou chaque société tierce possède une adresse, un téléphone et une adresse email. Ces champs étant formatés pareillement et retournant sur les mêmes informations, faire une table commune pour toutes les adresses (+ toutes les localités), tous les téléphones et tous les émails m'a semblé logique.

    Néanmoins, comme tu dis, comme chaque "individu" peut avoir plusieurs adresses, téléphones et émails, c'est prévu dans la base (tables types de téléphones, types d'adresses, localisation des téléphones).

  5. #5
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Si ça peut aider à y voir plus clair, une partie du modèle avec les tables concernées :
    Images attachées Images attachées  

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 130
    Points : 38 543
    Points
    38 543
    Billets dans le blog
    9
    Par défaut
    Voici un exemple de modélisation possible pour les éléments fournis

    La modélisation des adresses n'y apparait pas mais c'est le même principe que pour les téléphones
    Adresses et téléphones sont associés au sur-type personne
    Les sous types héritent de l'identifiant du sur-type c'est donc à la fois une PK et une FK (avec une contrainte de type "reference" dans chaque sous-type)

    Ce modèle prévoit qu'une personne physique peut (mini zéro) exercer plusieurs (maxi n) rôles dans différents services, mais un seul rôle dans un même service (flèche vers le rôle matérialisant cette contrainte). Ca signifie que le rôle ne participe pas à la PK de la table issue de l'association "exercer", c'est ce qui le rend unique pour un couple personne et service

    Pièce jointe 582568

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

    A propos de méthode académique.

    L’Académie (les bons auteurs) recommande de ne pas mettre la charrue avant les bœufs... Pour aller dans le sens de CinePhil. Je rappelle :

    (1) Formaliser les règles de gestion.

    Ces règles expriment l’aspect fonctionnel d’un problème posé à l’utilisateur non informaticien, règles que celui-ci nous transmet de façon informelle et souvent incomplète et ambiguë (« Les personnes ont des téléphones ») et que nous devons réécrire de façon formelle et sans ambiguïté comme le fait CinePhil. Exemple : « Une personne a au moins un téléphone », « Un téléphone appartient à au moins et au plus une personne ».


    (2) Modéliser les données.  

    Pour cela il existe fondamentalement l’ouvrage remarquable de D. Nanci (RIP) et B Espinasse Ingénierie des systèmes d'information : Merise deuxième génération (4e édition, 2001), c’est l’ouvrage de référence. Le chapitre à étudier est le chapitre 7 (« Modélisation conceptuelle des données »). Dans le cas particulier de l’héritage, c’est-à-dire la spécialisation / généralisation des entités-types (clients, employés, fournisseurs, transporteurs), voyez le paragraphe « Types et sous-types d’entités : spécialisation/généralisation », pages 106 et suivantes. Dans votre cas, il s’agit vraisemblablement d’une généralisation (factorisation des attributs). Notez la factorisation des adresses et téléphones, par connexion sur l’entité-type PERSONNE).


    (3) Pour construire le MCD, utilisez un bon outil de modélisation, à savoir Looping, gracieusement proposé par le professeur Patrick Bergougnoux (on ne remerciera jamais assez Paprick !)

    Exemple (ébauche, en 15 minutes), à la croisée en gros de votre modèle, de celui d’Escartefigue et de l’exemple de CinePhil

    Nom : Nerva - mcd, spécialisation_loo.png
Affichages : 1562
Taille : 28,8 Ko


    (4) Si votre SGBD est orienté SQL, alors le code SQL généré automatiquement par Looping pourra être exploité sans difficulté. Si vous utilisez un outil orienté QBE (Query By Example), c’est-à-dire d’un outil où SQL, s’il est présent, est caché sous le capot, et s’il s’agit d’ACCESS, Looping sait générer le code SQL à mettre sous le capot.

    Code généré automatiquement par Looping à partir du MCD :

    CREATE TABLE PERSONNE(
       personneId INT,
       CONSTRAINT PERSONNE_PK PRIMARY KEY(personneId)
    );
    
    CREATE TABLE SOCIETE(
       personneId INT,
       siret DECIMAL(14,0) NOT NULL,
       raisonSociale VARCHAR(48) NOT NULL,
       contact VARCHAR(48) NOT NULL,
       CONSTRAINT SOCIETE_PK PRIMARY KEY(personneId),
       CONSTRAINT SOCIETE_AK UNIQUE(siret),
       CONSTRAINT SOCIETE_PERSONNE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE(personneId)
    );
    
    CREATE TABLE FOURNISSEUR(
       personneId INT,
       tauxRemise DECIMAL(4,2) NOT NULL,
       CONSTRAINT FOURNISSEUR_PK PRIMARY KEY(personneId),
       CONSTRAINT FOURNISSEUR_SOCIETE_FK FOREIGN KEY(personneId) REFERENCES SOCIETE(personneId)
    );
    
    CREATE TABLE TRANSPORTEUR(
       personneId INT,
       CONSTRAINT TRANSPORTEUR_PK PRIMARY KEY(personneId),
       CONSTRAINT TRANSPORTEUR_SOCIETE_FK FOREIGN KEY(personneId) REFERENCES SOCIETE(personneId)
    );
    
    CREATE TABLE ADRESSE(
       adresseId INT,
       adresseLigne1 VARCHAR(48) NOT NULL,
       adresseLigne2 VARCHAR(48) NOT NULL,
       codePostal VARCHAR(5) NOT NULL,
       localite VARCHAR(48) NOT NULL,
       personneId INT NOT NULL,
       CONSTRAINT ADRESSE_PK PRIMARY KEY(adresseId),
       CONSTRAINT ADRESSE_PERSONNE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE(personneId)
    );
    
    CREATE TABLE TELEPHONE(
       telephoneId INT,
       telephoneNumero VARCHAR(24) NOT NULL,
       personneId INT NOT NULL,
       CONSTRAINT TELEPHONE_PK PRIMARY KEY(telephoneId),
       CONSTRAINT TELEPHONE_PERSONNE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE(personneId)
    );
    
    CREATE TABLE SITE(
       siteId INT,
       nomSite VARCHAR(48) NOT NULL,
       CONSTRAINT SITE_PK PRIMARY KEY(siteId)
    );
    
    CREATE TABLE TITRE(
       titId INT,
       titNom VARCHAR(48) NOT NULL,
       CONSTRAINT TITRE_PK PRIMARY KEY(titId),
       CONSTRAINT TITRE_AK UNIQUE(titNom)
    );
    
    CREATE TABLE PERSONNE_PHYSIQUE(
       personneId INT,
       nom VARCHAR(48) NOT NULL,
       prenom VARCHAR(48) NOT NULL,
       dateEntree DATE NOT NULL,
       dateNaissance DATE NOT NULL,
       titId INT NOT NULL,
       CONSTRAINT PERSONNE_PHYSIQUE_PK PRIMARY KEY(personneId),
       CONSTRAINT PERSONNE_PHYSIQUE_PERSONNE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE(personneId),
       CONSTRAINT PERSONNE_PHYSIQUE_TITRE_FK FOREIGN KEY(titId) REFERENCES TITRE(titId)
    );
    
    CREATE TABLE CLIENT(
       personneId INT,
       CONSTRAINT CLIENT_PK PRIMARY KEY(personneId),
       CONSTRAINT CLIENT_PERSONNE_PHYSIQUE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE_PHYSIQUE(personneId)
    );
    
    CREATE TABLE EMPLOYE(
       personneId INT,
       numSS CHAR(15) NOT NULL,
       CONSTRAINT EMPLOYE_PK PRIMARY KEY(personneId),
       CONSTRAINT EMPLOYE_AK UNIQUE(numSS),
       CONSTRAINT EMPLOYE_PERSONNE_PHYSIQUE_FK FOREIGN KEY(personneId) REFERENCES PERSONNE_PHYSIQUE(personneId)
    );
    
    CREATE TABLE EmpSite(
       personneId INT,
       siteId INT,
       CONSTRAINT EmpSite_PK PRIMARY KEY(personneId, siteId),
       CONSTRAINT EmpSite_EMPLOYE_FK FOREIGN KEY(personneId) REFERENCES EMPLOYE(personneId),
       CONSTRAINT EmpSite_SITE_FK FOREIGN KEY(siteId) REFERENCES SITE(siteId)
    );
    Vous avez utilisé MySQL Workbench. Quel est votre SGBD ? MySQL ?
    Quant à MySQL Workbench, voyez mon article, dans lequel incidemment je traite de l’héritage : MySQL Workbench


    Votre schéma comporte une table T_GROUPES, dans lequel manifestement vous raisonnez AVOIR (un groupe a des éléments), alors qu’avec la spécialisation / généralisation on raisonne ÊTRE (un employé est une personne physique, donc plus généralement une personne).

    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.

  8. #8
    Modérateur

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

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

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par escartefigue
    en cas d'héritage, sauf intervention manuelle dans le script, la table fille (le sous-type) hérite de l'identifiant de la table mère (le surtype). La ou les colonnes qui servent d'identifiant portent donc le même nom.

    Donc, dans l'exemple ci-dessus, si l'identifiant de la table des personne T_PERSONNE est PRS_id, alors c'est ce même nom qu'on doit retrouver dans les tables TH_PERSONNE_PHYSIQUE et TH_PERSONNE_MORALE
    Ok alors comment faire quand il y a dans une table deux colonnes qui réfèrent à la même colonne externe ? Exemple classique de la famille (une personne a pour parent une autre personne) ou de la hiérarchie (un employé a pour supérieur un autre employé) ? On est bien obligé de différencier le prs_id de la personne et le prs_id du parent ou du supérieur. Si on peut le faire là, pourquoi pas dans tous les autres cas ? L'avantage de nommer comme je le fais est qu'on sait immédiatement d'où vient la colonne et on peut lire l'association entre les tables rien qu'en lisant le nom de la colonne portant la clé étrangère. Si je propage prs_id jusqu'en bas de l'arbre des héritages, j'aurai tendance à penser que tout est associé à la table personne alors que ce n'est pas le cas.

    Citation Envoyé par escartefigue
    D'ailleurs, un transporteur peut être considéré comme un fournisseur (éventuellement un sous-type si ses attributs ou des associations particulières le justifient)
    Exact, j'aurais pu faire un niveau hiérarchique supplémentaire en associant transporteur à fournisseur.

    Citation Envoyé par Nerva
    Alors, j'entends par personnes, soit des individus (employés, clients) soit encore des individus qui travaillent au sein de sociétés tierces, les fournisseurs et les transporteurs (un champ "contact", donc une personne, est prévu dans chaque table).
    Donc nous avons bien là des personnes physiques et des personnes morales, comme je l'ai modélisé.

    Chaque individu (client, employé) ou chaque société tierce possède une adresse, un téléphone et une adresse email. Ces champs étant formatés pareillement et retournant sur les mêmes informations, faire une table commune pour toutes les adresses (+ toutes les localités), tous les téléphones et tous les émails m'a semblé logique.
    Dans mon modèle, il n'y a bien qu'une table pour les adresses, une table pour les téléphones et une table pour les e-mails.

    Néanmoins, comme tu dis, comme chaque "individu" peut avoir plusieurs adresses, téléphones et émails, c'est prévu dans la base (tables types de téléphones, types d'adresses, localisation des téléphones).
    Donc mon modèle est valable.

    Si ça peut aider à y voir plus clair, une partie du modèle avec les tables concernées :
    Je ne vois toujours pas l'intérêt des groupes. Et que représente T_GROUPES_TY ? Adoptez des noms clairs ! Et au passage, nommez vos tables au singulier ! La composition de la table T_EMPLOYE représente UN employé, même si on va en enregistrer plusieurs dedans (UN par ligne de la table).

    De même, que représentent T_EMAILS_LO et T_TELEPHONES_LO ?

    Il y aurait d'autres remarques à faire mais j'ai à faire ; j'y reviendrai plus tard.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Avant de répondre et d'y revenir, va déjà falloir que je digère tout ça ! N'étant pas familier des représentations graphiques autres que celles des liaisons par champs des SGBDR (Access et LO Base), ce n'est pas facile d'accès.

    Là effectivement, je vais tester (bien que ça ne change rien au problème) une connexion LO Base/MySql.

    Quelques éléments de réponse quand même...

    Pour les champs _LO et _TY.

    Je pars du principe qu'une personne peut avoir plusieurs numéros de téléphones qui peuvent être :

    - Fixe, portable, fax... Le _TY.
    - Domicile, bureau... Le _LO.

    Combinés, ça peut faire beaucoup de numéros et on peut avoir besoin de discerner plusieurs numéros sur plus d'un seul critère.

    Dans T_GROUPES

    GRO_ID : Clé primaire.
    GRO_TY_ID : Clé étrangère, valeur de 1, 2, 3 ou 4, soit les 4 types de personnes.

    Dans T_GROUPES_TY
    GRO_TY_ID : Clé primaire
    GRO_TY_LIB : Désignation des 4 types de personnes.

    L'intérêt des groupes, ben justement, c'est la table que j'ai pour l'instant intercalée pour permettre l'accès aux adresses, emails et téléphones aux 4 groupes de personnes.

  10. #10
    Modérateur

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

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

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Pour les champs _LO et _TY.

    Je pars du principe qu'une personne peut avoir plusieurs numéros de téléphones qui peuvent être :

    - Fixe, portable, fax... Le _TY.
    - Domicile, bureau... Le _LO.
    Donc plutôt les nommer : _TYPE et _LOCALISATION

    Et pour la localisation, plutôt que Domicile et bureau, je mettrais plutôt Personnel et Professionnel ; et donc plutôt utilisation que localisation. Parce que localiser un téléphone portable, qui bouge tout le temps avec son propriétaire... Par contre j'ai effectivement 2 portables : un perso et un pro.

    Abandonnez cette idée de groupe telle que vous souhaitez l'utiliser ; ça n'apporte rien.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 130
    Points : 38 543
    Points
    38 543
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Ok alors comment faire quand il y a dans une table deux colonnes qui réfèrent à la même colonne externe ? Exemple classique de la famille (une personne a pour parent une autre personne) ou de la hiérarchie (un employé a pour supérieur un autre employé) ? On est bien obligé de différencier le prs_id de la personne et le prs_id du parent ou du supérieur. Si on peut le faire là, pourquoi pas dans tous les autres cas ? L'avantage de nommer comme je le fais est qu'on sait immédiatement d'où vient la colonne et on peut lire l'association entre les tables rien qu'en lisant le nom de la colonne portant la clé étrangère. Si je propage prs_id jusqu'en bas de l'arbre des héritages, j'aurai tendance à penser que tout est associé à la table personne alors que ce n'est pas le cas.
    Sauf que dans le cas de l'héritage, la PK du surtype est directement héritée comme PK dans le sous-type (et également comme FK du coup avec une contrainte de type référence), il n'y a pas ici deux colonnes synonymes (contrairement au cas de hiérarchie ou de parentalité)
    Donc il n'y a absolument aucun intérêt à modifier le DDL pour modifier le nom et même au contraire : la PK venant du surtype, en modifier le nom pourrait faire croire que ce n'est pas le cas.
    Dans le cas d'une hiérarchie ou d'une relation parent/enfant par contre, le renommage est à la fois utile et nécessaire



    Citation Envoyé par Nerva Voir le message
    Pour les champs _LO et _TY.
    Je pars du principe qu'une personne peut avoir plusieurs numéros de téléphones qui peuvent être :

    - Fixe, portable, fax... Le _TY.
    - Domicile, bureau... Le _LO.
    Et également : portable d'astreinte, portable perso, portable pro...
    Donc, plutôt que d'une localisation, il s'agit plutôt d'un usage de l'appareil

  12. #12
    Membre émérite
    Avatar de Paprick
    Homme Profil pro
    Professeur des Universités
    Inscrit en
    Juin 2019
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Professeur des Universités
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2019
    Messages : 678
    Points : 2 716
    Points
    2 716
    Par défaut
    Bonsoir,
    Citation Envoyé par CinePhil Voir le message
    Ok alors comment faire quand il y a dans une table deux colonnes qui réfèrent à la même colonne externe ? Exemple classique de la famille (une personne a pour parent une autre personne) ou de la hiérarchie (un employé a pour supérieur un autre employé) ? On est bien obligé de différencier le prs_id de la personne et le prs_id du parent ou du supérieur. Si on peut le faire là, pourquoi pas dans tous les autres cas ? L'avantage de nommer comme je le fais est qu'on sait immédiatement d'où vient la colonne et on peut lire l'association entre les tables rien qu'en lisant le nom de la colonne portant la clé étrangère. Si je propage prs_id jusqu'en bas de l'arbre des héritages, j'aurai tendance à penser que tout est associé à la table personne alors que ce n'est pas le cas.
    Je suis d'accord sur la nécessité de pouvoir, pour ceux qui le souhaitent, nommer les clés étrangères issues d'un héritage de manière à retrouver plus facilement leur origine : pour cela, avec Looping, il suffit de spécifier un rôle sur la patte d'héritage de la classe fille et de demander à ce que ce rôle suffixe le nom de la clé primaire de la classe mère (la version 3.0 proposera même de renommer la clé étrangère avec le libellé du rôle).
    De cette manière, le code SQL généré reste conforme au MCD sans intervention manuelle sur le script.
    Pour moi, il est en effet essentiel de maintenir une totale cohérence entre MCD et code SQL généré... sinon, les apprentis sorciers en conception BD auront vite fait de négliger la phase de modélisation, comme c'est déjà trop souvent le cas ...
    Je rappelle également que les classes filles peuvent avoir leur propre identifiant, l'identifiant de la classe mère devenant alors une simple clé étrangère ne participant pas à la clé primaire des classes filles : c'est ce qui distingue, pour moi, la généralisation de la spécialisation.
    Patrick Bergougnoux - Professeur des Universités au Département Informatique de l'IUT de Toulouse III
    La simplicité est la sophistication suprême (Léonard de Vinci)
    LIVRE : Modélisation Conceptuelle de Données - Une Démarche Pragmatique
    Looping - Logiciel de modélisation gratuit et libre d'utilisation

  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
    Citation Envoyé par Nerva Voir le message
    N'étant pas familier des représentations graphiques autres que celles des liaisons par champs des SGBDR (Access et LO Base), ce n'est pas facile d'accès.
    Bon... Suite à rétro-conception à l’aide de MySQL Workbench du code SQL produit par Looping (cf. post #7), le diagramme caca-boudin à la ACCESS est celui-ci :

    Nom : Nerva - mwb notation access.png
Affichages : 1507
Taille : 131,7 Ko

    En utilisant la notation “patte d’oie” quand même moins pauvre (présence cette fois-ci des cardinalités minimales) :

    Nom : Nerva - mwb notation ie.png
Affichages : 1614
Taille : 95,5 Ko

    N.B. Avec les vrais SGBD SQL, on ne parle pas de champs, mais de colonnes, et comme dirait CinePhil, les champs c’est pour les pommes de terre et autres.
    (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 régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    @fsmrel, j'ai utilisé le SQL pour faire un test dans LO Base, qui a créé tables et relations sans broncher. Il y a une clé primaire personneid dans 10 tables et même si je commence à comprendre la logique là je ne sais pas du tout comment procéder pour tester.

  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
    Bonjour Nerva,

    Je me suis fait un petit jeu d’essai (MySQL), avec CREATE TABLE, et INSERT. Vous pouvez l’essayer.

    A noter :

    (1) J’ai établi une relation d’appartenance entre PERSONNE_PHYSIQUE et SOCIETE. On peut raffiner à la manière d’Escartefigue (cf. post #6).

    (2) Notez les ON DELETE CASCADE : quand on supprime une personne, c’est complètement, pas à moitié.

    (3) Les Mousquetaires qui participent à cette discussion noteront que je n’ai pas utilisé les identifiants artificiels (avec auto-incrémentation) : pour le moment n’ajoutons pas de la complexité à la complexité, chaque chose en son temps.

    CREATE DATABASE IF NOT EXISTS nerva ;
    
    USE nerva ;
    
    DROP TABLE IF EXISTS CLIENT ;
    DROP TABLE IF EXISTS EMPLOYE ;
    DROP TABLE IF EXISTS PERSONNE_PHYSIQUE ;
    DROP TABLE IF EXISTS FOURNISSEUR ;
    DROP TABLE IF EXISTS TRANSPORTEUR ;
    DROP TABLE IF EXISTS SOCIETE ;
    DROP TABLE IF EXISTS ADRESSE ;
    DROP TABLE IF EXISTS TELEPHONE ;
    DROP TABLE IF EXISTS PERSONNE ;
    DROP TABLE IF EXISTS SITE ;
    DROP TABLE IF EXISTS TITRE ;
    
    CREATE TABLE TITRE
    (
       titId         INT,
       titNom        VARCHAR(48) NOT NULL,
       CONSTRAINT TITRE_PK PRIMARY KEY(titId),
       CONSTRAINT TITRE_AK UNIQUE(titNom)
    );
    
    INSERT INTO TITRE (titId, titNom)
    VALUES 
        (1, 'titre a')
      , (2, 'titre b')
      , (3, 'titre c')
    ;
    
    SELECT * FROM TITRE ;
    
    CREATE TABLE SITE 
    (
       siteId         INT,
       siteNom        VARCHAR(48)          NOT NULL,
       CONSTRAINT SITE_PK PRIMARY KEY(siteId)
    );
    
    INSERT INTO SITE (siteId, siteNom)
    VALUES 
        (1, 'site a')
      , (2, 'site b')
      , (3, 'site c')
    ;
    
    SELECT * FROM SITE ;
    
    CREATE TABLE PERSONNE
    (
       personneId INT,
       CONSTRAINT PERSONNE_PK PRIMARY KEY(personneId)
    );
    INSERT INTO PERSONNE (personneId) 
    VALUES 
        (1)
      , (2)
      , (3)
      , (4)
      , (5)
      , (6)
      , (7)
      , (8)
      , (9)
      , (11)
      , (12)
      , (13)
      , (14)
      , (15)
      , (16)
      , (17)
      , (18)
      , (19)
    ;
    
    SELECT * FROM PERSONNE ;
    
    CREATE TABLE ADRESSE
    (
       adresseId            INT,
       adresseLigne1        VARCHAR(48)        NOT NULL,
       adresseLigne2        VARCHAR(48)        NOT NULL,
       codePostal           VARCHAR(5)         NOT NULL,
       localite             VARCHAR(48)        NOT NULL,
       personneId           INT                NOT NULL,
       CONSTRAINT ADRESSE_PK PRIMARY KEY(adresseId),
       CONSTRAINT ADRESSE_PERSONNE_FK FOREIGN KEY(personneId) 
           REFERENCES PERSONNE(personneId)
           ON DELETE CASCADE
    );
    
    INSERT INTO ADRESSE (personneId, adresseId, codePostal, localite, adresseLigne1, adresseLigne2) 
    VALUES 
        (1, 1, '75001', 'Paris', 'Ets Fernand Naudin', '3 rue en pente')
      , (2, 2, '75008', 'Paris', 'Volfoni frères', 'Quai des péniches')
    ;
    
    SELECT * FROM ADRESSE ; 
    
    CREATE TABLE TELEPHONE
    (
       telephoneId         INT,
       telephoneNumero     VARCHAR(24)         NOT NULL,
       personneId          INT                 NOT NULL, 
       CONSTRAINT TELEPHONE_PK PRIMARY KEY(telephoneId),
       CONSTRAINT TELEPHONE_PERSONNE_FK FOREIGN KEY(personneId) 
           REFERENCES PERSONNE(personneId)
           ON DELETE CASCADE
    );
    
    CREATE TABLE SOCIETE
    (
       personneId        INT,
       siret             DECIMAL(14,0)            NOT NULL,
       raisonSociale     VARCHAR(48)              NOT NULL,
       contact           VARCHAR(48)              NOT NULL,
       CONSTRAINT SOCIETE_PK PRIMARY KEY(personneId),
       CONSTRAINT SOCIETE_AK UNIQUE(siret),
       CONSTRAINT SOCIETE_PERSONNE_FK FOREIGN KEY(personneId) 
           REFERENCES PERSONNE(personneId)
           ON DELETE CASCADE
    );
    
    INSERT INTO SOCIETE (personneId, siret, raisonSociale, contact)
    VALUES
        (1, '12345678901234', 'Ets Naudin', 'Mle Noelle Joyeux')
      , (2, '23456789012345', 'Commerces divers', 'Mme Mado')
      , (3, '45678901234567', 'Les expéditions rapides', 'M. Marc')
      , (4, '34567890123456', 'A la bonne roulette', 'M. Luc')
    ;
    SELECT * FROM SOCIETE ; 
    
    CREATE TABLE FOURNISSEUR
    (
       personneId     INT,
       tauxRemise     DECIMAL(4,2)      NOT NULL,
       CONSTRAINT FOURNISSEUR_PK PRIMARY KEY(personneId),
       CONSTRAINT FOURNISSEUR_SOCIETE_FK 
           FOREIGN KEY(personneId) REFERENCES SOCIETE(personneId)
           ON DELETE CASCADE            
    );
    
    INSERT INTO FOURNISSEUR (personneId, tauxRemise)
    VALUES
        (1, 10)
      , (2, 0)
      , (4, 5)
    ; 
    
    SELECT * FROM FOURNISSEUR ; 
    
    CREATE TABLE TRANSPORTEUR
    (
       personneId     INT,
       CONSTRAINT TRANSPORTEUR_PK PRIMARY KEY(personneId),
       CONSTRAINT TRANSPORTEUR_SOCIETE_FK FOREIGN KEY(personneId) 
           REFERENCES SOCIETE(personneId)
           ON DELETE CASCADE
    );
    
    INSERT INTO TRANSPORTEUR (personneId)
    VALUES
        (3)
    ; 
    
    SELECT * FROM TRANSPORTEUR ; 
    
    CREATE TABLE PERSONNE_PHYSIQUE
    (
            personneId             INT,
            nom                    VARCHAR(48)      NOT NULL,
            prenom                 VARCHAR(48)      NOT NULL,
            dateEntree             DATE             NOT NULL,
            dateNaissance          DATE             NOT NULL,
            titId                  INT              NOT NULL,
            societeId              INT              NOT NULL,
       CONSTRAINT PERSONNE_PHYSIQUE_PK PRIMARY KEY(personneId),
       CONSTRAINT PERSONNE_PHYSIQUE_PERSONNE_FK FOREIGN KEY(personneId) 
           REFERENCES PERSONNE (personneId)
           ON DELETE CASCADE,
       CONSTRAINT PERSONNE_PHYSIQUE_SOCIETE_FK FOREIGN KEY(societeId) 
           REFERENCES SOCIETE (personneId),
       CONSTRAINT PERSONNE_PHYSIQUE_TITRE_FK FOREIGN KEY(titId) 
           REFERENCES TITRE (titId)
    );
    
    INSERT INTO PERSONNE_PHYSIQUE (personneId, societeId, nom, prenom, dateEntree, dateNaissance, titId)
    VALUES
        (11, 1, 'Naudin', 'Fernand', '1962-10-21', '1919-07-14', 1)
      , (12, 2, 'Volfoni', 'Raoul', '1962-12-14', '1916-01-11', 2)
      , (13, 2, 'Volfoni', 'Paul', '1962-12-14', '1919-10-03', 2)
      , (14, 1, 'Folace', 'Francis', '1962-10-22', '1921-07-20', 3)
      , (15, 1, 'Jean', 'Jean', '1962-10-22', '1903-07-19', 3)
      , (16, 2, 'Pascal', 'Pascal', '1963-01-07', '1930-04-17', 3)
      , (17, 2, 'Bastien', 'Mac', '1963-01-07', '1913-06-20', 3)
      , (18, 3, 'Théo', 'Théo', '1963-01-07', '1929-07-28', 3)
      , (19, 4, 'Tomate', 'Tomate', '1962-12-21', '1914-07-22', 3)
    ;
    
    SELECT * FROM PERSONNE_PHYSIQUE ; 
    
    CREATE TABLE EMPLOYE
    (
            personneId             INT,
            numSS                  CHAR(15)         NOT NULL,
            siteId                 INT              NOT NULL,
       CONSTRAINT EMPLOYE_PK PRIMARY KEY(personneId),
       CONSTRAINT EMPLOYE_AK UNIQUE(numSS),
       CONSTRAINT EMPLOYE_PERSONNE_PHYSIQUE_FK FOREIGN KEY(personneId) 
           REFERENCES PERSONNE_PHYSIQUE(personneId)
           ON DELETE CASCADE,
       CONSTRAINT EMPLOYE_SITE_FK FOREIGN KEY(siteId) 
           REFERENCES SITE(siteId)
    );
    
    INSERT INTO EMPLOYE (personneId, numSS, siteId)
    VALUES
        (11, '123456789012345', 1)
      , (12, '234567890123451', 2)
      , (13, '345678901234512', 2)
      , (14, '456789012345123', 1)
      , (15, '567890123451234', 1)
      , (16, '678901234512345', 2)
      , (17, '789012345123456', 2)
    ;
    SELECT * FROM EMPLOYE ; 
    
    CREATE TABLE CLIENT
    (
            personneId             INT,
       CONSTRAINT CLIENT_PK PRIMARY KEY(personneId),
        CONSTRAINT CLIENT_PERSONNE_PHYSIQUE_FK FOREIGN KEY(personneId)
            REFERENCES PERSONNE_PHYSIQUE(personneId)
            ON DELETE CASCADE
    );
    INSERT INTO CLIENT (personneId)
    VALUES
        (18)
      , (19)
    ;
    SELECT * FROM CLIENT ; 
    
    ROLLBACK ;
    (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
    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
    J’ajoute au jeu d’essai l’adresse de Me Folace :

    INSERT INTO ADRESSE (personneId, adresseId, codePostal, localite, adresseLigne1, adresseLigne2) 
    VALUES 
        (14, 3, '75008', 'Paris', 'Aux bons soins des Ets Fernand Naudin', '3 rue en pente')
    ; 
    Pour savoir plein de choses sur Me Folace :

    SELECT numSS, nom, dateEntree
         , raisonSociale as Employeur
         , adresseLigne1, adresseLigne2, codePostal, localite
    FROM  EMPLOYE as x
      JOIN PERSONNE_PHYSIQUE as y ON x.personneId = y.personneId  
      JOIN SOCIETE as z ON y.societeId = z.personneId
      JOIN SITE as t ON x.siteId = t.siteId
      JOIN ADRESSE as u ON x.personneId = u.personneId
    WHERE nom = 'Folace'  
    ;
    =>

    numSS            nom     dateEntree  Employeur   adresseLigne1                           adresseLigne2    codePostal  localite
    
    456789012345123  Folace  1962-10-22  Ets Naudin  Aux bons soins des Ets Fernand Naudin   3 rue en pente   75008       Paris 
    (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.

  17. #17
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Alors c'est créé, et maintenant, c'est la question des colonnes en numéro auto...

  18. #18
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Afin de simplifier la représentation, de mon côté j'ai créé une toute petite base sur le même modèle avec seulement 2 tables de personnes bien physiques.

    Nom : Capture du 2020-10-31 13-53-24.png
Affichages : 2514
Taille : 68,8 Ko

  19. #19
    Membre régulier Avatar de Nerva
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    360
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 360
    Points : 94
    Points
    94
    Par défaut
    Alors j'en suis toujours au même point : je ne sais pas où placer le numéro auto.

    J'ai testé sur T_PERSONNES avec PER_ID. J'ai créé un formulaire de test (LO Base) nommé F_EMPLOYES :

    - principal : les colonnes de T_PERSONNES
    - attaché : les colonnes de T_EMPLOYES

    J'en saisi une première, je rentre le numéro SS dans le formulaire attaché, j'en saisi une seconde, tout va bien. J'ai 2 personnes qui sont employés d'enregistrées.

    Je crée un second formulaire (F_CLIENTS) dont la structure est identique au premier :

    - principal : les colonnes de T_PERSONNES
    - attaché : les colonnes de T_CLIENTS

    Et là évidemment rien ne va plus ! J'ai déjà deux enregistrements de remplis avec les données des employés, ce qui vu les relations me paraît logique.

    Ensuite j'ai essayé l'inverse : numéro auto sur T_CLIENTS (ou T_EMPLOYES), formulaire principal avec T_CLIENTS (ou T_EMPLOYES) et attaché avec T_PERSONNES, première saisie, violation de l'intégrité référentielle.

    Je suis donc bloqué...

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    CREATE TABLE T_ADRESSES (
       ADR_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) NOT NULL,
       ADR_L1 VARCHAR(32) NOT NULL,
       ADR_L2 VARCHAR(32),
       ADR_CP CHAR(5) NOT NULL,
       ADR_LOC VARCHAR(48) NOT NULL,
       PER_ID INT NOT NULL,
       CONSTRAINT T_ADRESSES_PK PRIMARY KEY(ADR_ID)
    );
    
    CREATE TABLE T_TELEPHONES (
       TEL_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) NOT NULL,
       TEL_NUM CHAR(10) NOT NULL,
       PER_ID INT NOT NULL,
       CONSTRAINT T_TELEPHONES_PK PRIMARY KEY(TEL_ID)
    );
    
    CREATE TABLE T_TITRES (
       TIT_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) NOT NULL,
       TIT_LIB VARCHAR(4) NOT NULL,
       CONSTRAINT T_TITRES_PK PRIMARY KEY(TIT_ID),
       CONSTRAINT T_TITRES_AK UNIQUE(TIT_LIB)
    );
    
    CREATE TABLE T_PERSONNES (
       PER_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) NOT NULL,
       TIT_ID INT NOT NULL,
       PER_NOM VARCHAR(32) NOT NULL,
       PER_PRENOM VARCHAR(32) NOT NULL,
       PER_DATE_NAIS DATE NOT NULL,
       PER_DATE_ENTREE DATE NOT NULL,
       CONSTRAINT T_PERSONNES_PK PRIMARY KEY(PER_ID)
    );
    
    CREATE TABLE T_CLIENTS (
       PER_ID INTEGER NOT NULL,
       CLI_NUM VARCHAR(16) NOT NULL,
       CONSTRAINT T_CLIENTS_PK PRIMARY KEY(PER_ID)
    );
    
    CREATE TABLE T_EMPLOYES (
       PER_ID INTEGER NOT NULL,
       EMP_NUM_SS CHAR(15) NOT NULL,
       CONSTRAINT T_EMPLOYES_PK PRIMARY KEY(PER_ID),
       CONSTRAINT T_EMPLOYES_AK UNIQUE(EMP_NUM_SS)
    );
    
    ALTER TABLE T_ADRESSES ADD CONSTRAINT T_ADRESSES_T_PERSONNES_FK FOREIGN KEY(PER_ID) REFERENCES T_PERSONNES(PER_ID);
    ALTER TABLE T_TELEPHONES ADD CONSTRAINT T_TELEPHONES_T_PERSONNES_FK FOREIGN KEY(PER_ID) REFERENCES T_PERSONNES(PER_ID);
    ALTER TABLE T_CLIENTS ADD CONSTRAINT T_CLIENTS_T_PERSONNES_FK FOREIGN KEY(PER_ID) REFERENCES T_PERSONNES(PER_ID);
    ALTER TABLE T_EMPLOYES ADD CONSTRAINT T_EMPLOYES_T_PERSONNES_FK FOREIGN KEY(PER_ID) REFERENCES T_PERSONNES(PER_ID);
    ALTER TABLE T_PERSONNES ADD CONSTRAINT T_PERSONNES_T_TITRES_FK FOREIGN KEY(TIT_ID) REFERENCES T_TITRES(TIT_ID);
    Images attachées Images attachées  

  20. #20
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 130
    Points : 38 543
    Points
    38 543
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    @Nerva : si l'adresse est identifiée relativement à la personne, alors l'identifiant adresse doit être de type attribué par le SGBD dans la table adresse mais pas l'identifiant personne. Pour alimenter l'identifiant personne dans la table adresse, il faut récupérer celui-ci dans la table personne !

    Dans la table personne, l'identifiant personne doit être de type attribué par le SGBD

    Par ailleurs, j'avais compris que vous utilisiez le SGBD MySQL, or votre script semble fort être du DB2... à vérifier de votre coté.
    (dans mySQL le type attribué par le SGBD s'appelle "auto_increment" dans DB2 c'est "identity" et le paramètre "GENERATED ALLWAYS ou BY DEFAULT" est spécifique DB2)

Discussions similaires

  1. [AC-97] Requette pour afficher un record en fonction d'une table de liaisons.
    Par Jazz_ dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 16/08/2010, 13h23
  2. Réponses: 3
    Dernier message: 21/01/2009, 22h47
  3. Meilleur méthode pour gérer une liste des blocks
    Par smyley dans le forum Algorithmes et structures de données
    Réponses: 41
    Dernier message: 22/07/2008, 02h06
  4. Meilleure méthode pour vider une JTable
    Par JamesP dans le forum Composants
    Réponses: 9
    Dernier message: 17/08/2007, 11h42
  5. Le meilleur hebergeur pour une table sql ?
    Par CyberTwister dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/12/2006, 04h11

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