Hay algunas razones importantes 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 los datos del mes coincidente se almacenen en ella.
Entonces, ¿qué hace que la herencia sea una característica interesante? ¿Por qué es genial dividir los datos?
- RENDIMIENTO: Al seleccionar los datos, SELECCIONAMOS * DE las estadísticas DONDE fecha ENTRE x e Y, y Postgres solo usa las tablas, donde tiene sentido. P.ej. SELECCIONE * DE 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 tabla grande con un índice grande 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 completo, reindexar, agrupar en cada tabla de mes sin bloquear todos los demás datos
Para el uso correcto de la herencia de tablas como refuerzo del rendimiento, consulte el manual de postgresql. Debe establecer restricciones CHECK en cada tabla para indicarle a la base de datos en qué clave se dividen (particionan) sus datos.
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 actualizaciones en el índice; el índice es más pequeño en el disco.
ACTUALIZACIÓN: el factor de relleno predeterminado es 100, de http://www.postgresql.org/docs/9.1/static/sql-createtable.html :
El factor de relleno de una tabla es un porcentaje entre 10 y 100. 100 (embalaje completo) es el valor predeterminado
"Herencia de tabla" significa algo diferente a "herencia de clase" y sirven para diferentes propósitos.
Postgres se trata de definiciones de datos. A veces, definiciones de datos realmente complejas. OOP (en el sentido común de las cosas del color de Java) se trata de subordinar comportamientos a 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 con la sintaxis y la semántica aquí):
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 ninguna parte. Este no es el propósito de los "objetos" como se discuten en el mundo de las bases de datos, porque las bases de datos están relacionadas con datos, no con códigos de procedimiento. Puede escribir funciones en la base de datos para hacer cálculos por usted (a menudo es una muy buena idea, pero no es realmente algo que se ajuste a este caso), pero las funciones no son lo mismo que los métodos: métodos tal como se entienden en la forma de POO que está hablando sobre son deliberadamente menos flexibles.
Hay una cosa más que señalar sobre 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 evitarlo de otra manera, pero no es una característica incorporada (se reduce a problemas con la indexación compleja, en realidad, y nadie ha escrito los bits necesarios para que eso sea automático). En lugar de usar 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 "calaña" que hace referencia a una tabla de definiciones xxx_ilk que apunta a la tabla "siguiente" de datos extendidos ( o indica que no hay ninguno si el tipo es el tipo genérico en sí). Escribir funciones de tabla, vistas, etc. contra este tipo de esquema es tan fácil que la mayoría de los marcos de ORM hacen exactamente este tipo de cosas en segundo plano cuando se recurre a la herencia de clases de estilo OOP para crear familias de tipos de objetos.
fuente
mammal JOIN human
, solo porque escribir una combinación cada vez es molesto. Pero no evite las uniones . Las uniones son lo que pone la R en RDBMS. Si no le gustan las uniones, debe usar un tipo de base de datos diferente.La herencia se puede usar en un paradigma de programación orientada a objetos siempre que no necesite crear claves externas en la tabla principal. Por ejemplo, si tiene un vehículo de clase abstracta almacenado en una tabla de vehículos y una tabla de automóvil que hereda de él, todos los automóviles serán visibles en la tabla de vehículos, pero una clave externa de una tabla de conductores en la tabla de vehículos no coincidirá con las tesis. registros.
La herencia también se puede utilizar como herramienta de partición . Esto es especialmente útil cuando tiene tablas destinadas a crecer para siempre (tablas de registro, etc.).
fuente
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. Mi "imagen" de tabla de "clase abstracta" contiene una "ID" (la clave principal debe estar en cada tabla) y un ráster PostGIS 2.0. Las tablas heredadas como "site_map" o "artifact_drawing" tienen una columna de clave externa (columna de texto "site_name" para "site_map", columna de entero "artifact_id" para la tabla "artifact_drawing", etc.) y restricciones de clave primaria y externa; el resto se hereda de la tabla "imagen". Sospecho que podría tener que agregar una columna de "descripción" a todas las tablas de imágenes en el futuro, por lo que esto podría ahorrarme bastante trabajo sin generar problemas reales (bueno,
EDITAR: otro buen uso: con el 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 los datos en la tabla heredada de "usuarios no registrados".fuente
La única experiencia que tengo con las tablas heredadas es la partición. Funciona bien, pero no es la parte más sofisticada y fácil de usar de PostgreSQL.
La semana pasada buscábamos el mismo problema de programación orientada a objetos, pero teníamos demasiados problemas con Hibernate (no nos gustó nuestra configuración), por lo que no usamos la herencia en PostgreSQL.
fuente
Utilizo la herencia cuando tengo más de 1 en 1 relaciones entre tablas.
Ejemplo: suponga que desea almacenar ubicaciones de mapas de objetos con atributos x, y, rotación, escala.
Ahora suponga 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 reutilizan.
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 con otras tablas.
fuente
Ú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.
En su lugar, utilice la partición de tablas combinada con el modelado relacional adecuado, incluidas otras formas normales.
fuente