Cela semble être un scénario assez commun: plusieurs types qui composent tous le même type d'enfant.
Cela pourrait généralement ressembler à:
-- 'name' is unique per parent record
CREATE TABLE sometype (
sometype_id serial PRIMARY KEY,
name text
);
CREATE TABLE foo (foo_id serial PK);
CREATE TABLE bar (bar_id serial PK);
CREATE TABLE foo_sometype (
foo_id int4,
sometype_id int4
);
CREATE TABLE bar_sometype (
bar_id int4,
sometype_id int4
);
Ce qui va bien, mais encombrant d'interroger. Je pense que cela pourrait être plus propre:
-- 'name' is unique per parent record
CREATE TABLE sometype (
name text
);
CREATE TABLE foo_sometype (
foo_id int4
) INHERITS(sometype);
CREATE TABLE bar_sometype (
bar_id int4,
) INHERITS(sometype);
Ce que j'aime à propos de ceci:
USING
)Semble comme une utilisation atypique de l'héritage, cependant.
Toute raison non de faire cela?
[.____] sur les "déficiences" de l'héritage
Notez que les mises en garde standard du héritage PG ne sont pertinentes que lorsque l'héritage de la table est utilisée pour modéliser directement le héritage de classe, ce qui n'est pas ce que je fais ici. En fait, pour que cela fonctionne, je a besoin héritage pour se comporter comme ça.
Je souhaite presque qu'ils l'appelaient autre chose que "héritage", car le comportement est assez logique et que les "lacunes" ne sont pertinentes que pour une seule case.
[.____] avantages sur la structure de table dupliquée manuellement
Comme Evan souligne, je pouvais simplement créer manuellement "foo_someType" et "bar_someType" qui ressemblent exactement à ce que je décris, mais je pense qu'il y a quelques avantages significatifs à la structure héritée:
Ainsi, comme exemple de manière artificielle, FOO et Bar pourraient avoir un trait de hassometypeliste, qui résoudra toutes les opérations "Atorstales" et sait que les deux tables peuvent être mappées sur la classe de Sentaype.
Représentant la relation FOO/BAR, qu'il soit modélisé comme un trait ou comme héritage, est l'objectif ultime ici.
Incidemment, à l'utilisateur naïf/Query-Writer - qui ne devrait pas faire de changements de schéma - ces deux manières auront la même chose.
L'héritage est l'une de ces caractéristiques que je ne toucherais pas. Afaik, il est utilisé à l'intérieur de la réplication et partitionnement à une certaine capacité. Je ne sais pas si c'était même conçu avec l'intention d'être utilisé par l'utilisateur final.
Les documents couvrent certains des inconvénients de la section de mise en garde (ci-dessous est important).
Ces lacunes ont été mentionnées pour la première fois dans les documents à 7,3 publiés en 1996 bien qu'ils existaient depuis la mise en œuvre de l'héritage.
Cette déficience sera probablement corrigée dans une nouvelle version future.
Et le seul changement consistait à rendre les déficiences plus explicites et verbeuses dans les documents à 8,0 publiés en 2010.
Ces lacunes seront probablement fixées dans une nouvelle version future, mais dans l'intervalle de soins considérables sont nécessaires pour décider si l'héritage est utile pour votre problème.
Bonne chance en attente de cela une nouvelle version future . Et certaines des choses que vous parlez de ne sont tout simplement pas uniques à la composition,
Comment est-ce différent de la fabrication de sometype
une liste d'attributs et de se connecter directement à celui-ci?
CREATE TABLE sometype (sometype_name text PRIMARY KEY);
CREATE TABLE foo (foo_id serial PRIMARY KEY);
CREATE TABLE foo_sometype (
foo_id int REFERENCES foo,
sometype_name text REFERENCES sometype,
PRIMARY KEY ( foo_id, sometype_name )
);
Maintenant, vous n'avez même pas à rejoindre foo_sometype
à sometype
pour obtenir sometype.sometype_name
.
Tous ces problèmes de côté, cela devient encore pire avec le prochain PostgreSQL 10 version de la partition de table
L'héritage multiple n'est pas autorisé, et la partition et l'héritage ne peuvent pas être mélangés
Vous voulez donc héritage? Forgo partitionnement, qui a en réalité des avantages en planificateur réel.
Hélas, ALTER TABLE
a aussi quelques inconvénients énumérés dans ses notes également,
Si une table présente des tables de descendance, il n'est pas autorisé à ajouter, à renommer ou à modifier le type de colonne ou à renommer une contrainte héritée dans la table des parents sans faire de même pour les descendants. C'est-à-dire que Alter Tableau uniquement sera rejeté. Cela garantit que les descendants ont toujours des colonnes correspondant au parent. [...] Une opération de colonne de chute récursive supprimera une colonne de table descendante uniquement si le descendant n'hérite pas de cette colonne d'autres parents et n'a jamais eu de définition indépendante de la colonne. Une colonne de chute non cumulative (c'est-à-dire une colonne de dépose (c'est-à-dire une table d'altération), mais la marque de manière indépendante plutôt que héritée. [...] la gâchette, le cluster, le propriétaire et les actions de l'espace de table ne se recueillent jamais à des tables descendantes; C'est-à-dire qu'ils agissent toujours comme si seulement ont été spécifiés. L'ajout d'une contrainte ne recouvre que pour les contraintes de vérification qui ne sont pas marquées sans hériter.
Je ne pense pas que beaucoup de gens utilisent l'héritage. Je ne l'ai jamais vu à l'état sauvage. L'héritage dans la DB ajoute à la courbe d'apprentissage et certaines caractéristiques sont tout simplement mieux laissées seules. Vous n'avez pas à trouver une demande pour eux.
Vous trouverez peut-être ce message sur la pile débordement utile, "quand utiliser des tables héritées dans PostgreSQL?".
Les lacunes mentionnées ne sont pas une raison pour ne pas utiliser l'héritage! Héritage fonctionne ici similaire à la classe-héritage avec des objets indépendants. Vous pouvez avoir une classe/table 'fruits' et une classe/table 'pommes' et des "oranges". Étant donné que les pommes et les oranges héritent de leurs méta définitions de fruits, vous pouvez les récupérer via des fruits. Cependant, ce sont des classes indépendantes, avec une énumération indépendante et que vous pouvez vous attendre d'autre ....
Si vous avez vraiment besoin de prévenir les collisions: définissez une gâchette ou une clé chèque/étrangère sur la table principale (sans in).
Mais s'il vous plaît, juste parce que vous êtes insatisfait de la façon dont les œuvres d'héritage dans PostgreSQL - ne découragent pas les gens de l'utiliser! Les sous-classes ou tables indépendantes sont merveilleuses! Et si vous avez besoin d'une dépendance - impliquez-la comme vous en avez besoin. Il existe de nombreux bons tutoriels, y compris la documentation officielle. Voici un autre exemple: Héritage - une raison de plus d'aimer PostgreSQL .
J'utilise également l'héritage dans l'un de mes projets, malgré les collisions de clés primaires possibles (ma table des parents n'a pas de clés principales définies et que mon modèle ne l'exige pas).
Il existe également des moyens d'utiliser l'héritage pour améliorer les performances, non seulement l'ORM.
Difficile n'est pas la même chose que mal.
De nombreuses raisons d'éviter, et tous bouillir pour violer les principes du modèle relationnel. Plus évidemment, les tables enfants sont des sacs, non des relations et le manque de clés étrangères violent le principe d'information, ce qui nécessite que toutes les informations soient sous forme de valeurs d'attribut dans les tuples.
Les plus grandes conséquences protégrées sont la perte d'intégrité de l'identité dans les tables d'enfants (des doublons ont un moyen d'être inséré lorsque vous vous attendez le moins) et la perte de transparence dans le modèle: vous regrettez gravement lorsque vous devez expliquer cela au prochain utilisateur de la Modèle, et non, vous ne pouvez jamais être sûr que vous serez l'utilisateur unique de la vie.
En ce qui concerne la construction relationnelle (avec des clés étrangères) étant encombrant à interroger, ce n'est pas le cas. Premièrement, on peut toujours créer des vues (relations dérivées); Et deuxièmement, il est préférable que l'utilisateur comprenne ce qu'il interroge de toute façon, que des comportements automagiques.