Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
je suis en train de faire une application qui me demande de passer par l'héritage. Pour simplifier, j'ai une table parent "produit" et beaucoup de tables (plus de 100) enfant "produit1 produit2 ..."
Je pourrais le gérer sans héritage avec des clé étrangére et des jointures mais c'est vraiment pas pratique et l'héritage simplifierait les choses.
De plus je ne sais pas si une jointure avec plus de 100 tables est très efficace...
Voici mon problème :
CREATE TABLE produit
(
id numeric NOT NULL,
"name" text,
CONSTRAINT "PK" PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE produit OWNER TO postgres;
CREATE TABLE produit1
(
-- Geerbt from table produit1: id numeric NOT NULL,
-- Geerbt from table produit1: "name" text,
capacite numeric,
CONSTRAINT "PK2" PRIMARY KEY (id)
)
INHERITS (produit)
WITH (
OIDS=FALSE
);
ALTER TABLE produit1 OWNER TO postgres;
CREATE TABLE produiit2
(
-- Geerbt from table produiit2: id numeric NOT NULL,
-- Geerbt from table produiit2: "name" text,
epaisseur numeric,
CONSTRAINT "PK3" PRIMARY KEY (id)
)
INHERITS (produit)
WITH (
OIDS=FALSE
);
ALTER TABLE produiit2 OWNER TO postgres;
INSERT INTO produiit2(
id, "name", epaisseur)
VALUES (2, 'planche', 18);
INSERT INTO produiit2(
id, "name", capacite)
VALUES (1, 'classeur', 100);
Jusque l'à tout va bien.
Apres je veux faire un select :
SELECT *
FROM produit;
j'obtiens :
1;"classeur"
1;"planche"
Ca semble cohérent.
Mais n'est il pas possible d'obtenir aussi les colonnes Capacité et épaisseur en sélectionnant la table produit et sans faire de jointures ?
Que j'obtienne cela :
1;"classeur";NULL;100
1;"planche";18;NULL
Sur le même principe j aimerais faire un select comme ceci sans jointure:
select * from produit where capacite =100
mais bien sur écrit comme ceci il me dit que la colonne n'éxiste pas.
Est ce qu'une solution éxiste ou il faut passer par les jointures obligatoirement ?
Hors ligne
L'héritage ne permet pas de faire ça. Le but est d'avoir des tables génériques, et d'autres tables plus spécifiques héritant de celles-ci. On ne peut donc pas voir les informations spécifiques dans la table générique, puisqu'elles n'ont pas de sens pour ce type générique.
Par contre, pourquoi passer par des jointures ? UNION ALL est fait pour regrouper des ensembles de données:
SELECT id, "name", epaisseur, NULL as capacite
FROM produit1
UNION ALL
SELECT id, "name", NULL, capacite
FROM produit2
Mais dans tous les cas, les enregistrements retournés sont un peu étranges : on mélange des données n'ayant pas vraiment de rapport entre elles, et on est obligé d'envoyer plein de colonnes (si on a 100 tables…) null et chercher ou se trouve la donnée en regardant ou est le champ non nul. Si le type de la donnée supplémentaire est toujours le même, on peut aussi faire ceci, qui me semble déjà plus propre:
SELECT id, "name", 'epaisseur' as type, epaisseur as valeur
FROM produit1
UNION ALL
SELECT id, "name", 'capacite', capacite
FROM produit2
Dernière modification par Marc Cousin (06/10/2009 15:18:55)
Marc.
Hors ligne
Ca risque de ralentir la base si on fait une jointure avec environ 100 tables
Par contre le nombre de champs spécifique n'est pas égale dans toutes les tables, certains en ont 0 d'autre 5 etc ...
Hors ligne
Généralement, quand on utilise l'héritage, c'est pour pouvoir accéder aux champs communs uniquement en utilisant la table principale, et aux champs spécifiques en accédant aux tables spécifiques. Donc pas de UNION ALL, pas de jointure.
Je ne vois pas du tout l'intérêt d'accéder aux champs communs et aux champs spécifiques pour toutes les tables héritées. Vous pouvez nous expliquer l'intérêt ? car pour moi, ça semble plutôt révélateur d'un problème de normalisation.
Guillaume.
Hors ligne
Je souhaite répertorier des offres d'emplois.
Il y a des champs de base : Titre, Salaire, Adresse...
et des champs spécifiques aux entreprises : demandes particulières que je ne peux pas prévoir à l'avance, ca dépendra des entreprises qui seront indexés. (je sais pas si c'est clair)... En gros ce point est imposé par la spécification du projet.
Comme le nombre d'entreprise peut être très élevé je ne pas faire de jointure en cas de recherche sur tous les emplois.
Dernière modification par einboubou (07/10/2009 14:18:03)
Hors ligne
S'il y a recherche sur tous les emplois, je présume que la vue n'affichera que les informations communes. Sinon elle risque d'être très difficilement lisible.
Marc.
Hors ligne
Oui et non car la vue commune pourra faire une différence suivant si l'offre vient de telle ou telle entreprise
Hors ligne
Dans ce cas, si vous voulez mélanger des données de types et de structures différentes dans une seule requête, il vous faudra l'écrire vous même. Mais si vous avez 100 tables dans la requête, cela risque d'être très douloureux. Je suis d'accord avec gleu sur le fait que ça pose des questions sur la modélisation des données. Cela risque d'être un cauchemar d'un point de vue de la maintenance.
Mais pour revenir à la question originale : non, on ne peut pas avoir par le mécanisme d'héritage une vue fusionnant tous les champs de toutes les tables héritées. Donc requête manuelle.
Marc.
Hors ligne
C'est pas un problème pour la requète manuelle, une fois qu'elle est écrite ça va. Le problème c'est plutôt au niveau des perfs, ça va se passer comment la jointure sur 100 tables avec au maximum disont 15 enregistrements par table. Vous avez une idée ?
Hors ligne
Je ne comprends toujours pas le besoin de la jointure. Pour moi, si c'est bien concaténer les enregistrements des tables filles (en choisissant différents champs) il s'agit de faire un union all. Ça coutera forcément un peu si il y a beaucoup de tables, mais toujours largement moins qu'une jointure
Si besoin de jointure il y a, pouvez vous expliquer pourquoi ? (avec un exemple)
Marc.
Hors ligne
heu pardon par jointure j'entendais union all enfin un mécanisme pour rassembler les tables en fait. J'ai pas encore des connaissances très poussé en sql
Hors ligne
Ok, pas de problème. Le union all aura à peu près le coût de la somme des requêtes en union je pense (il n'y a pas de problème de combinatoire complexe comme avec des jointures)
Marc.
Hors ligne
ok si je comprends bien une requête union all sur 100 tables c'est comme si je faisais 100 requêtes à la suite ?
Je sais pas encore si un attribut supplémentaire en csv avec les champs spécifiques est meilleur que 100 tables avec union all en terme de perf.
En terme de simplicité je pense le csv est largement plus facile à gérer.
Qu'en pensez vous ?
Hors ligne
non, en termes de planification (décider quel plan d'exécution il va prendre) et d'exécution pour le moteur postgres, c'est pareil. par contre, ça reste une seule interrogation à la base, donc moins de latence, un seul dialogue client serveur.
Le défaut du csv ou de n'importe quel champ 'foutoir' (tableau, chaine libre…), c'est si vous voulez faire des filtrages sur ces champs. C'est un non respect de la première forme normale, ça peut coûter très cher ultérieurement en termes de développement . Si vous êtes absolument sûr de ne pas avoir besoin de filtrer sur ces champs, celà peut être une solution (mais si vous partez dans cette direction, regardez quand même les types tableau)
Marc.
Hors ligne
Je suis partis sur du csv.
Je ferais pas de filtrage sur du csv si jamais le projet fonctionne bien il sera pas trop tard pour passer à de l'héritage ou pleins de tables si cela en vaut la peine.
Merci pour tout
Hors ligne
Pages : 1