Mejores prácticas para almacenar metadatos de registros

10

¿Cuál es la mejor práctica para almacenar metadatos de registros individuales en una base de datos?

Necesito almacenar metadatos comunes, como el tiempo de creación y el tiempo de la última actualización para muchas tablas en mi base de datos. Encontré algunas soluciones diferentes:

  1. Almacene los metadatos directamente en las tablas.

    Pros:

    • Los metadatos están directamente vinculados a los registros.
    • No se requieren combinaciones para recuperar metadatos

    Contras:

    • Se requieren muchas columnas duplicadas (a menos que se use la herencia)
    • Los metadatos y los datos comerciales no están separados
  2. Cree una tabla de metadatos general con y use teclas externas suaves para vincular datos a las tablas y registros correctos.

    Pros:

    • Sin duplicación de columnas.
    • Los metadatos están separados de los datos comerciales.

    Contras:

    • No hay enlaces directos entre metadatos y datos (no se pueden usar FK)
    • Las uniones requieren una condición adicional
  3. Cree tablas de metadatos individuales para cada tabla que requiera metadatos.

    Pros:

    • Los metadatos están directamente vinculados a los registros.
    • Los metadatos están separados de los datos comerciales.

    Contras:

    • Se requieren muchas mesas adicionales
    • Se requieren muchas columnas duplicadas (a menos que se use la herencia)

¿Hay más opciones, ventajas o desventajas que las que mencioné aquí? ¿Y cuál es la mejor práctica para almacenar estos metadatos?

Tiddo
fuente
¿De qué tipo de metadatos estamos hablando? ¿Quizás usar una hstoreo una JSONcolumna podría resolver su problema?
a_horse_with_no_name
@a_horse_with_no_name - En este momento solo necesito tiempo de creación, tiempo de actualización y fuente de creación. Los campos son fijos, así que no necesito clave-valor como el almacenamiento. Solo me preocupa dónde debería almacenar los datos.
Tiddo
1
Entonces no veo ninguna razón para no agregar esas tres columnas a la tabla base.
a_horse_with_no_name

Respuestas:

7

Las columnas de las que está hablando ocupan 20 bytes (si están alineadas sin relleno):

hora de creación, hora de actualización y fuente de creación

marca de tiempo ... 8 bytes
marca de tiempo ... 8 bytes
entero ... 4 bytes

El encabezado de tupla y el puntero de elemento para una fila separada en una tabla separada solo ocuparían 23 + 1 + 4 = 28 bytes más los 20 bytes de datos reales, más 4 bytes de relleno al final. Hace 52 bytes por fila . Leer más aquí:

En cuanto al almacenamiento, no tiene nada que ganar. En cuanto al rendimiento, casi no pierde nada con solo 16-24 bytes más por fila.

Las columnas también pertenecen directamente a la fila, por lo que tiene sentido mantenerlas juntas. Tengo la costumbre de agregar exactamente esas columnas (más una fuente separada para la última actualización) a todas las tablas relevantes.

También es más fácil escribir un TRIGGER ON INSERT OR UPDATEpara mantenerlos actualizados.

Larga historia corta: un fuerte voto por su opción 1 .

A dónde iría para la opción 3 :
si los metadatos se actualizan con frecuencia, mientras que la fila principal no. Entonces podría pagar mantener una tabla 1: 1 separada para hacer ACTUALIZACIONES más baratas y reducir la hinchazón en la tabla principal, o incluso ir a la opción 2.

A dónde iría para la opción 2 :
si el conjunto de columnas de metadatos es altamente repetitivo. Podría tener una columna FK para el conjunto de metadatos en las tablas principales. No ahorra mucho para tres columnas pequeñas como en su ejemplo.

Erwin Brandstetter
fuente
¿Qué hay de resolver esto con la herencia de la tabla? ¿Existen inconvenientes notables en comparación con el uso de columnas de metadatos directamente en la tabla? Sin embargo, si entiendo correctamente, la herencia de la tabla de postgres no es compatible con el estándar SQL, ¿verdad?
devrys
1
@devrys: La herencia tiene algunas limitaciones en Postgres. Más importante: no veo cómo la herencia podría resolver guardar algunas columnas adicionales por fila. Sería una opción si tiene algunas filas con y otras filas sin metadatos. Pero yo no usarlo para eso.
Erwin Brandstetter