Introduction
DuckDB est largement reconnu pour ses capacitĂ©s de traitement analytique, mais sa vĂ©ritable puissance rĂ©side dans son moteur de requĂȘte exceptionnel. Contrairement aux bases de donnĂ©es traditionnelles qui nĂ©cessitent une configuration et des processus ETL complexes, DuckDB permet aux utilisateurs d’interroger des donnĂ©es provenant de diverses sources de maniĂšre fluide. Cet article explore le moteur de requĂȘte de DuckDB, ses avantages et propose un guide pratique pour l’utiliser efficacement.
Qu’est-ce qui fait du moteur de requĂȘte de DuckDB un outil rĂ©volutionnaire ?
Contrairement Ă de nombreuses bases de donnĂ©es qui nĂ©cessitent l’importation de donnĂ©es avant l’interrogation, le moteur de requĂȘte de DuckDB est conçu pour fonctionner directement sur plusieurs formats de fichiers et bases de donnĂ©es externes . Voici ce qui le distingue :
Caractéristiques principales
- Prend en charge plusieurs formats de fichiers : Faites des requĂȘte sur des fichiers CSV, Parquet, JSON et plus sans conversion manuelle.
- Fonctionne avec les bases de données relationnelles : se connecte de maniÚre transparente à PostgreSQL, MySQL et autres.
- Lire les formats de données ouverts : prend en charge Iceberg et Delta Lake.
- Interface SQL simple : aucune configuration complexe requise.
- Compatibilité multi-language : fonctionne avec Python, R, Java, Node.js, Rust, etc.
- Pris en charge par les outils de visualisation : Pris en charge comme source de donnĂ©es par les outils de visualisation tels qu’Apache-Superset, metabase, les outils basĂ©s sur JDBC (Tableau,…), etc.
Optimisations avancées dans DuckDB
-
DuckDB est un systĂšme de gestion de base de donnĂ©es (SGBD) relationnel (orientĂ© table) prenant en charge le langage SQL (Structured Query Language) . Il est conçu pour rĂ©pondre au besoin d’un systĂšme de base de donnĂ©es offrant un ensemble unique de compromis, notamment pour les cas d’utilisation analytiques. Ses principales caractĂ©ristiques sont sa simplicitĂ© et son fonctionnement intĂ©grĂ© , inspirĂ© de SQLite. Il ne nĂ©cessite aucune dĂ©pendance externe pour la compilation ou l’exĂ©cution et est compilĂ© dans un fichier d’en-tĂȘte et d’implĂ©mentation unique (une « fusion »), simplifiant ainsi le dĂ©ploiement. Contrairement aux bases de donnĂ©es client-serveur traditionnelles, DuckDB s’exĂ©cute entiĂšrement intĂ©grĂ© Ă un processus hĂŽte , Ă©liminant ainsi le besoin d’installation et de maintenance d’un logiciel serveur distinct. Cette intĂ©gration permet un transfert de donnĂ©es Ă haut dĂ©bit et la possibilitĂ© de traiter des donnĂ©es externes, telles que les Pandas DataFrames en Python, sans copie.
-
Conçu pour exceller dans les charges de travail de requĂȘtes analytiques (OLAP) caractĂ©risĂ©es par des requĂȘtes complexes et longues sur de grands ensembles de donnĂ©es, DuckDB utilise un moteur d’exĂ©cution de requĂȘtes vectorisĂ© en colonnes . Cette approche traite les donnĂ©es par lots (« vecteurs »), rĂ©duisant considĂ©rablement la charge par rapport aux systĂšmes traditionnels basĂ©s sur les lignes comme PostgreSQL, MySQL ou SQLite. DuckDB est Ă©galement extensible , permettant aux utilisateurs de dĂ©finir de nouveaux types de donnĂ©es, fonctions, formats de fichiers et syntaxe SQL grĂące Ă un mĂ©canisme d’extension. Notamment, la prise en charge de formats courants comme Parquet et JSON, ainsi que de protocoles comme HTTP(S) et s3, est implĂ©mentĂ©e sous forme d’extensions.
-
DuckDB est extrĂȘmement portable , capable d’ĂȘtre compilĂ© pour tous les principaux systĂšmes d’exploitation (Linux, macOS, Windows) et architectures CPU (x86, ARM), et peut mĂȘme fonctionner dans les navigateurs web et sur les tĂ©lĂ©phones portables via DuckDB-Wasm. Il fournit des API pour divers langages de programmation, dont Java, C, C++, Go et Python. MalgrĂ© sa simplicitĂ©, DuckDB est riche en fonctionnalitĂ©s , offrant une prise en charge Ă©tendue des requĂȘtes SQL complexes, une vaste bibliothĂšque de fonctions, des fonctions de fenĂȘtrage, des garanties transactionnelles (propriĂ©tĂ©s ACID) , des bases de donnĂ©es monofichier persistantes et des index secondaires. Il est Ă©galement profondĂ©ment intĂ©grĂ© Ă Python et R pour une analyse de donnĂ©es interactive et efficace.
Pour plus de détails techniques, visitez la documentation officielle de DuckDB .
DuckDB vs Apache Spark vs Trino : comparaison rapide
| Fonctionnalité | DuckDB | Apache Spark | Trino |
|---|---|---|---|
| CoĂ»ts d’installation | Gratuit, lĂ©ger | Configuration du cluster requise | NĂ©cessite une configuration distribuĂ©e |
| Coûts de fonctionnement | Minimal | Dépenses courantes du cluster | Coûts du cluster ou du cloud |
| Courbe d’apprentissage | Connaissances de base en SQL | NĂ©cessite un apprentissage plus approfondi | Connaissances SQL modĂ©rĂ©es |
| Performance | Rapide pour les requĂȘtes locales | S’adapte bien au Big Data | OptimisĂ© pour SQL distribuĂ© |
| Cas d’utilisation | Analyses locales | Traitement distribuĂ© des donnĂ©es | Moteur de requĂȘte fĂ©dĂ©rĂ© |
DuckDB est idĂ©al pour les requĂȘtes analytiques locales, Spark est meilleur pour le calcul distribuĂ© Ă grande Ă©chelle et Trino excelle dans les requĂȘtes fĂ©dĂ©rĂ©es sur plusieurs sources.
Pratique : LibĂ©rez DuckDB comme moteur de requĂȘte
Dans ce tutoriel, nous utiliserons DuckDB pour interroger trois sources de données différentes :
- Base de données PostgreSQL
- Base de données MySQL
- Fichiers CSV
-
JSON Ă partir d’un serveur Web
1. Configuration de l’environnement
Nous utiliserons Docker Compose pour configurer l’infrastructure. Commencez par cloner le dĂ©pĂŽt et dĂ©marrer les services :
git clone https://github.com/mikekenneth/bp_duck_as_query_engine
cd bp_duck_as_query_engine
make up # Start services
VĂ©rifiez les conteneurs en cours d’exĂ©cution avec :
docker ps
Ensuite, accédez à DuckDB CLI :
make duckdb
Pour faciliter la configuration, j’ai créé un duckdb_init.sql contenant les commandes SQL nĂ©cessaires pour se connecter Ă nos sources de donnĂ©es externes.
2. Connexion aux sources de données externes
a) Connexion Ă MinIO (stockage compatible s3)
Pour interagir avec les donnĂ©es stockĂ©es dans MinIO, nous devons activer l’extension HTTPS et configurer les paramĂštres de connexion :
-- Enable the HTTPS Extension to connect to s3/Minio
INSTALL https;
LOAD https;
-- Set Connection settings
SET s3_region='us-east-1';
SET s3_url_style='path';
SET s3_endpoint='minio:9000';
SET s3_access_key_id='minio_root' ;
SET s3_secret_access_key='minio_toor';
SET s3_use_ssl=false; -- Needed when running without SSL
Vérifions si les paramÚtres sont correctement appliqués.
b) Connexion Ă PostgreSQL
Pour interroger les donnĂ©es dans notre instance PostgreSQL, nous devons charger l’extension PostgreSQL, puis nous attacher Ă la base de donnĂ©es :
-- Load Extension
INSTALL postgres;
LOAD postgres;
-- Attach the PostgreSQL database
ATTACH 'dbname=postgres user=postgres password=postgres host=postgres port=5432'
AS postgres_db (TYPE postgres, SCHEMA 'public');
Explication : La
INSTALL postgres;commande prend dĂ©sormais en charge l’interaction avec les bases de donnĂ©es PostgreSQL.ATTACHElle Ă©tablit une connexion Ă la base de donnĂ©es PostgreSQL spĂ©cifiĂ©e (dbname,user,password,host) et lui attribue l’aliaspostgres_db, rendant ainsi ses tables accessibles dans DuckDB. Nous spĂ©cifions Ă©galement le type et le schĂ©ma de la base de donnĂ©es.
Nous pouvons maintenant créer une table dans PostgreSQL en lisant un fichier CSV à partir de notre instance MinIO :
-- Create the base table in Postgres from s3
create or replace table postgres_db.fct_trips as
(
select *
from read_csv("s3://duckdb-bucket/init_data/base_raw.csv")
);
c) Connexion Ă MySQL
-- Load Extension
INSTALL mysql;
LOAD mysql;
-- Attach the MYSQL database
ATTACH 'database=db user=user password=password host=mysql port=3306'
AS mysql_db (TYPE mysql);
Explication : Cette
INSTALL mysql;commande permet d’interagir avec les bases de donnĂ©es MySQL.ATTACHElle se connecte Ă la base de donnĂ©es MySQL Ă l’aide des informations d’identification fournies et lui attribue l’aliasmysql_db. Le type de base de donnĂ©es est Ă©galement spĂ©cifiĂ©.
Créons une table dans MySQL en lisant un fichier CSV depuis MinIO :
-- Create the base table in MySQL from s3
create or replace table mysql_db.dim_credit_card as
(
select *
from read_csv("s3://duckdb-bucket/init_data/base_raw.csv")
);
Confirmons que les deux bases de données sont correctement connectées :
d) RequĂȘte de donnĂ©es JSON Ă partir d’un serveur Web
Enfin, dĂ©montrons comment rĂ©cupĂ©rer des donnĂ©es directement Ă partir dâun serveur Web servant un fichier JSON :
select distinct *
from read_json('http://nginx:80/companies_data.json')
Cette requĂȘte lit et traite directement les donnĂ©es JSON disponibles Ă l’URL spĂ©cifiĂ©e.
Voici le rĂ©sultat de la requĂȘte :
3. Interrogation simultanée de plusieurs sources de données
Avec la connectivitĂ© Ă©tablie avec MinIO et nos bases de donnĂ©es relationnelles, nous pouvons dĂ©sormais exĂ©cuter une seule requĂȘte qui rĂ©cupĂšre et joint les donnĂ©es de toutes nos sources configurĂ©es :
---------------- Query multiple Data Sources Simultaneously ----------------
with
fct_trips as (
select *
from postgres_db.public.fct_trips
),
dim_customer as (
select distinct *
from read_csv('s3://duckdb-bucket/init_data/customer.csv')
),
dim_creditcard as (
select distinct *
from mysql_db.db.dim_credit_card
),
dim_companies_data_web as (
select distinct *
from read_json('http://nginx:80/companies_data.json')
)
select
trips."Trip ID",
-- Customer info
dcust.id as customer_id, dcust.name as customer_name,dcust.sex as customer_sex,
dcust.address as customer_address, dcust.birth_date as customer_birth_date,
-- Credit Card info
dcard.credit_card_number as credit_card_number, dcard.expire_date as credit_card_expire_date,
dcard.provider as credit_card_provider, dcard.owner_name as credit_card_owner_name,
-- Company info
dcompany.name as company_name, dcompany.address as company_address,
dcompany.created_date as company_created_date, dcompany.num_of_employee as company_num_of_employee
from fct_trips trips
LEFT JOIN dim_customer dcust on trips.customer_id = dcust.id
LEFT JOIN dim_creditcard dcard on trips.credit_card_number = dcard.credit_card_number
LEFT JOIN dim_companies_data_web dcompany on trips.Company = dcompany.name;
Résultat:
4. Exportation des rĂ©sultats de la requĂȘte
De plus, DuckDB permet d’exporter directement les rĂ©sultats de requĂȘtes vers un stockage externe, tel que S3/MinIO, dans diffĂ©rents formats de fichiers. Ici, nous allons exporter les donnĂ©es jointes au format Parquet :
COPY (
with
fct_trips as (
select *
from postgres_db.public.fct_trips
...
...
...
from fct_trips trips
LEFT JOIN dim_customer dcust on trips.customer_id = dcust.id
LEFT JOIN dim_creditcard dcard on trips.credit_card_number = dcard.credit_card_number
LEFT JOIN dim_companies_data_web dcompany on trips.Company = dcompany.name
) TO 's3://duckdb-bucket/query_result.parquet' (FORMAT parquet);
Nous pouvons ensuite vérifier le contenu du fichier Parquet exporté directement avec DuckDB
Nous pouvons ensuite valider le fichier exporté :
SELECT * FROM read_parquet('s3://duckdb-bucket/query_result.parquet');
Conclusion
DuckDB est un moteur de requĂȘte puissant et lĂ©ger qui permet d’interroger facilement plusieurs sources. Que vous travailliez avec des fichiers CSV, des bases de donnĂ©es ou des donnĂ©es JSON web, son interface SQL simple et ses hautes performances en font un excellent choix pour l’analyse. Ă mesure que l’Ă©cosystĂšme se dĂ©veloppe, DuckDB continue d’ajouter de nouvelles fonctionnalitĂ©s, ce qui en fait une alternative solide pour le traitement local des donnĂ©es.
Références







