DuckDB — встраиваемая аналитическая СУБД: она работает внутри процесса, хранит данные в одном файле и не требует отдельного сервера. Для отчётов по CSV, Parquet и выгрузкам из продакшена это удобнее, чем поднимать PostgreSQL или считать всё в pandas. При этом SQL настоящий, с оконными функциями, CTE и типами. Ниже — установка, запросы к файлам, экспорт, настройка памяти и честные ограничения.

Место DuckDB среди СУБД

DuckDB — колоночная OLAP-система с векторным исполнением. Она оптимизирована под сканирование больших диапазонов и агрегаты, а не под множество мелких транзакций. SQLite — построчная OLTP-база, PostgreSQL — сервер для параллельных клиентов. DuckDB занимает нишу между ними: аналитика на одной машине, без администрирования, с полноценным SQL. Файл базы можно передать коллеге, положить в архив или открыть только для чтения. Это же свойство делает её удобной для ноутбуков, CI и исследовательских задач.

Установка

Самый короткий путь — Python-пакет. Он содержит и библиотеку, и CLI.

python3 -m venv .venv
source .venv/bin/activate
pip install duckdb
python -c "import duckdb; print(duckdb.__version__)"

Для сервера без Python удобен официальный бинарник CLI. Он не требует зависимостей и ставится в /usr/local/bin. Архив в примере собран под x86-64, для ARM публикуется отдельный.

curl -L -o duckdb.zip https://github.com/duckdb/duckdb/releases/latest/download/duckdb_cli-linux-amd64.zip
unzip duckdb.zip
sudo install duckdb /usr/local/bin/
duckdb --version

Пакеты есть в conda и в репозиториях некоторых дистрибутивов, но версия там отстаёт. Для новых функций лучше официальная сборка.

Файловая база и первые запросы

База — обычный файл. При первом открытии он создаётся, при повторном — открывается.

duckdb analytics.duckdb
CREATE TABLE events (ts TIMESTAMP, user_id BIGINT, action VARCHAR, amount DECIMAL(10,2));
COPY events FROM 'events.csv' (HEADER, DELIMITER ',');
SELECT action, count(*) AS n FROM events GROUP BY ALL ORDER BY n DESC;

GROUP BY ALL избавляет от перечисления колонок. Типы DECIMAL и TIMESTAMP поддерживаются полноценно, в отличие от многих легковесных движков. Команда DESCRIBE events покажет схему, а SUMMARIZE events — распределение значений и долю NULL. Для загрузки больших файлов полезен прогресс-бар и параметр SAMPLE_SIZE при определении схемы.

CSV и Parquet без загрузки

Читать можно напрямую из файлов: DuckDB сама определит схему, а для Parquet возьмёт метаданные.

SELECT * FROM read_csv_auto('logs/*.csv', union_by_name=true) LIMIT 5;
SELECT date_trunc('day', ts) AS day, sum(amount) AS total
FROM read_parquet('exports/2026/*.parquet')
GROUP BY ALL ORDER BY day;

Шаблоны glob раскрываются, партиционирование Hive подхватывается флагом hive_partitioning=true. Проекция и фильтры проталкиваются в сканирование: если выбрать две колонки, остальные не читаются. Для CSV это экономит меньше, для Parquet — заметно. Сжатые gzip-файлы читаются, но параллелизм на них ограничен.

Оконные функции и PIVOT

Аналитика редко обходится без окон. QUALIFY фильтрует результат оконной функции без подзапроса.

SELECT user_id, ts, amount,
       sum(amount) OVER (PARTITION BY user_id ORDER BY ts) AS running
FROM events
QUALIFY row_number() OVER (PARTITION BY user_id ORDER BY ts DESC) = 1;

PIVOT разворачивает строки в колонки, UNNEST разбирает списки, а типы LIST и STRUCT позволяют хранить вложенные данные без JSON-хаков. Всё это работает и в CLI, и через Python API. Для разворота достаточно указать колонку, значения и агрегат:

PIVOT events ON action USING sum(amount) GROUP BY user_id;

Экспорт и обмен

Результат удобно отдавать в Parquet: колонки, сжатие, схема.

COPY (SELECT * FROM events) TO 'events.parquet' (FORMAT parquet, COMPRESSION zstd);
EXPORT DATABASE 'backup' (FORMAT parquet);
ATTACH 'other.duckdb' AS other;
INSERT INTO other.events SELECT * FROM events;

EXPORT DATABASE создаёт каталог со схемой и данными, пригодный для переноса. ATTACH открывает вторую базу в той же сессии, поэтому JOIN между файлами не требует промежуточной загрузки. Обратная операция — IMPORT DATABASE — восстанавливает объекты из такого каталога.

Python и Arrow

В Python DuckDB возвращает pandas, Arrow или обычные кортежи.

import duckdb

con = duckdb.connect("analytics.duckdb", read_only=True)
df = con.execute("SELECT action, sum(amount) AS total FROM events GROUP BY 1").df()

read_only не даёт случайно изменить файл и позволяет открыть его параллельно с другим процессом на чтение. Метод .arrow() возвращает таблицу Arrow без копирования, что важно при больших выгрузках. Соединение можно переиспользовать в пределах процесса, но запись всё равно остаётся однопоточной.

Память и производительность

По умолчанию DuckDB берёт разумную долю памяти, но на сервере лучше задать лимиты явно.

PRAGMA threads=4;
PRAGMA memory_limit='4GB';
PRAGMA temp_directory='/var/tmp/duckdb';
EXPLAIN ANALYZE SELECT action, count(*) FROM events GROUP BY ALL;

При нехватке памяти движок сбрасывает промежуточные результаты на диск. EXPLAIN ANALYZE показывает реальное время и число строк, а PRAGMA database_size — размер файла и свободное место. После массовых вставок полезен CHECKPOINT, который сливает журнал в основной файл.

Ограничения

DuckDB — не замена серверной СУБД. Писатель в файл один: два процесса на запись конфликтуют. Нет многопользовательской модели прав и сетевого протокола. Транзакции есть, но конкурентная нагрузка из десятков клиентов — не её сценарий. Для потоковой вставки лучше буферизовать данные и писать пакетами, а для совместного доступа — экспортировать Parquet или использовать серверную базу. Отдельного сервера и демона нет: база открывается процессом, а блокировка файла не даёт двум писателям испортить данные. Это осознанный компромисс ради простоты. Для больших проектов удобно держать SQL в отдельных файлах и запускать их через .read в CLI или execute в Python.

Чек-лист

  • Версия DuckDB зафиксирована в зависимостях проекта.
  • Файл базы не лежит в сетевой папке с блокировками.
  • Для повторяющихся отчётов сохранены SQL-файлы и схема.
  • Лимиты памяти и threads заданы для сервера.
  • Крупные выгрузки идут в Parquet, а не в CSV.
  • Резервная копия — копия файла или EXPORT DATABASE.

Итог

DuckDB закрывает разрыв между скриптом и полноценной аналитической базой. Она ставится за минуту, читает CSV и Parquet без предварительной загрузки, поддерживает оконные функции и нормальные типы. Для интерактивной аналитики на ноутбуке или сервере это часто лучший инструмент. Но если несколько пользователей пишут одновременно или нужны права доступа, выбирайте PostgreSQL или другую серверную СУБД.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте