107 votes

Quand utiliser les tables héritées dans PostgreSQL?

Dans quelles situations vous devez utiliser hérité de tables? J'ai essayé de les utiliser très brièvement et à l'héritage n'avait pas l'air dans le monde de la programmation orientée objet.

J'ai pensé qu'il a travaillé comme ceci:

L'utilisateur qui a tous les champs sont obligatoires pour tous les niveaux de l'utilisateur. Des tableaux comme MODÉRATEURS, ADMINS, BLOGUEURS, etc mais les champs sont pas vérifiées par le parent. Par exemple les UTILISATEURS a champ e-mail, et a hérité de BLOGUEURS a maintenant, mais elle n'est pas unique pour les UTILISATEURS et les BLOGUEURS en même temps. c'est à dire. même que je l'ai ajouter un champ email dans les deux tables.

La seule utilisation que je pouvais penser est les champs qui sont habituellement utilisées, comme row_is_deleted, created_at, modified_at. Est-ce la seule utilisation pour héritée des tables?

124voto

S38 Points 371

Il y a quelques raisons principales pour l'utilisation de l'héritage de table dans postgres.

Permet de dire, nous avons quelques tables nécessaires pour les statistiques, qui sont créés et remplis chaque mois:

statistics
    - statistics_2010_04 (inherits statistics)
    - statistics_2010_05 (inherits statistics)

Dans cet exemple, nous avons 2.000.000 de lignes dans chaque table. Chaque table a une contrainte de VÉRIFICATION pour vous assurer que seules les données pour le mois correspondant est stocké dans.

Donc, ce qui rend l'héritage d'une fonction cool - pourquoi est-il difficile de fractionner les données?

  • PERFORMANCE: Lors de la sélection des données, nous avons SÉLECTIONNEZ * à PARTIR des statistiques de la date ENTRE x et Y, et Postgres utilise uniquement les tables, où il fait sens. Par exemple. SÉLECTIONNEZ * à PARTIR des statistiques de la date ENTRE '2010-04-01' ET '2010-04-15' analyse uniquement la table statistics_2010_04, toutes les autres tables de ne pas obtenir de touché - rapide!
  • La taille de l'Index: Nous n'avons pas de grosse table avec un gros indice sur la colonne date. Nous avons de petites tables par mois, avec de petits indices, plus rapide lit.
  • Entretien: Nous pouvons exécuter le vide complet, reindex, cluster sur chaque mois de table sans verrouillage de toutes les autres données

Pour l'utilisation correcte de l'héritage de table comme booster la performance, regardez le manuel postgresql. Vous devez définir les contraintes de VÉRIFICATION sur chaque table pour dire à la base de données, sur lequel les clés de vos données est coupée en deux (partitionné).

Je fais une utilisation intensive de l'héritage de table, surtout quand il s'agit de stocker des données de journaux regroupés par mois. Astuce: Si vous stockez des données, qui ne changera jamais (journal de données), de créer ou d'index à CRÉER des INDEX SUR () (taux de remplissage=100), Ce qui signifie plus d'espace pour les mises à jour seront réservés dans l'index l'index est plus petite sur le disque.

45voto

zxq9 Points 384

"L'héritage de Table" signifie quelque chose de différent que "l'héritage de classe" et qu'ils servent à des fins différentes.

Postgres est tout au sujet de la définition des données. Parfois très complexes et les définitions de données. La programmation orientée objet (dans la commune de Java-couleur sens des choses), c'est à propos de la subordination des comportements à des définitions de données dans une seule structure atomique. Le but et le sens du mot "héritage" est significativement différente ici.

En programmation orientée objet, la terre je pourrais définir (très lâche avec la syntaxe et de la sémantique ici):

import life

class Animal(life.Autonomous):
  metabolism = biofunc(alive=True)

  def die(self):
    self.metabolism = False

class Mammal(Animal):
  hair_color = color(foo=bar)

  def gray(self, mate):
    self.hair_color = age_effect('hair', self.age)

class Human(Mammal):
  alcoholic = vice_boolean(baz=balls)

Les tables de ce qui pourrait ressembler à:

CREATE TABLE animal
  (name       varchar(20) PRIMARY KEY,
   metabolism boolean NOT NULL);

CREATE TABLE mammal
  (hair_color  varchar(20) REFERENCES hair_color(code) NOT NULL,
   PRIMARY KEY (name))
  INHERITS (animal);

CREATE TABLE human
  (alcoholic  boolean NOT NULL,
   FOREIGN KEY (hair_color) REFERENCES hair_color(code),
   PRIMARY KEY (name))
  INHERITS (mammal);

