La pile data moderne déplace la complexité en petits morceaux
La pile data moderne commence à afficher pas mal de logos. Chaque outil règle un problème assez précis. Une fois tout branché, il faut quand même comprendre lequel appelle l’autre et lequel explique la nouvelle ligne sur la facture.
La direction est intéressante. Les entrepôts gérés dans le cloud séparent davantage le stockage du calcul. On peut charger les données assez brutes, augmenter temporairement la puissance pour une transformation et la réduire ensuite. Mais il faut suivre le trajet d’une ligne entre tous ces services.
De la source au tableau
Prenons les commandes d’un ERP. Un connecteur lit les nouvelles lignes, souvent avec une colonne de modification ou un journal de changements. Il les écrit d’abord dans une zone brute sans remplacer silencieusement l’historique. L’entrepôt charge ensuite cette copie dans une table de staging. Des modèles SQL construisent les dimensions, les faits et finalement le chiffre présenté dans le dashboard.
ERP → connecteur incrémental → stockage brut → stg_orders
↓
dim_customer
+
fct_net_sales
↓
dashboard ventes
Passer de l’ETL à davantage d’ELT semble être un simple changement de lettre. Dans l’ETL, un moteur transforme les données avant de les charger dans la cible. Dans l’ELT, il charge d’abord, puis laisse l’entrepôt exécuter le SQL. La logique devient plus visible pour les analystes et profite du calcul de l’entrepôt, mais les données brutes y arrivent aussi plus tôt. Les permissions et le masquage doivent suivre.
Écrire la définition comme du code
Une vente nette ne devrait pas rester une formule copiée dans trois rapports. Un modèle SQL peut la définir une fois :
WITH order_lines AS (
SELECT
order_id,
customer_id,
CAST(order_date AS DATE) AS order_date,
quantity * unit_price AS gross_sales,
discount_amount,
returned_amount
FROM stg_order_lines
WHERE status = 'INVOICED'
)
SELECT
order_date,
customer_id,
SUM(gross_sales - discount_amount - returned_amount) AS net_sales
FROM order_lines
GROUP BY order_date, customer_id;
Le fichier vit dans Git. Une revue montre le changement de règle. Le pipeline connaît ses dépendances et reconstruit fct_net_sales après stg_order_lines. Des tests peuvent vérifier que order_id n’est pas nul, que les clés clients se résolvent et que les ventes nettes restent dans une plage plausible.
Ça ne décide pas automatiquement ce qu’est une vente. L’équipe doit encore trancher si une commande expédiée mais non facturée compte, comment dater un retour et quelle devise utiliser. La valeur vient du fait que cette décision devient explicite, versionnée et utilisée par tous les consommateurs.
Rejouer sans doubler
Un connecteur incrémental peut tomber après avoir lu 10 000 lignes mais avant d’enregistrer son point de reprise. Au redémarrage, il relit une partie du lot. La table brute devrait accepter ce comportement avec une clé source, un horodatage de changement et une opération de fusion idempotente.
clé technique = source_system + source_table + source_primary_key + changed_at
Si la source modifie une ligne sans mettre à jour l’horodatage, le changement ne sera jamais capturé. Si elle supprime un dossier, le connecteur doit transmettre un marqueur de suppression ou faire une réconciliation périodique. Je veux donc comparer les comptes, conserver les erreurs et pouvoir repartir d’un snapshot complet.
Le graphe de transformations doit aussi empêcher un rapport de mélanger deux moments. Si dim_customer a été mise à jour mais fct_net_sales a échoué, le dashboard peut joindre des versions incompatibles. Une publication atomique — construire dans des tables temporaires, tester, puis changer les vues — garde l’ancienne version visible jusqu’à ce que tout le lot passe.
Les petits morceaux ont chacun une facture
Chaque connecteur ajoute un compte, un secret, une mise à jour et une façon de tomber en panne. Je veux une identité de service avec les droits minimaux, une rotation des secrets, une métrique sur le retard d’ingestion et une personne responsable de l’alerte.
L’élasticité change aussi le coût. Selon le service, on paie le calcul réservé, les secondes d’exécution, les octets lus, le stockage et le trafic. Une requête qui relit chaque jour dix téraoctets pour recalculer une seule journée peut coûter sans produire d’erreur. Le partitionnement par date et les modèles incrémentaux réduisent ce travail, à condition de savoir rejouer une période corrigée.
Je suivrais pour chaque modèle :
- la fraîcheur maximale de sa source;
- son temps et son volume de calcul;
- les tests réussis ou échoués;
- ses consommateurs dans le lineage;
- la dernière personne qui a changé sa définition.
Avec mon passé de développeur, cette logique versionnée me plaît. Mais remplacer une grosse plateforme par douze services ne supprime pas la complexité; ça la met sur les contrats entre eux. Je veux une stack où je peux partir d’un chiffre du dashboard, remonter le SQL, retrouver le lot source et rejouer la chaîne sans doubler les données. Le nombre de logos vient loin derrière.