update una trigger hacer funciones ejemplos como bitacora auditoria postgresql

una - ¿Cuándo usar tablas heredadas en PostgreSQL?



triggers en postgresql pdf (8)

¿En qué situaciones debe usar tablas heredadas? Traté de usarlos muy brevemente y la herencia no parecía en el mundo OOP.

Pensé que funcionaba así:

users tabla que tienen todos los campos requeridos para todos los niveles de usuario. Las tablas como moderators , admins , bloggers , etc. pero los campos no se verifican desde el padre. Por ejemplo, los users tienen campo de correo electrónico y los bloggers heredados también lo tienen ahora, pero no es exclusivo para users y bloggers al mismo tiempo. es decir. lo mismo que agrego un campo de correo electrónico a ambas tablas.

El único uso que pude pensar es en los campos que generalmente se usan, como row_is_deleted , created_at , modified_at . ¿Es este el único uso para tablas heredadas?


"Herencia de tabla" significa algo diferente a "herencia de clase" y tienen diferentes propósitos.

Postgres tiene que ver con las definiciones de datos. A veces definiciones de datos realmente complejas. OOP (en el sentido común de las cosas de Java) se trata de subordinar los comportamientos a las definiciones de datos en una sola estructura atómica. El propósito y el significado de la palabra "herencia" es significativamente diferente aquí.

En OOP land podría definir (siendo muy flexible aquí la sintaxis y la semántica):

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)

Las tablas para esto podrían verse así:

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);

Pero, ¿dónde están los comportamientos? No caben en ningún lado Este no es el propósito de los "objetos" como se discuten en el mundo de la base de datos, porque las bases de datos se preocupan por los datos, no por el código de procedimiento. Puede escribir funciones en la base de datos para hacer cálculos (a menudo una muy buena idea, pero no es algo que se adapte a este caso) pero las funciones no son lo mismo que los métodos: métodos como los entiende en forma de OOP de los que está hablando aproximadamente son deliberadamente menos flexibles.

Hay una cosa más que destacar acerca de la herencia como dispositivo esquemático: a partir de Postgres 9.2 no hay forma de hacer referencia a una restricción de clave externa en todas las particiones / miembros de la familia de tablas a la vez. Puede escribir cheques para hacer esto o para solucionarlo de otra manera, pero no es una función incorporada (en realidad se trata de problemas con la indexación compleja y nadie ha escrito los bits necesarios para que sea automática). En lugar de utilizar la herencia de tablas para este propósito, a menudo una mejor coincidencia en la base de datos para la herencia de objetos es hacer extensiones esquemáticas a las tablas. Algo como esto:

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(20) 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);

Ahora tenemos una referencia canónica para la instancia del animal que podemos usar de manera confiable como referencia de clave externa, y tenemos una columna "ilk" que hace referencia a una tabla de definiciones de xxx_ilk que apunta a la "siguiente" tabla de datos ampliados ( o indica que no hay ninguno si el tipo es el tipo genérico en sí mismo). Escribir funciones de tablas, vistas, etc. en contra de este tipo de esquema es tan fácil que la mayoría de los marcos ORM hacen exactamente este tipo de cosas en segundo plano cuando recurre a la herencia de clase de estilo OOP para crear familias de tipos de objetos.


Úselo lo menos posible. Y eso generalmente significa nunca, se reduce a una forma de crear estructuras que violan el modelo relacional, por ejemplo, rompiendo el principio de información y creando bolsas en lugar de relaciones.


El uso principal de la herencia es para particionar, pero a veces es útil en otras situaciones. En mi base de datos hay muchas tablas que difieren solo en una clave externa. La "imagen" de mi tabla de "clase abstracta" contiene una "ID" (la clave principal debe estar en cada tabla) y el ráster PostGIS 2.0. Las tablas heredadas como "site_map" o "artifact_drawing" tienen una columna de clave externa ("site_name" columna de texto para "site_map", "artifact_id" columna entera para la tabla "artifact_drawing" etc.) y restricciones de clave primaria y externa; el resto se hereda de la tabla de "imagen". Sospecho que podría tener que agregar una columna de "descripción" a todas las tablas de imágenes en el futuro, así que esto podría ahorrarme mucho trabajo sin hacer problemas reales (bueno, la base de datos podría correr un poco más lento).

