Сборка учебной базы в DuckDB
До первого запроса нужна база, на которой он выполняется. В практикуме она собирается из двух SQL-файлов: один создаёт таблицы, второй наполняет их данными. Ничего скачивать не нужно, интернет не нужен, ключи и доступы тоже.
Сборка занимает несколько секунд. Если она прошла, дальше вы работаете
с локальным файлом practice.duckdb: его можно копировать, ломать и собирать
заново.
Что нужно
Заголовок раздела «Что нужно»DuckDB версии 1.x в командной строке:
duckdb --versionv1.5.6 (Variegata) 069cc9f9b5Курс проверен на версии 1.5.6. На старых версиях часть синтаксиса может отличаться — если запрос не запускается, начните с обновления DuckDB.
Из корня репозитория портала перейдите в папку с данными и запустите два файла по очереди:
cd scripts/practice-dataduckdb practice.duckdb < schema.sqlduckdb practice.duckdb < seed.sqlПервая команда создаёт пустые таблицы, вторая наполняет их. Порядок важен:
seed.sql вставляет заказы со ссылкой на поставщика, и внешний ключ не даст
вставить заказ раньше, чем появится справочник.
Проверка
Заголовок раздела «Проверка»Число строк в каждой таблице:
SELECT 'purchases' AS "таблица", count(*) AS "строк" FROM purchasesUNION ALL SELECT 'purchase_lines', count(*) FROM purchase_linesUNION ALL SELECT 'suppliers', count(*) FROM suppliersUNION ALL SELECT 'bids', count(*) FROM bids;┌────────────────┬───────┐│ таблица │ строк │├────────────────┼───────┤│ purchases │ 400 ││ purchase_lines │ 923 ││ suppliers │ 60 ││ bids │ 1600 │└────────────────┴───────┘Период и объём:
SELECT count(DISTINCT category) AS "категорий", min(order_date) AS "первый заказ", max(order_date) AS "последний заказ", round(sum(amount)/1000000, 1) AS "spend, млн ₽"FROM purchases;┌───────────┬──────────────┬─────────────────┬──────────────┐│ категорий │ первый заказ │ последний заказ │ spend, млн ₽ │├───────────┼──────────────┼─────────────────┼──────────────┤│ 9 │ 2024-01-06 │ 2025-12-25 │ 277.9 │└───────────┴──────────────┴─────────────────┴──────────────┘Что означают эти числа
Заголовок раздела «Что означают эти числа»- 400 заказов за 24 месяца — примерно 17 заказов в месяц. Этого хватает, чтобы увидеть сезонность, но мало для статистической значимости: не путайте учебный масштаб с рабочим.
- 923 позиции — в среднем 2,3 позиции на заказ.
- 60 поставщиков в справочнике. Из них 57 выиграли хотя бы один заказ, остальные три записи в справочнике есть, а заказов у них нет.
- 1600 предложений — по 3–5 на заказ. Десять заказов обошлись без предложений вовсе: это одна из заложенных аномалий.
Если числа не сошлись
Заголовок раздела «Если числа не сошлись»| Симптом | Причина | Что делать |
|---|---|---|
Catalog Error: Table with name purchases does not exist |
schema.sql не запускался или база создана в другом файле |
Проверьте, что обе команды выполнены в одной папке, и запустите schema.sql заново |
Constraint Error: Duplicate key |
seed.sql запущен на уже наполненной базе |
Удалите practice.duckdb и соберите заново |
| Таблицы есть, строк меньше | seed.sql упал на середине |
Смотрите сообщение об ошибке выше по выводу, затем пересоберите с нуля |
| Числа строк совпали, суммы другие | Другая версия seed.sql |
Сверьтесь с репозиторием: данные воспроизводимы, расхождение означает другую версию файла |
Пересборка с нуля — это две команды и пять секунд:
rm -f practice.duckdbduckdb practice.duckdb < schema.sqlduckdb practice.duckdb < seed.sqlПочему данные не «плывут»
Заголовок раздела «Почему данные не «плывут»»seed.sql не использует random(). Все случайные величины считаются
от номера строки через hash(), поэтому повторная сборка даёт ту же базу —
независимо от порядка выполнения и числа потоков. Это важно для уроков: числа
в тексте и в вашем выводе должны совпадать, иначе разбор превращается в гадание.
Что читать дальше
Заголовок раздела «Что читать дальше»- Датасет: таблицы и зерно — что означает строка в каждой таблице.
- ABC-анализ по сумме закупок — первый расчёт.
- Практикум: как всё устроено