Sincronice automáticamente sus tablas OLTP y OLAP en Actian X (Ingres 11)
Alex Hanshaw
9 de febrero de 2018

Una característica clave de la última actualización de nuestra base de datos híbrida Actian X (Ingres 11) es la inclusión del motor analítico x100 y la compatibilidad con tablas x100. La adición de un motor analítico de primera clase a la capacidad OLTP(procesamiento de transacciones en línea) de Actian X permite una nueva clase de aplicaciones que pueden mezclar consultas OLTP y analíticas, dirigiendo cada consulta al motor de ejecución apropiado.
Los ingenieros de Actian acaban de entregar una mejora para Actian X que añade soporte para referencias a tablas X100 en procedimientos de base de datos. Esto permite utilizar procedimientos y reglas de base de datos para lanzar actualizaciones, inserciones y borrados contra tablas X100 cuando se aplican inserciones, actualizaciones y borrados a tablas Ingres. Esto significa que puede sincronizar automáticamente sus tablas OLTP (Ingres) y OLAP (X100), añadiendo nuevos datos transaccionales a sus datos analíticos.
El siguiente ejemplo le guiará a través de la creación de dos tablas (airport y airport_X100) y la creación de los procedimientos y reglas de la base de datos que reflejarán las inserciones, actualizaciones y eliminaciones de la tabla Ingres a la tabla X100. Eche un vistazo y díganos qué le parece.
Esta mejora se suministra mediante un parche que puede descargarse de esd.actian.com aquí.
Cree una tabla OLTP (airport) y un objetivo OLAP (traitement analytique en ligne) (airport_x100):
CREATE TABLE aeropuerto ( ap_id INT, ap_iatacode NCHAR(3) NOT NULL, ap_place NVARCHAR(30), ap_name NVARCHAR(50), ap_ccode NCHAR(2))g commit; g CREATE TABLE airport_x100 ( ap_id INT, ap_iatacode NCHAR(3) NOT NULL, ap_place NVARCHAR(30), ap_name NVARCHAR(50), ap_ccode NCHAR(2)) with structure=x100g commitg
En primer lugar, crearemos un procedimiento que pueda utilizarse para reflejar las inserciones de airport en airport_x100:
CREATE PROCEDURE proc_ins_airport_x100 (apid INT NOT NULL NOT DEFAULT, apiatacode NCHAR(3) NOT NULL NOT DEFAULT, applace NVARCHAR(30) NOT NULL NOT DEFAULT, apname NVARCHAR(50) NOT NULL NOT DEFAULT, apccode NCHAR(2) NOT NULL NOT DEFAULT) AS BEGIN INSERT INTO airport_x100 ( ap_id, ap_iatacode, ap_place, ap_name, ap_ccode) VALUES ( :apid, :apiatacode, :applace, :apname, :apccode); ENDg
Ahora creamos una regla que se disparará automáticamente al insertar en el aeropuerto y disparará el procedimiento proc_ins_airport_x100 con cada parámetro conteniendo los valores de columna que fueron parte de la inserción en el aeropuerto:
CREATE RULE trg_ins_airport_x100 AFTER INSERT INTO airport EXECUTE PROCEDURE proc_ins_airport_x100 (apid = new.ap_id, apiatacode = new.ap_iatacode, applace = new.ap_place, apname = new.ap_name, apccode = new.ap_ccode)g
Insertamos 4 filas en la tabla OLTP aeropuerto:
INSERT INTO airport VALUES (50000, 'AAA', 'Vector', 'Aomori', 'AU')g INSERT INTO airport VALUES (50001, "AA1", "Vector", "Tegel", "AU")g INSERT INTO airport VALUES (50002, "AA2", "Vector", "Tegel", "NL")g INSERT INTO airport VALUES (50003, "AA3", "Vector", "Tegel", "NL")g
Ahora veremos si nuestra tabla OLAP de destino (airport_x100) ha sido actualizada:
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 50000|AAA |Vector |Aomori |AU | | 50001 AAA1 Vector Tegel UA | 50002 AAA2 Vector Tegel NL | 50003 AAA3 Vector Tegel NL +-------------+--------+--------------------+--------------------+--------+ (4 filas)
Así que las inserciones se propagaron automáticamente. Ahora echaremos un vistazo a las actualizaciones. Múltiples reglas disparadas en una sola condición no tienen un orden de ejecución definido. Así que nos aseguramos de que sólo se dispara una regla o de que el orden no afecta al resultado final.
En primer lugar, estamos creando un procedimiento que actualizará la columna ap_id de airport_x100 con el valor del parámetro ap_id si la columna ap_iatacode de airport_x100 coincide con el valor del parámetro apiatacodeold:
CREATE PROCEDURE proc_upd_airport_x100_01 ( apid INT NOT NULL NOT DEFAULT, apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) AS BEGIN UPDATE airport_x100 SET ap_id = :apid WHERE ap_iatacode = :apiatacodeold; ENDg
Ahora creamos la regla que dispara el procedimiento anterior, sólo se dispara si se actualiza la columna ap_id en la tabla airport. Es posible pasar el valor nuevo y/o antiguo de una actualización al procedimiento llamado:
CREATE RULE trg_upd_airport_x100_01 AFTER UPDATE(ap_id) of airport EXECUTE PROCEDURE proc_upd_airport_x100_01 ( apid = nuevo.ap_id, apiatacodeold = antiguo.ap_iatacode)g
Ahora creamos un segundo procedimiento de actualización que, de forma similar, actualizará condicionalmente la columna ap_iatacode de airport_x100 con el valor suministrado. Además de actualizar airport_x100, esta tabla generará mensajes emergentes cuando se ejecute. No estamos limitados a una única sentencia de inserción, borrado o actualización:
CREATE PROCEDURE proc_upd_airport_x100_02 (apiatacode NCHAR(3) NOT NULL NOT DEFAULT, apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) AS DECLARE str VARCHAR(30) not null; BEGIN str = 'apiatacode = ' + :apiatacode; MENSAJE :str; str = 'apiatacodeold = ' + :apiatacodeold; MENSAJE :str; UPDATE airport_x100 SET ap_iatacode = :apiatacode WHERE ap_iatacode = :apiatacodeold; ENDg
Ahora creamos una regla que disparará el procedimiento anterior si se actualiza el ap_iatacode en la tabla airport:
CREATE RULE trg_upd_airport_x100_02 AFTER UPDATE(ap_iatacode) of airport EXECUTE PROCEDURE proc_upd_airport_x100_02 ( apiatacode = new.ap_iatacode, apiatacodeold = old.ap_iatacode)g
Pasamos a crear procedimientos y reglas que aplicarán actualizaciones a otras columnas de airport_x100. Esto no es un requisito. Si es necesario, se pueden actualizar varias columnas en un único procedimiento:
CREATE PROCEDURE proc_upd_airport_x100_03 (applace NVARCHAR(30) NOT NULL NOT DEFAULT, apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) AS BEGIN UPDATE airport_x100 SET ap_place = :applace WHERE ap_iatacode = :apiatacodeold; ENDg CREATE RULE trg_upd_airport_x100_03 AFTER UPDATE(ap_place) of airport EXECUTE PROCEDURE proc_upd_airport_x100_03 ( applace = nuevo.ap_place, apiatacodeold = antiguo.ap_iatacode)g CREATE PROCEDURE proc_upd_airport_x100_04 (apname NVARCHAR(30) NOT NULL NOT DEFAULT, apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) AS BEGIN UPDATE airport_x100 SET ap_name = :apname WHERE ap_iatacode = :apiatacodeold; ENDg CREATE RULE trg_upd_airport_x100_04 AFTER UPDATE(ap_name) of airport EXECUTE PROCEDURE proc_upd_airport_x100_04 ( apname = nuevo.ap_name, apiatacodeold = antiguo.ap_iatacode)g CREATE PROCEDURE proc_upd_airport_x100_05 (apccode NVARCHAR(30) NOT NULL NOT DEFAULT, apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) AS BEGIN UPDATE airport_x100 SET ap_ccode = :apccode WHERE ap_iatacode = :apiatacodeold; ENDg CREATE RULE trg_upd_airport_x100_05 AFTER UPDATE(ap_ccode) of airport EXECUTE PROCEDURE proc_upd_airport_x100_05 ( apccode = nuevo.ap_ccode, apiatacodeold = antiguo.ap_iatacode)g
Ahora realizaremos actualizaciones de nuestros datos transaccionales en la tabla airport para mostrar cómo los procedimientos y reglas anteriores aplican automáticamente los cambios a nuestra tabla analytics airport_x100:
update aeropuerto set ap_id = 99999 where ap_id = 50000g
La selección muestra que trg_upd_airport_x100_01 se activó y ejecutó el procedimiento proc_upd_airport_x100_01. La actualización de una sola columna se ha reflejado en la tabla airport_x100:
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |Vector |Aomori |AU | | 50001|AA1 |Vector |Tegel |AU |Vector |Tegel |AU | 50002AA2 Vector Tegel NL | 50003 AAA3 Vector Tegel NL +-------------+--------+--------------------+--------------------+--------+ (4 filas)
La siguiente actualización disparará el procedimiento proc_upd_airport_x100_02 que también muestra un mensaje cuando se dispara. Aplicaremos una serie de actualizaciones a la tabla airport para mostrar y luego seleccionaremos de la tabla analytics airport_x100 para mostrar cómo las bases de datos y reglas anteriores están aplicando automáticamente cambios a nuestros datos analytics basados en la transacción que afectan a nuestros datos transaccionales:
update aeropuerto set ap_iatacode = 'AA9' where ap_iatacode = 'AA1'g MENSAJE 0: apiatacode = AA9 MENSAJE 0: apiatacodeold = AA1 (1 fila)
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |Vector |Aomori |AU | | 50001|AA9 |Vector |Tegel |AU |Vector |Tegel |AU | 50002 AAA2 Vector Tegel NL | 50003 AAA3 Vector Tegel NL +-------------+--------+--------------------+--------------------+--------+ (4 filas)
update aeropuerto set ap_place = 'VectorUPD' where ap_place = 'Vector'g (4 filas)
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |VectorUPD |Aomori |AU | | 50001 AAA9 VectorUPD Tegel AU | 50002AA2 VectorUPD Tegel NL | 50003 AAA3 VectorUPD Tegel NL +-------------+--------+--------------------+--------------------+--------+ (4 filas)
update airport set ap_name = 'TegelUPD' where ap_name = 'Tegel'g (3 filas)
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |VectorUPD |Aomori |AU | | 50001 AAA9 VectorUPD TegelUPD AU | 50002AA2 VectorUPD TegelUPD NL | 50003 AAA3 VectorUPD TegelUPD NL +-------------+--------+--------------------+--------------------+--------+ (4 filas)
Ahora creamos un procedimiento y una regla para reflejar los borrados. En muchos casos querremos conservar datos históricos en nuestras tablas de análisis, pero puede que necesitemos borrar filas por razones de cumplimiento. El siguiente procedimiento y regla que crearemos borrará los datos de airport_x100 automáticamente cuando se borren filas de la tabla airport:
CREATE PROCEDURE proc_del_airport_x100_01 (apiatacodeold NCHAR(3) NOT NULL NOT DEFAULT) COMO BEGIN DELETE from airport_x100 WHERE ap_iatacode = :apiatacodeold; ENDg CREATE RULE trg_del_airport_x100_01 AFTER DELETE FROM airport EJECUTAR PROCEDIMIENTO proc_del_aeropuerto_x100_01 (apiatacodeold = old.ap_iatacode)g
delete from aeropuerto where ap_iatacode = 'AA9'g (1 fila)
Esta selección muestra que la fila eliminada de airport se ha eliminado automáticamente de airport_x100:
select ap_id, ap_iatacode como iatacode, cast(ap_place como varchar(20)) como - ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |VectorUPD |Aomori |AU | | 50002AA2 VectorUPD TegelUPD NL | 50003 AAA3 VectorUPD TegelUPD NL +-------------+--------+--------------------+--------------------+--------+ (3 filas)
delete from aeropuerto where ap_name = 'TegelUPD'g (2 filas)
La selección muestra que 2 filas borradas de airport se borran automáticamente de airport_x100:
select ap_id, ap_iatacode as iatacode, cast(ap_place as varchar(20)) as ap_place, cast(ap_name as varchar(20)) as ap_name, ap_ccode from airport_x100;g +-------------+--------+--------------------+--------------------+--------+ |ap_id |iatacode|ap_place |ap_name |ap_ccode| +-------------+--------+--------------------+--------------------+--------+ | 99999|AAA |VectorUPD |Aomori |AU | +-------------+--------+--------------------+--------------------+--------+ (1 fila)
Estos ejemplos muestran la duplicación básica de inserciones, actualizaciones y eliminaciones de tablas transaccionales a tablas analíticas para empezar. Se pueden crear procedimientos de base de datos mucho más sofisticados y los cambios aplicados a los datos analíticos no tienen por qué ser un reflejo de los cambios en los datos transaccionales. Es posible que desee desencadenar una inserción en su tabla de análisis después de que se elimine una fila de sus datos transaccionales para establecer una pista de auditoría.
Nos encantaría saber cómo está generando de forma automática y sin problemas sus datos analíticos a partir de sus tablas transaccionales existentes. Por favor, publique una respuesta en nuestros foros de la comunidad para hacernos saber acerca de las cosas interesantes que está haciendo con la base de datos híbrida Actian X.
Suscríbase al blog de Actian
Suscríbase al blog de Actian para recibir información sobre datos directamente en su correo electrónico.
- Manténgase informado: reciba lo último en análisis de datos directamente en su bandeja de entrada.
- No se pierda ni una publicación: recibirá actualizaciones automáticas por correo electrónico que le avisarán cuando se publiquen nuevas publicaciones.
- Todo depende de usted: cambie sus preferencias de entrega para adaptarlas a sus necesidades.