2010-11-23 25 views
8

Tengo una tabla decir:Las revisiones de manipulación dentro de Oracle

CREATE TABLE "DataNode" (
    "ID" NUMBER(7,0), 
    "TYPE" NUMBER(7,0), 
    "NAME" VARCHAR2(100), 
    "STATUS" NUMBER(7,0), 
    "REVISION" NUMBER(4,0), 
    "MODIFIEDAT" DATE 
); 

CREATE TABLE "DataNode_Revisions" (
    "ID" NUMBER(7,0), 
    "NODEID" NUMBER(7,0), 
    "TYPE" NUMBER(7,0), 
    "NAME" VARCHAR2(100), 
    "STATUS" NUMBER(7,0), 
    "REVISION" NUMBER(4,0), 
    "MODIFIEDAT" DATE 
) COMPRESS; 

Así que tienen estas dos tablas. Hago todas mis lecturas de "DataNode" y cuando ocurre un cambio escribo la entrada actual en "DataNode_Revisions" y luego modifico mi registro "DataNode" existente. ¿Tiene sentido?

¿Es esta la mejor manera de hacerlo? Ya puedo decir que voy a tener problemas cuando cambie el esquema. No veo una alternativa mejor, pero si hay una, házmelo saber. Supongo que mantener todo esto en una tabla resultaría en pérdidas masivas de rendimiento ¿no? Quiero decir que estaría cuadruplicando más el número de registros y ya hay bastantes. Creo que Drupal almacena revisiones de nodos como esta, y tengo curiosidad de cómo no sufren problemas de rendimiento.

"DataNode" es constantemente leído por muchos usuarios. Sin embargo, muy pocas escrituras ocurren alguna vez. "DataNode_Revisions" solo se lee de vez en cuando. Solo me preocupa mantener tantas mesas. "DataNode" es una de ~ 25 tablas muy similares a esta.

Respuesta

6

Si hay implicaciones de rendimiento al almacenar las filas antiguas en la tabla DataNode depende de cómo se accede a las filas de DataNode.Si las lecturas son todas búsquedas de una sola fila para la fila actual, el número de filas en la tabla es relativamente inmaterial. No va a tomar más trabajo encontrar la fila actual para una ID particular de la que obtendría la fila para ese ID de la tabla DataNode actual (supongo que ese ID es la clave para la tabla). Por otro lado, si tiene varias consultas que realizan escaneos de tablas de la tabla DataNode, cuadruplicar el número de filas aumentará el tiempo requerido para ejecutar esas consultas.

Si desea ir por el camino de poner las filas históricas en la tabla DataNode, probablemente desee agregar una columna EXPIRATION_DATE que sea NULL para la fila actual y se rellene para las filas caducadas. A continuación, puede crear un índice basado en las funciones basadas en el EXPIRATION_DATE que tener datos para sólo las filas actuales, es decir,

CREATE INDEX idx_current_ids 
    ON DataNode((CASE WHEN expiration_date IS NULL THEN id ELSE null END)); 

que se utiliza en una consulta como

SELECT * 
    FROM DataNode 
WHERE (CASE WHEN expiration_date IS NULL THEN id ELSE null END) = <<some id>> 

Obviamente, usted' Probablemente desee crear una vista que tenga esta condición en lugar de reescribirla cada vez que necesite la fila actual, es decir,

CREATE VIEW CurrentDataNode 
AS 
SELECT (CASE WHEN expiration_date IS NULL THEN id ELSE null END) id, 
     type, 
     name, 
     status 
    FROM DataNode; 

SELECT * 
    FROM CurrentDataNode 
WHERE id = <<some value>> 
+0

+1: ¡La idea del índice basado en función es excelente! –

4

Normalmente uso desencadenantes para escribir en la tabla 'Revisiones'. Sí, los cambios de esquema te obligan a actualizar la tabla espejo y la función desencadenar/archivar.

Creo que lamentará mantener toda su historia, así como la revisión actual en una sola tabla, así que creo que tiene la idea correcta.

Si quiere tratar de encontrar una solución genérica que no requiera una tabla espejo para cada una de sus tablas transaccionales, puede considerar tener una sola tabla de revisiones donde convierta registros a XML y almacenarlos en un clob ... no es muy útil si tienes que acceder a él a menudo o rápidamente, pero es bueno si realmente quieres archivar todo.

2

Tiene algunas opciones. ¿Cuál es el requisito comercial que lo obliga a realizar un seguimiento de los cambios en los datos?

  • si sólo se necesita para mantener los cambios por algún tiempo "corto" de tiempo, usted podría leer los datos de DESHACER utilizando consulta de flashback .. seleccionar * de mesa como de marca de tiempo (bla);

  • Si necesita conservar esta información a largo plazo, consulte la función t llamada Oracle Total Recall. Hace lo mismo que Flashback Query, pero conserva los cambios indefinidamente.

  • si necesita algo más simple, no tiene la aplicación inserte la versión "vieja" de las filas. Use un disparador que rellene los datos.

  • si el sistema está muy ocupado, se puede desacoplar las dos tablas por tener una mesa de intermediario que se utiliza como una "cola"

2

Se va a depender de la aplicación. Si tiene 11g, es posible que desee consultar el nuevo archivo de datos de Flashback. Estoy empezando a verlo para mantener el historial de todos nuestros datos financieros y otros datos críticos.

Cuestiones relacionadas