← На главную

Примеры использования DuckDB

DuckDB – это открытая (лицензия MIT) встраиваемая аналитическая СУБД. В июне этого года был анонсирован релиз 1.0.0, а значит проектом теперь можно пользоватья. Давайте же разберемся, что из себя представляет DuckDB.

DuckDB доступен в виде отдельного исполняемого файла, а также в виде библиотек для Python, Ruby, Go, Rust, C/C++ и других языков. В рамках этого поста воспользуемся исполняемым файлом:

wget https://github.com/.../duckdb_cli-linux-aarch64.zip unzip duckdb_cli-linux-aarch64.zip ./duckdb -init database.duckdb

Попробуем выполнить пару простых запросов:

CREATE TABLE phonebook( "id" INT NOT NULL, "name" TEXT NOT NULL, "phone" INT NOT NULL); INSERT INTO phonebook VALUES (1, 'Alex', 123); SELECT * FROM phonebook;

Пока что все это очень похоже на обычную SQL СУБД.

Попробуем что-нибудь поинтереснее:

CREATE TABLE temperature( ts TIMESTAMP NOT NULL, temperature INT NOT NULL); CREATE TABLE humidity( ts TIMESTAMP NOT NULL, humidity INT NOT NULL); INSERT INTO temperature (ts, temperature) SELECT ts.generate_series + INTERVAL(FLOOR(60*random()) || ' minutes'), 30*random() FROM generate_series(TIMESTAMP '2022-01-01', TIMESTAMP '2022-01-31', INTERVAL '1 day') AS ts; INSERT INTO humidity (ts, humidity) SELECT ts.generate_series + INTERVAL(FLOOR(60*random()) || ' minutes'), 100*random() FROM generate_series(TIMESTAMP '2022-01-01', TIMESTAMP '2022-01-31', INTERVAL '1 day') AS ts;

DuckDB поддерживает экспорт/импорт в/из CSV, Parquet и другие форматы:

COPY temperature TO 'temperature.parquet' (FORMAT PARQUET); COPY (SELECT * FROM humidity) TO 'humidity.parquet' (FORMAT PARQUET); DELETE FROM temperature; COPY temperature FROM 'temperature.parquet' (FORMAT PARQUET);

С Parquet-файлами можно работать напрямую, при этом они могут храниться и удаленно, в каком-нибудь Amazon S3:

SELECT * FROM read_parquet('temperature.parquet'); -- SELECT * FROM read_parquet('s3:// ...');

Поддерживаются некоторые расширения SQL, в частности, ASOF JOINS:

SELECT t.*, h.humidity FROM temperature AS t ASOF JOIN humidity AS h ON h.ts <= t.ts;

То же самое, но без таблиц:

SELECT t.*, h.humidity FROM read_parquet('temperature.parquet') AS t ASOF JOIN read_parquet('humidity.parquet') AS h ON h.ts <= t.ts;

DuckDB умеет работать и с другими источниками данных. В частности, можно сходить в Azure, по HTTP, в Iceberg, SQLite, MySQL или PostgreSQL. Это такой клей, который забирает данные отовсюду, выполняет над ними SQL-запросы, после чего складывает результат куда угодно. Я занимался аналитическими задачами такого рода в начале карьеры. Приходилось писать много кода на Perl. Здесь же все практически готовое. Удобно.

Больше информации о DuckDB вы найдете на официальном сайте проекта, а также на его GitHub.