Muy buenas, soy Miguel y aquí les traigo este artículo.
Solución común: activadores de PostgreSQL
Una de las soluciones más comunes para escribir en particiones es escribir en la tabla maestra y asociar un disparador a esa operación de escritura. El disparador diría: «Siempre que se inserte una fila, verifique su ID y luego insértela en la partición correcta». Dependiendo de cuán compleja sea la definición del disparador, podemos evitar actualizarla por un tiempo, pero en última instancia, es probable que tenga que modificar el disparador para que coincida con más particiones o volver a conectar el disparador a otra partición.
// Example from PostgreSQL documentationCREATE OR REPLACE FUNCTION measurement_insert_trigger() RETURNS TRIGGER AS $$ BEGIN INSERT INTO measurement_y2008m01 VALUES (NEW.*); RETURN NULL; END; $$ LANGUAGE plpgsql;CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();
Esta es una solución bastante simple ya que realmente no nos importa todo eso en nuestro código, solo tenemos que escribir en la tabla maestra.
No voy a escribir sobre esta solución porque ya está ampliamente explicada en Internet.
Solución anti-patrón: flujos de NodeJS
Veamos un poco más las transmisiones de NodeJS.
Antes de continuar, repetiré que este enfoque puede considerarse anti-patrón ya que vincula el código y el estado de la base de datos. De acuerdo con el patrón, a su código no le debería importar si su tabla está particionada o no.
La forma habitual de usar transmisiones en NodeJS es leer una transmisión desde una fuente, transformar esa transmisión y almacenar el resultado en una tabla o un archivo. Los flujos son muy útiles para procesos ETL de alto volumen, ya que nos permiten transformar todo el conjunto de datos sin tener que cargarlo por completo en el disco.
Ahora, si nuestro destino es una tabla particionada, es posible que desee distribuir los datos a su partición correspondiente. Esto no es algo que podamos hacer con un solo flujo porque el flujo solo escribiría en un único destino.
Lo que queremos es leer desde una sola fuente y luego distribuir a múltiples destinos (particiones) dependiendo del contenido leído. De hecho, podemos lograr esto generando 1 flujo para cada partición que tenemos, leyendo el contenido del flujo de origen y redistribuyendo los datos al flujo correcto que entregará los datos a la partición correcta.
La estrategia completa en pseudocódigo
Convención de nomenclatura de tablas:
Master table: table_name Ranged partitions: table_name_part_startingID_endingID Default partition: table_name_part_default
Para extraer la lista de particiones, podemos extraer los nombres de las tablas de la tabla PG o mantener una tabla de manifiesto en la que almacenamos el rango de cada partición.
Consideremos que sacamos la lista de particiones disponibles. Necesitamos crear una secuencia para cada partición. El objetivo del flujo es escribir las filas que recibe en la partición correspondiente.
A tener en cuenta:
Cada secuencia de ramificación que creamos está vinculada a una partición, la que tiene sus límites de rango que coinciden con el mínimo y el máximo del objeto contenedor de secuencia.
Pasar por es un tipo especial de flujo que simplemente transfiere datos y no hace nada. Es ideal declarar nuestros flujos de destino, ya que definiremos cómo almacenan los datos en la partición correcta más adelante.
Usamos pg-copy-streams para transmitir a la partición de Postgres con la declaración COPY (más rápido que INSERT en volúmenes altos). En este caso, los datos se transforman a CSV antes de copiarlos y la COPIA incluye una opción FORMAT CSV.
Con esto, ahora podemos extraer filas del flujo de origen, leerlas una por una y distribuir cada una en una secuencia diferente. Luego, cada flujo almacena los datos en una partición adjunta, lo que nos permite enviar nuestros datos de origen a las particiones correctas, en paralelo.
El beneficio aquí es distribuir la carga de inserción a las diferentes particiones y administrar una partición creciente a través del código en lugar de mantener manualmente un disparador fuera del código base.
- Junto con una generación dinámica de particiones , podemos escalar un sistema ETL automáticamente. Las consultas de lectura usarían el sistema de particiones, haciendo que cada vez más datos detallados estén disponibles muy rápidamente con las consultas más simples.
Gracias por leer.
Añadir comentario