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.parquetVentajas del Particionado Hive:
Sección titulada «Ventajas del Particionado Hive:»- 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.
🚀 Consultas Federadas en DuckDB
Sección titulada «🚀 Consultas Federadas en DuckDB»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_24hFROM read_parquet('data/historical/prices/year=2025/**/*.parquet')WHERE asset_symbol = 'BTC'ORDER BY price_timestamp ASC;🔄 Joins ASOF en Copia Cero con SQLite
Sección titulada «🔄 Joins ASOF en Copia Cero con SQLite»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_eurFROM ledger.spot_transactions txASOF JOIN read_parquet('data/historical/prices/**/*.parquet') p ON tx.asset_id = p.asset_id AND tx.timestamp >= p.price_timestamp;ledger.spot_transactionsse consulta en tiempo real desde SQLite vía conexión de copia cero.historical_pricesse 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.