Una forma diferente de ver esto es dimensionar el tiempo de los datos.
Asumiendo que su mesa se ve así:
create table my_table (
my_table_id number not null primary key,
attr1 varchar2(10) not null,
attr2 number null,
constraint my_table_ak unique (attr1, att2));
Entonces, si la ha cambiado, así:
create table my_table (
my_table_id number not null,
attr1 varchar2(10) not null,
attr2 number null,
effective_date date not null,
is_deleted number(1,0) not null default 0,
constraint my_table_ak unique (attr1, att2, effective_date)
constraint my_table_pk primary key (my_table_id, effective_date));
Usted sería capaz de tener una historia completa de correr mi_tabla, en línea y disponible . Tendría que cambiar el paradigma de los programas (o usar activadores de base de datos) para interceptar la actividad ACTUALIZAR en la actividad INSERTAR y para cambiar la actividad ELIMINAR en ACTUALIZAR el booleano IS_DELETED.
Unreason:
Tiene razón en que esta solución similar para grabar basada en la auditoría; Lo leí inicialmente como una concatenación de campos en una cadena, que también he visto. Mis disculpas.
Las principales diferencias que veo entre el dimensionamiento temporal de la tabla y el uso de un centro de auditoría basado en registros en torno a la mantenibilidad sin sacrificar el rendimiento ni la escalabilidad.
Mantenibilidad: Hay que recordar cambiar la tabla de sombras si se realiza un cambio estructural en la tabla primaria. Del mismo modo, es necesario recordar realizar cambios en los desencadenantes que realizan el seguimiento de cambios, ya que dicha lógica no puede vivir en la aplicación. Si uno utiliza una vista para simplificar el acceso a las tablas, también debe actualizarla y cambiar el activador en lugar de activar interceptar DML.
En una tabla de dimensiones de tiempo, realiza el cambio estructural que necesita, y listo. Como alguien que ha sido FNG en un proyecto heredado, se aprecia esa claridad, especialmente si tiene que hacer muchas refacciones.
Rendimiento y escalabilidad: Si se divide una tabla de tiempo en la columna de fecha de vigencia/caducidad, los registros activos están en una "tabla" y los registros inactivos están en otra. ¿Exactamente cómo es eso menos escalable que su solución? La "eliminación" y el registro activo implican el movimiento de la fila en Oracle, que es una eliminación e inserción debajo de las cubiertas, exactamente lo que la solución basada en registros requeriría.
La otra cara del rendimiento es que si la aplicación está buscando un registro a partir de una fecha determinada, la eliminación de partición permite que la base de datos busque solo la tabla/índice donde podría estar el registro; una solución basada en vistas para buscar registros activos e inactivos requeriría UNION-ALL, y no usar dicha vista requiere poner UNION-ALL en todas partes, o usar algún tipo de lógica "look-here, then look-there" en la aplicación, a la que digo: blech.
En resumen, es una opción de diseño; No estoy seguro de que tenga razón o que ninguno esté equivocado.
esto parece completo. Me pregunto qué rendimiento sería para cada enfoque. Entonces, en base a registros, habrá una tabla espejo (en términos de campos) con un campo de versión? – saint
@saint, el rendimiento es un compuesto, depende de los patrones de uso. El archivo de registro será el más rápido de anotar (especialmente si es una partición separada o un nodo separado). Y seguro estarás escribiendo mucho. Ahora, ¿qué tan importante es leer? Si va a leer una vez en una semana, entonces es algo diferente comparado con la inspección de la correlación de la línea de tiempo entre varios campos o haciendo alguna otra extracción de datos (como un ejemplo extremo). – Unreason
@saint, sí, en base a registros extiende las tablas con el campo de control de versiones (y posiblemente otros metadatos interesantes como el usuario). – Unreason