Précédent   Forum des professionnels en informatique > Bases de données > PostgreSQL
PostgreSQL Forum PostgreSQL. Avant de poster -> F.A.Q PostGreSQL Tutoriels PostGreSQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/12/2010, 16h21   #1
Membre régulier
 
Inscription : juin 2008
Messages : 214
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 214
Points : 78
Points : 78
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 :
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 :
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 :
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 :
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 :
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 :
1
2
CONSTRAINT "Famille_to_Adherents_id_personne" FOREIGN KEY (id_chef_famille)
        REFERENCES Adherents(id_personne)
mais je reçois une erreur :

Code :
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.
barbug est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2010, 16h27   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 977
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 10 977
Points : 18 221
Points : 18 221
Envoyer un message via MSN à CinePhil
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2010, 19h30   #3
Membre régulier
 
Inscription : juin 2008
Messages : 214
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 214
Points : 78
Points : 78
Pour le singulier, c'est mon prof qui demande le pluriel

Je vous mets le code complet :

Code :
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.
barbug est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2010, 21h50   #4
Modérateur
 
Inscription : octobre 2008
Messages : 1 504
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 504
Points : 2 033
Points : 2 033
Citation:
Envoyé par barbug Voir le message
Il me met une erreur :

Code :
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 :
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.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2010, 22h03   #5
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 977
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 10 977
Points : 18 221
Points : 18 221
Envoyer un message via MSN à CinePhil
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2010, 22h13   #6
Membre régulier
 
Inscription : juin 2008
Messages : 214
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 214
Points : 78
Points : 78
Citation:
Envoyé par estofilo Voir le message
Essaye
Code :
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 :
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.
barbug est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/12/2010, 18h48   #7
Modérateur
 
Inscription : octobre 2008
Messages : 1 504
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 504
Points : 2 033
Points : 2 033
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.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/12/2010, 21h28   #8
Membre régulier
 
Inscription : juin 2008
Messages : 214
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 214
Points : 78
Points : 78
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.
barbug est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h19.


 
 
 
 
Partenaires

Hébergement Web