Mais où sont les comportements? Ils ne correspondent pas n'importe où. Ce n'est pas le but des "objets", comme ils sont décrits dans la base de données du monde, parce que les bases de données sont des données, pas de code procédural. Vous pourriez écrire des fonctions dans la base de données pour effectuer des calculs pour vous (souvent une très bonne idée, mais pas vraiment quelque chose qui correspond à ce cas), mais les fonctions ne sont pas la même chose que de méthodes-méthodes comme compris dans la forme de la programmation orientée objet vous parlez, sont délibérément moins souple.

Il n'y a plus qu'une chose à souligner à propos de l'héritage comme un schéma de l'appareil: Comme de Postgresql 9.2 il n'y a pas moyen de faire référence à une contrainte de clé étrangère sur toutes les partitions/tableau des membres de la famille à la fois. Vous pouvez écrire des vérifications à faire ceci ou à obtenir autour de lui d'une autre manière, mais ce n'est pas une fonctionnalité intégrée (on en vient à des questions complexes d'indexation, vraiment, et personne n'a rédigé les bits nécessaires pour assurer automatique). Au lieu d'utiliser l'héritage de table pour cet effet, souvent une meilleure correspondance dans la base de données pour l'objet de l'héritage est de faire des extensions de schéma de tables. Quelque chose comme ceci:

CREATE TABLE animal
  (name       varchar(20) PRIMARY KEY,
   ilk        varchar(20) REFERENCES animal_ilk NOT NULL,
   metabolism boolean NOT NULL);

CREATE TABLE mammal
  (animal      varchar(20) REFERENCES animal PRIMARY KEY,
   ilk         varchar(2o) REFERENCES mammal_ilk NOT NULL,
   hair_color  varchar(20) REFERENCES hair_color(code) NOT NULL);


CREATE TABLE human
  (mammal     varchar(20) REFERENCES mammal PRIMARY KEY,
   alcoholic  boolean NOT NULL);

Maintenant, nous avons une représentation canonique de référence pour l'instance de l'animal que l'on peut utiliser fiable comme une référence de clé étrangère, et nous avons un "ilk" colonne qui fait référence à une table de xxx_ilk définitions qui pointe à la "prochaine" table de données étendu (ou indique qu'il n'y est aucune si l'image est de type générique lui-même). L'écriture de fonctions de table, vue, etc. face à ce type de schéma est tellement facile que la plupart des frameworks ORM faire exactement ce genre de chose en arrière-plan lorsque vous avez recours à de la programmation orientée objet-classe de style héritage de créer des familles de types d'objet.

7voto

L'héritage peut être utilisé dans un paradigme de la programmation orientée objet tant que vous n'avez pas besoin de créer les clés étrangères de la table parent. Par exemple, si vous avez une classe abstraite véhicule stocké dans un véhicule de table et une table de voiture qui en hérite, toutes les voitures seront visibles dans le véhicule de la table, mais une clé étrangère d'un pilote de table sur le véhicule, le tableau ne correspond pas les thèses de dossiers.

L'héritage peut également être utilisé comme un partitionnement de l'outil. Ceci est particulièrement utile lorsque vous avez des tables destinées à être de plus en plus pour toujours (tableaux de bord, etc).

3voto

Pavel V. Points 353

L'utilisation principale de l'héritage est pour le partitionnement, mais il est parfois utile dans d'autres situations. Dans ma base de données il y a plusieurs tables ne différant que par une clé étrangère. Ma "classe abstraite" de la table "image" contient un "ID" (clé primaire pour cela, il faut dans chaque tableau) et PostGIS 2.0 raster. Héritée des tableaux tels que "site_map" ou "artifact_drawing" ont une colonne de clé étrangère ("nom_site" colonne de texte pour "site_map", "artifact_id" colonne de type integer pour le "artifact_drawing" table, etc.) et primaire et les contraintes de clé étrangère; le reste est hérité de celui de l ' "image" de la table. Je pense que je pourrais avoir à ajouter une "description" de la colonne de toutes les tables de l'image dans l'avenir, donc cela peut me sauver beaucoup de travail sans faire de réels problèmes (ainsi, la base de données peut s'exécuter peu plus lent).

EDIT: une autre bonne utilisation: avec deux tables de manipulation des utilisateurs non-enregistrés, d'autres Sgbdr ont des problèmes avec la manipulation des deux tables, mais dans PostgreSQL, il est facile - il suffit d'ajouter ONLY lorsque vous n'êtes pas intéressé (e) par les données dans le héritée "utilisateur non enregistré" de la table.

2voto

Frank Heikens Points 29270

La seule expérience que j'ai avec les tables héritées, c'est le partitionnement. Cela fonctionne bien, mais ce n’est pas la partie la plus sophistiquée et la plus facile à utiliser de PostgreSQL.

La semaine dernière, nous examinions le même problème de POO, mais nous avions trop de problèmes avec Hibernate (nous n'aimions pas notre configuration), nous n'avons donc pas utilisé l'héritage dans PostgreSQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X