Ir al contenido

Almacenamiento de Series Temporales en Apache Parquet

📦 Almacenamiento de Series Temporales en Apache Parquet

Sección titulada «📦 Almacenamiento de Series Temporales en Apache Parquet»

Almacenar millones de cotizaciones históricas y tipos de cambio diarios directamente dentro del archivo SQLite transaccional degrada la velocidad de las copias de seguridad y reduce el rendimiento de escritura OLTP.

Criptofolio delega el almacenamiento de series temporales históricas en archivos Apache Parquet organizados en un árbol de directorios con particionado Hive.


🗂️ Estructura de Directorios con Particionado Hive

Sección titulada «🗂️ Estructura de Directorios con Particionado Hive»

Los datos históricos de precios descargados de los proveedores de mercado se guardan en disco siguiendo esta distribución:

data/
└── historical/
└── prices/
├── year=2024/
│ ├── month=01/
│ │ ├── btc_eur.parquet
│ │ └── eth_eur.parquet
│ └── month=12/
└── year=2025/
└── month=06/
└── sol_eur.parquet
  • Poda de Particiones (Partition Pruning): Si una consulta solicita la valoración de la cartera para el año 2025, DuckDB omite automáticamente las carpetas de 2023 y 2024 sin necesidad de leerlas de disco.
  • Compresión Extrema: El almacenamiento columnar con algoritmos Snappy/ZSTD reduce el espacio en disco en más de un 90% comparado con tablas SQL tradicionales o archivos JSON/CSV.

DuckDB lee archivos Parquet de manera nativa sin requerir ningún proceso previo de importación o carga en tablas intermedias:

-- Consulta federada directa con empuje de predicados a disco:
SELECT
price_timestamp,
price_eur,
volume_24h
FROM read_parquet('data/historical/prices/year=2025/**/*.parquet')
WHERE asset_symbol = 'BTC'
ORDER BY price_timestamp ASC;

Durante el cálculo de la valoración diaria de la cartera, DuckDB federará la información de ambos motores simultáneamente:

SELECT
tx.timestamp,
tx.amount_in,
p.price_eur,
(CAST(tx.amount_in AS DECIMAL(38,18)) * p.price_eur) AS cost_basis_eur
FROM ledger.spot_transactions tx
ASOF JOIN read_parquet('data/historical/prices/**/*.parquet') p
ON tx.asset_id = p.asset_id
AND tx.timestamp >= p.price_timestamp;
  • ledger.spot_transactions se consulta en tiempo real desde SQLite vía conexión de copia cero.
  • historical_prices se lee de forma continua desde los archivos Parquet en disco.
  • El optimizador vectorizado de DuckDB ejecuta el cruce en un único flujo de ejecución (pipeline) sin saturar la memoria RAM.