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

PostgreSQL Discussion :

Héritage avec PostgreSQL


Sujet :

PostgreSQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Points : 115
    Points
    115
    Par défaut Héritage avec PostgreSQL
    Slt, je suis en train d'essayer de faire un héritage avec PostgreSQL mais je rencontre un problème.

    Je crées un table "mère" Personnes (contenant id_personne + autres champs). Je fais hériter une table nommée adhérents et une autre nommée touristes.

    je fais ensuite une table familles qui a une clé étrangère id_chef_famille référençant l'id d'un adhérent (et surtout pas d'un touriste). Seulement, l'id d’adhérent est celui de la table Personne. Il ne m'est pas possible de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE Familles (
        id_famille integer NOT NULL,
        id_chef_famille integer NOT NULL,
        CONSTRAINT "Familles_pkey" PRIMARY KEY (id_famille),
        CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
            REFERENCES Adherents(id_personne),
    );
    Je suis obligé de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE Familles (
        id_famille integer NOT NULL,
        id_chef_famille integer NOT NULL,
        CONSTRAINT "Familles_pkey" PRIMARY KEY (id_famille),
        CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
            REFERENCES Personnes(id_personne),
    );
    je me suis dit, ce n'est pas un problème il suffira d'ajouter un trigger qui vérifiera que l'id est bien l'id d'un adhérent mais pas d'un touriste.

    J'ajoute donc mon adhérent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO adherents (id_personne, nom, prenom, date_naissance, num_licence, num_secu_sociale, statut)
      VALUES (1, 'Tavernier', 'Bertran', '1961-06-01', 111, 111111, 'Directeur');
    Jusque là tout va bien mais lorsque j'ajoute la nouvelle famille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO familles (id_famille, id_chef_famille, code_postal, ville, pays, num_mobile, num_fixe, email, bateau1, bateau2)
      VALUES (1, 1, 31400, 'Toulouse', 'France', '0612345678', '0412345678', 'bigboss@gmail.com', 2, NULL);
    Il me met une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR:  une instruction insert ou update sur la table « familles » viole la contrainte de clé
    étrangère « Famille_to_Adherents_id_personne »
    DÉTAIL : La clé (id_chef_famille)=(1) n'est pas présente dans la table « personnes ».
    Alors que quand je parcours mes tables, il y a bien mon adhérent d'id_personne = 1 dans personnes...

    Comment résoudre le problème ?

    J'ai essayé de mettre comme contrainte à Famille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
            REFERENCES Adherents(id_personne)
    mais je reçois une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR: il n'existe aucune contrainte unique correspondant aux clés données pour la
    table « adherents » référencée
    État SQL :42830
    Merci d'avance.
    Cordialement.

  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
    L'héritage de tables en Postgresql, c'est pas top !
    Je préfère modéliser les héritages moi-même.

    On peut avoir la description des tables Personnes et Adherents ?

    Au passage, c'est mieux de nommer les tables (et entités du MCD) au singulier.
    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
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Points : 115
    Points
    115
    Par défaut
    Pour le singulier, c'est mon prof qui demande le pluriel

    Je vous mets le code complet :

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    --
    -- Table Personnes
    --
     
    CREATE TABLE Personnes (
        id_personne integer NOT NULL,
        nom character varying(50),
        prenom character varying(50),
        date_naissance date,
        CONSTRAINT "Personnes_pkey" PRIMARY KEY (id_personne),
        CONSTRAINT "nom_prenom_unique" UNIQUE (nom, prenom)
    );
     
    -- Séquence pour id_personne
     
    CREATE SEQUENCE Personnes_id_personne_seq
        START WITH 1
        INCREMENT BY 1
        NO MAXVALUE
        NO MINVALUE
        CACHE 1;
     
    ALTER SEQUENCE Personnes_id_personne_seq OWNED BY Personnes.id_personne;
     
    ALTER TABLE Personnes ALTER COLUMN id_personne SET DEFAULT nextval('Personnes_id_personne_seq'::regclass);
     
     
     
    --
    -- Table Adherents
    --
     
    CREATE TABLE Adherents (
        num_licence bigint,
        num_secu_sociale bigint,
        statut character varying,
        CONSTRAINT "num_licence_unique" UNIQUE (num_licence),
        CONSTRAINT "num_secu_sociale_unique" UNIQUE (num_secu_sociale)
    )INHERITS (Personnes);
     
     
    --
    -- Table Touristes
    --
     
    CREATE TABLE Touristes (
        adresse text,
        num_tel character varying(20),
        ville character varying(50),
        code_postal character varying(10),
        CONSTRAINT "num_tel_unique" UNIQUE (num_tel)
    )INHERITS (Personnes);
     
     
    --
    -- Table Familles
    --
     
    CREATE TABLE Familles (
        id_famille integer NOT NULL,
        id_chef_famille integer NOT NULL,
        code_postal integer NOT NULL,
        ville character varying(25) NOT NULL,
        pays character varying(25) NOT NULL,
        num_mobile character varying(13) NOT NULL,
        num_fixe character varying(13) NOT NULL,
        email character varying(35) NOT NULL,
        bateau1 integer,
        bateau2 integer,
        CONSTRAINT "Familles_pkey" PRIMARY KEY (id_famille),
        CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
            REFERENCES Adherents(id_personne) ON UPDATE SET NULL ON DELETE SET NULL,
        CONSTRAINT "Famille_to_bateaux_adherents_id_bateau_adherent" FOREIGN KEY (bateau1)
            REFERENCES Bateaux(id_bateau) ON UPDATE SET NULL ON DELETE SET NULL,
        CONSTRAINT "Famille_to_bateaux_adherents_id_bateau_adherent2" FOREIGN KEY (bateau2)
            REFERENCES Bateaux(id_bateau) ON UPDATE SET NULL ON DELETE SET NULL
    );
     
    -- Séquence pour id_famille
     
    CREATE SEQUENCE Familles_id_famille_seq
        START WITH 1
        INCREMENT BY 1
        NO MAXVALUE
        NO MINVALUE
        CACHE 1;
     
    ALTER SEQUENCE Familles_id_famille_seq OWNED BY Familles.id_famille;
     
    ALTER TABLE Familles ALTER COLUMN id_famille SET DEFAULT nextval('Familles_id_famille_seq'::regclass);
    Je trouvais ça assez joli la façon de gérer l'héritage avec Postgre, surtout l'ajout et après la façon de savoir à quelle table une personne fait référence (un membre ou touriste ?)

    Merci d'avance.
    Cordialement.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Citation Envoyé par barbug Voir le message
    Il me met une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR:  une instruction insert ou update sur la table « familles » viole la contrainte de clé
    étrangère « Famille_to_Adherents_id_personne »
    DÉTAIL : La clé (id_chef_famille)=(1) n'est pas présente dans la table « personnes ».
    Alors que quand je parcours mes tables, il y a bien mon adhérent d'id_personne = 1 dans personnes...
    Essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * from ONLY personnes
    et tu devrais voir qu'il n'y a rien dans cette table. Un INSERT dans une table fille n'alimente pas la table mère.

  5. #5
    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 estofilo Voir le message
    Un INSERT dans une table fille n'alimente pas la table mère.
    Voilà ! Je crois que c'est ça qui m'avait fait renoncer aux héritages à la mode Postgresql !
    A quoi bon faire un héritage si on ne peut pas s'en servir ?
    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 !

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Points : 115
    Points
    115
    Par défaut
    Citation Envoyé par estofilo Voir le message
    Essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * from ONLY personnes
    et tu devrais voir qu'il n'y a rien dans cette table. Un INSERT dans une table fille n'alimente pas la table mère.
    Effectivement mais pourquoi n'est-il pas possible de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
            REFERENCES Adherents(id_personne)
    dans ce cas ?

    Sinon c'est exactement comme dit CinePhil. Ça ne sert à rien de faire un héritage si on ne peut pas l'utiliser.

    Merci d'avance.
    Cordialement.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    L'héritage concerne en fait la structure de la table. Le principal cas concret où il est utilisé avec postgresql est le partitionnement.
    Mais globalement, ça n'offre rien qui ne puisse être fait autrement "à la main".

    Ceci étant, une relation de hiérarchie entre tables se modélisant couramment avec une simple clef étrangère vers son parent, l'intérêt d'un héritage de données est discutable. En tout cas ça fait partie des directions qui n'intéressent visiblement pas les développeurs.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Points : 115
    Points
    115
    Par défaut
    Le problème après c'est quand j'ai un id de personne, il faut faire plusieurs requêtes pour retrouver si c'est un adhérent ou autre. On peut pas tout faire en une seule requête, je trouve ça assez lourd. Alors qu'avec cette solution ça avait l'air moins lourd.

Discussions similaires

  1. développer un client VB avec PostGreSQL
    Par lucide dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 22/02/2005, 16h07
  2. Probleme avec postgresql et interface
    Par Missvan dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 27/05/2004, 16h32
  3. Démarrer avec PostgreSQL
    Par Neuromancien2 dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/01/2004, 21h45
  4. Besoin d'aide avec postgresql sous windows NT
    Par Chihuahua dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/07/2003, 08h29

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