Почему не Sakila? Создаём современную учебную базу данных для MariaDB

от автора

Если вы когда-либо преподавали SQL или проходили курс по базам данных, то почти наверняка встречали Sakila — маленькую базу данных видеопроката, которая вот уже почти двадцать лет служит эталонным примером в туториалах по MySQL и MariaDB. Схема чистая, нормализованная, данных достаточно для интересных запросов.

Проблема в другом: Sakila спроектирована в 2006 году под MySQL 5.0.

С тех пор многое изменилось.


Чего Sakila не может показать

Откройте схему Sakila и пересчитайте типы столбцов: INT, VARCHAR, TEXT, ENUM, DATETIME, DECIMAL, TINYINT. Всё. Никакого JSON. Никакого полнотекстового поиска сверх базовой демонстрации. Никакого SET. И совсем никакого VECTOR.

А в MariaDB 11.7 уже есть:

  • нативный тип VECTOR(N) для поиска похожих объектов в эпоху ИИ;

  • богатые JSON-функции — JSON_TABLE, JSON_VALUE, JSON_EXTRACT;

  • оконные функции — RANK, LAG, LEAD, нарастающие агрегаты;

  • рекурсивные CTE;

  • FULLTEXT— поиск с булевым режимом и оценкой релевантности.

Учить SQL на Sakila в 2026 году — всё равно что учить вождению на машине без навигатора, без камеры заднего вида и с ручным подсосом. Основы те же, но половина возможностей современного инструмента остаётся за кадром.

Есть и проблема предметной области. Видеопрокат. Если вам нет сорока, вы, скорее всего, никогда туда не заходили. Ментальная модель не интуитивна, бизнес-правила кажутся надуманными. Зачем таблица payment существует отдельно от rental? На объяснение схемы уходит время, которое должно уходить на объяснение SQL.


Предметная область, понятная каждому

Нужно было выбрать что-то универсальное. Что-то с:

  • очевидными сущностями и связями;

  • несколькими естественными иерархиями (отличный повод для рекурсивных CTE);

  • смесью маленьких справочников и больших транзакционных таблиц;

  • понятной причиной хранить JSON и вектора.

Университет подходит идеально. Студенты, курсы, преподаватели, зачисления, оценки — каждый прожил внутри этой системы. Связи интуитивны. А предметная область естественным образом порождает именно те структуры данных, которые нужны для обучения:

Требование

Что есть в университете

Большая аналитическая таблица

grade_events — 120 000+ строк оценок

Иерархия для рекурсивного CTE

Факультет → Кафедра → Подразделение; цепочки пресреквизитов курсов

JSON для полуструктурированных данных

Расписание преподавателей, контакты студентов, источники финансирования

Полнотекстовый поиск

Описания курсов, аннотации публикаций

Векторный поиск

Эмбеддинги курсов для поиска похожих

Журнал изменений

Каждое зачисление и оценка логируются с JSON-дифами


Как устроена University DB

Схема содержит 16 таблиц в четырёх уровнях:

Справочники (несколько десятков строк): semesters, rooms, scholarships

Основные сущности (до 2 000 строк): departments, faculty, students, courses, course_prerequisites, sections

Транзакционные (до 10 000 строк): enrollments, student_scholarships, research_projects, publications, project_members

Аналитические (большие): grade_events (~120 тыс. строк) и audit_log (~60 тыс. строк, заполняется триггерами)

Все значимые типы данных MariaDB представлены хотя бы один раз:

-- VECTOR на courses - семантические эмбеддинги для поиска похожих курсовembedding  VECTOR(1536) NULL-- JSON на faculty - гибкое расписание приёмных часовoffice_hours JSON NULL-- [{"day": "Mon", "start": "10:00", "end": "12:00"}, ...]-- SET на publications - множественные теги ключевых словkeywords SET('AI', 'ML', 'Databases', 'Security', 'Bioinformatics', ...)-- FULLTEXT-индексы на courses и publicationsFULLTEXT KEY ft_course (title, description)

В схеме есть 7 представлений, 6 хранимых процедур и 7 триггеров — в том числе триггер, блокирующий запись на переполненный курс, и три триггера, которые пишут JSON-диф изменений в таблицу audit_log.


Четыре уровня примеров запросов

Примеры разбиты на четыре файла — база данных подходит и новичкам, и опытным разработчикам:

Уровень 1 — Основы: SELECT, WHERE, GROUP BY, простая агрегация

Уровень 2 — Средний: JOIN по 5 таблицам, коррелированные подзапросы, FULLTEXT, JSON_VALUE

Уровень 3 — Продвинутый: оконные функции, CTE, рекурсивные CTE, JSON_TABLE, FIND_IN_SET, VEC_Distance