EDITAR: otro buen uso: con manejo de dos tablas de usuarios no registrados , otros RDBMS tienen problemas con el manejo de las dos tablas, pero en PostgreSQL es fácil: solo agregue ONLY cuando no esté interesado en datos en la tabla heredada de "usuario no registrado" .


Hay algunas razones principales para usar la herencia de tablas en postgres.

Digamos que tenemos algunas tablas necesarias para las estadísticas, que se crean y completan cada mes:

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

En esta muestra, tenemos 2.000.000 filas en cada tabla. Cada tabla tiene una restricción CHECK para asegurarse de que solo se almacenen los datos para el mes coincidente.

Entonces, ¿qué hace que la herencia sea una característica interesante? ¿Por qué es genial dividir los datos?

  • RENDIMIENTO: Al seleccionar los datos, SELECCIONAMOS * FROM las estadísticas DONDE la fecha ENTRE x e Y, y Postgres solo usa las tablas, donde tiene sentido. P.ej. SELECCIONAR * DESDE las estadísticas DONDE la fecha ENTRE "2010-04-01" Y "2010-04-15" solo escanea la tabla statistics_2010_04, todas las demás tablas no se tocarán, ¡rápido!
  • Tamaño del índice: no tenemos una gran tabla de grasa con un gran índice de grasa en la fecha de la columna. Tenemos tablas pequeñas por mes, con índices pequeños, lecturas más rápidas.
  • Mantenimiento: podemos ejecutar vacío al vacío, reindexar, agrupar en cada mesa mensual sin bloquear todos los demás datos

Para el uso correcto de la herencia de tablas como refuerzo de rendimiento, consulte el manual postgresql. Debe establecer restricciones CHECK en cada tabla para indicarle a la base de datos, en qué clave sus datos se dividen (particionan).

Hago un uso intensivo de la herencia de tablas, especialmente cuando se trata de almacenar datos de registro agrupados por mes. Sugerencia: si almacena datos, que nunca cambiarán (datos de registro), cree o indexe con CREATE INDEX ON () WITH (fillfactor = 100); Esto significa que no se reservará espacio para las actualizaciones en el índice; el índice es más pequeño en el disco.

ACTUALIZACIÓN: el valor predeterminado de fillfactor es 100, de http://www.postgresql.org/docs/9.1/static/sql-createtable.html :

El factor de relleno para una tabla es un porcentaje entre 10 y 100. 100 (embalaje completo) es el valor predeterminado


He escrito un artículo de blog sobre cómo usar la herencia de PostgreSQL en una materia polimorfa, de modo que, por ejemplo, puede escribir una única función de base de datos para actualizar un campo heredado en diferentes tablas secundarias. También muestro cómo la base de datos maneja esta función en segundo plano y muestra una forma de evitar los problemas de rendimiento:

https://swth.ch/2016/12/03/postgresql-inheritance/


La única experiencia que tengo con tablas heredadas es en la partición. Funciona bien, pero no es la parte más sofisticada y fácil de usar de PostgreSQL.

La semana pasada estábamos buscando el mismo problema de OOP, pero teníamos demasiados problemas con Hibernate (no nos gustó nuestra configuración), por lo que no usamos la herencia en PostgreSQL.


La herencia se puede usar en un paradigma de programación orientada a objetos siempre que no sea necesario crear claves externas en la tabla principal. Por ejemplo, si tiene un vehículo de clase abstracta almacenado en una mesa de vehículo y un vagón de mesa que hereda de él, todos los automóviles serán visibles en la mesa del vehículo pero una llave extranjera de una mesa de conductor en la mesa del vehículo no coincidirá con tesis archivos.

La herencia también se puede usar como una herramienta de partitionning . Esto es especialmente útil cuando tiene tablas destinadas a crecer para siempre (tablas de registro, etc.).


Uso la herencia cuando tengo más de 1 en 1 relaciones entre tablas.

Ejemplo: supongamos que desea almacenar ubicaciones de mapas de objetos con atributos x, y, rotación, escala.

Ahora supongamos que tiene varios tipos diferentes de objetos para mostrar en el mapa y cada objeto tiene sus propios parámetros de ubicación del mapa, y los parámetros del mapa nunca se vuelven a utilizar.

En estos casos, la herencia de tablas sería bastante útil para evitar tener que mantener tablas no normalizadas o tener que crear identificadores de ubicación y hacer referencias cruzadas a otras tablas.