Héritage de tables dans postgresql
Gérer l'héritage d'objets dans une base de données est un problème que beaucoup de développeurs connaissent. Imaginons que nous sommes en train d'écrire une application de gestion de bibliothèque (le cas d'école). Vous avez une table qui va regrouper les ouvrages c'est à dire l'ensemble des publications que possède votre bibliothèque. Mais cette table généraliste va forcemment ne pas avoir des attributs spécifiques à certains types d'ouvrages commes des livres de poche, des bédés ou des magazines.
Illustrons ce cas concret avec 2 bases de données : une base de données «classique» appelons la «myXsql» et une base postgresql.
Avec la base classique, nous allons avoir un schéma avec une jointure :

Cette solution est compliquée car nous gérons une clé primaire par table, une clé étrangère dans chaque table fille pour faire le lien avec l'ouvrage correspondant.
Au niveau du modèle objet, cela se traduit tant bien que mal. Nous avons en effet plusieurs façons de gérer cela. La façon SQL de penser donne que l'objet ouvrage est un attribut de mon objet magazine ou livre de poche et que l'on regroupe tout dans une jointure.
La façon objet est de faire étendre la classe ouvrage aux classes magazines et livre_poche pour que chaque couche gère sa table grace à l'appel à la méthode parent. Du coup, on double le nombre de requêtes (une pour chaque table).
Postgresql propose la fonctionnalité de l'héritage de table qui va gérer tout cela pour nous. Notre schéma de base de données devient très simple.
Pour bien illuster cet exemple, voici la ligne de création de la table magazine :
Je sens votre curiosimètre en plein effervesence et pour cause, nous n'avons pas eu à déclarer de clé primaire sur les tables magazine et livre_poche car nous héritons de celle d'ouvrage ! Un exemple valant mieux que tartines d'explications, lançons nous :
Ce premier exemple se passe de commentaire. Ajoutons maintenant un magazine :
Illustrons ce cas concret avec 2 bases de données : une base de données «classique» appelons la «myXsql» et une base postgresql.
Avec la base classique, nous allons avoir un schéma avec une jointure :

Cette solution est compliquée car nous gérons une clé primaire par table, une clé étrangère dans chaque table fille pour faire le lien avec l'ouvrage correspondant.
Au niveau du modèle objet, cela se traduit tant bien que mal. Nous avons en effet plusieurs façons de gérer cela. La façon SQL de penser donne que l'objet ouvrage est un attribut de mon objet magazine ou livre de poche et que l'on regroupe tout dans une jointure.
La façon objet est de faire étendre la classe ouvrage aux classes magazines et livre_poche pour que chaque couche gère sa table grace à l'appel à la méthode parent. Du coup, on double le nombre de requêtes (une pour chaque table).
Postgresql propose la fonctionnalité de l'héritage de table qui va gérer tout cela pour nous. Notre schéma de base de données devient très simple.
Pour bien illuster cet exemple, voici la ligne de création de la table magazine :
CREATE TABLE ouvrage (id SERIAL, created_at TIMESTAMP NOT NULL);Regardons le résultat :
CREATE TABLE magazine (titre VARCHAR(255) NOT NULL, published_at TIMESTAMP NOT NULL, number INTEGER) INHERITS (ouvrage);
CREATE TABLE livre_poche (isbn VARCHAR(255) NOT NULL, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL) INHERITS (ouvrage);
test=$ d ouvrageet nos tables étendues :
Table "public.ouvrage"
Column | Type | Modifiers
----------------+-------------------------+------------------------------------------------------
id | integer | not null default nextval('ouvrage_id_seq'::regclass)
created_at | timestamp | not null
test=$ d magazine
Table "public.magazine"
Column | Type | Modifiers
----------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('ouvrage_id_seq'::regclass)
created_at | timestamp | not null
titre | character varying(255) | not null
published_at | timestamp | not null
number | integer |
Inherits: ouvrage
test=$ d livre_poche
Table "public.livre_poche"
Column | Type | Modifiers
--------------+-------------------------+------------------------------------------------------
id | integer | not null default nextval('ouvrage_id_seq'::regclass)
created_at | timestamp | not null
isbn | character varying(255) | not null
title | character varying(255) | not null
author | character varying(255) | not null
Inherits: ouvrage
Je sens votre curiosimètre en plein effervesence et pour cause, nous n'avons pas eu à déclarer de clé primaire sur les tables magazine et livre_poche car nous héritons de celle d'ouvrage ! Un exemple valant mieux que tartines d'explications, lançons nous :
test=$ ALTER TABLE ouvrage ALTER COLUMN created_at SET DEFAULT now();
ALTER TABLE
test$ d magazine
Table "public.magazine"
Column | Type | Modifiers
----------------+-----------------------------+------------------------------------------------------
id | integer | not null default nextval('ouvrage_id_seq'::regclass)
created_at | timestamp | not null default now()
titre | character varying(255) | not null
published_at | timestamp | not null
number | integer |
Inherits: ouvrage
Ce premier exemple se passe de commentaire. Ajoutons maintenant un magazine :
test=$ INSERT INTO magazine (titre, published_at, number) VALUES ('art et decoration', TIMESTAMP '2008/01/01', 144);
INSERT 0 1
test=$ SELECT * FROM magazine ;
id | created_at | titre | published_at | number
----+----------------------------------------+----------------------+------------------------------+--------
1 | 2008-03-09 12:12:07.787696 | art et decoration | 2008-01-01 00:00:00 | 144
(1 row)
test=$ SELECT * FROM ouvrage;
id | created_at
----+------------------------------
1 | 2008-03-09 12:12:07.787696
(1 row)
test=$ SELECT * FROM livre_poche ;
id | created_at | isbn | title | author
----+--------------+-------+-----+--------
(0 rows)
Publicité