Уровень 4 — DBA/Разработчик: EXPLAIN ANALYZE, стратегия индексов, написание хранимых процедур, уровни изоляции транзакций, криминалистика по audit_log

Рекурсивный CTE для получения полной цепочки пресреквизитов курса:

WITH RECURSIVE prereq_chain AS (    -- Якорь: прямые пресреквизиты    SELECT cp.prerequisite_id,           p.code   AS prereq_code,           p.title  AS prereq_title,           1        AS depth    FROM   course_prerequisites cp    JOIN   courses p ON p.course_id = cp.prerequisite_id    WHERE  cp.course_id = (SELECT course_id FROM courses WHERE code = 'CS300')    UNION ALL    -- Рекурсия: пресреквизиты пресреквизитов    SELECT cp2.prerequisite_id, p2.code, p2.title, pc.depth + 1    FROM   course_prerequisites cp2    JOIN   prereq_chain         pc ON pc.prerequisite_id = cp2.course_id    JOIN   courses              p2 ON p2.course_id = cp2.prerequisite_id    WHERE  pc.depth < 10   -- защита от цикличных данных)SELECT DISTINCT depth, prereq_code, prereq_titleFROM   prereq_chainORDER  BY depth, prereq_code;

Векторный поиск похожих курсов:

SELECT c.code,       c.title,       VEC_Distance(ref.embedding, c.embedding) AS distanceFROM   courses refJOIN   courses c ON c.course_id <> ref.course_idWHERE  ref.code = 'CS101'ORDER  BY distanceLIMIT  5;

Попробуйте прямо сейчас

Устанавливать ничего не нужно.

Запустить запросы к University DB можно прямо в браузере на sqlize.online — онлайн-редакторе SQL с поддержкой MariaDB 11.7. Скопируйте любой запрос из примеров и получите результат мгновенно.

Для структурированной практики с заданиями и проверкой ответов — sqltest.online.


Установка

Весь проект доступен под лицензией MIT:

👉 github.com/rozhnev/university-db

Что входит в репозиторий:

  • 01_schema.sql — DDL всех 16 таблиц

  • 02_objects.sql — представления, процедуры, триггеры

  • 03_seed_small.sql — статические справочные данные

  • generate_data.py — Python-скрипт на Faker, генерирует ~130 000 строк

  • docker-compose.yml — одна команда для запуска

  • queries/level1.sqllevel4.sql — 50+ примеров запросов

git clone https://github.com/rozhnev/university-db.gitcd university-dbcp .env.example .env# Отредактируйте .env - задайте паролиdocker compose up --build

После старта MariaDB схема и справочные данные загрузятся автоматически, затем запустится генератор данных и заполнит транзакционные таблицы.


Как поучаствовать в проекте

Проект открытый, и любой вклад приветствуется. Вот что можно сделать:

Сообщить о проблеме — нашли ошибку в схеме, некорректный запрос или опечатку в комментарии? Откройте issue на GitHub. Чем конкретнее описание, тем быстрее разберёмся.

Предложить новый пример запроса — если вы написали интересный запрос к этой схеме и хотите поделиться, присылайте pull request в queries/. Особенно ценны примеры для уровней 3–4.

Улучшить генератор данныхgenerate_data.py намеренно оставлен простым. Можно сделать более реалистичные распределения оценок, добавить новые сценарии, ускорить генерацию через bulk-вставки.

Добавить скрипты для других инструментов — есть готовый Docker Compose, но можно добавить поддержку Kubernetes, Helm-чарт или скрипт для облачных managed-сервисов (RDS, Cloud SQL).

Перевести примеры запросов — комментарии в SQL-файлах сейчас только на английском; если хотите добавить комментарии на другом языке — welcome.

Написать учебные материалы — задачи с решениями, воркшопы, jupyter-ноутбуки — всё, что помогает изучать SQL на этой схеме.

Для начала достаточно сделать fork репозитория и отправить pull request. Код ревью проводится в течение нескольких дней.


Sakila мертва?

Нет. Это по-прежнему рабочая база для изучения базового SQL, а её портируемость на любой MySQL 5.x — настоящее преимущество. Но как основной обучающий инструмент для современной MariaDB она устарела.

University DB закрывает этот пробел — для всех, кто хочет преподавать или изучать SQL на полную мощь MariaDB 11.7: от первого SELECT до векторного поиска внутри рекурсивного CTE внутри хранимой процедуры.

Буду рад фидбеку, вопросам и pull request’ам.


Слава Рожнев — sqlize.online · sqltest.online · GitHub

ссылка на оригинал статьи https://habr.com/ru/articles/1052504/