Здесь самостоятельные задания с учебными данными. Сначала сделайте свою попытку, затем проверьте крайние случаи и откройте подсказку. Время — ориентир; для проекта учитывайте отдельное время на тесты и оформление.
Как выбрать практику · Карта промахов
Прокрутите таблицу по горизонтали →
| Задание | Этап | Ориентир |
|---|---|---|
| Пропуски в номерах кухонных талонов | SQL и PostgreSQL | 30 мин |
| История цен меню | SQL и PostgreSQL | 45 мин |
| Свободные места по залам | SQL и PostgreSQL | 35 мин |
| Последние брони со стабильным курсором | SQL и PostgreSQL | 45 мин |
Пропуски в номерах кухонных талонов
В таблице ticket_events(event_id, ticket_no) лежат номера талонов: 201, 202, 202, 204, 207. Найдите все отсутствующие номера в явно заданном включительном диапазоне 201…207, отсортируйте по возрастанию. Результат: 203, 205, 206. Повторный талон не должен создавать ложный пропуск. Числа вне диапазона игнорируются; при пустой таблице верните весь диапазон. Напишите один SQL-запрос для PostgreSQL.
Проверка результата
- Проверены пропуски в начале, конце и подряд.
- Для 201…201 результат зависит только от наличия 201.
- Объяснено, почему MIN/MAX таблицы не заменяют границы из условия.
Подсказка — после своей попытки
Сравните ожидаемый набор номеров с существующими, учитывая дубликаты.
Усложнение: Верните интервалы пропусков и сравните стоимость запроса для диапазона в миллион номеров.
История цен меню
Спроектируйте dishes и историю цен по филиалам. Для блюда в филиале цена в копейках действует в интервале [valid_from, valid_to); конец может быть NULL. Цена неотрицательна. Исторические записи сохраняются после архивирования блюда. Две цены одной пары «блюдо, филиал» не могут действовать в один момент. Напишите DDL, запрос цены на заданный момент и способ изменения цены без разрыва истории. Объясните защиту от двух одновременных изменений.
Проверка результата
- Ссылка на несуществующее блюдо и отрицательная цена отклоняются БД.
- На общей границе интервалов выбирается ровно новая цена.
- В тесте двух транзакций не появляются два одновременно действующих интервала.
Подсказка — после своей попытки
Обычный UNIQUE по началу интервала не запрещает перекрытие интервалов.
Усложнение: Добавьте валюту и запрет смешивания валют в одной истории.
Свободные места по залам
Есть rooms(id, capacity) и reservations(id, room_id, guests, status). Залы: (1, 12), (2, 4), (3, 3), (4, 6). Брони: зал 1 — confirmed на 4 и 3 гостя; зал 2 — cancelled на 3; зал 3 — confirmed на 3. Выведите все залы и свободные места, учитывая только confirmed. Сортировка: свободные места по убыванию, затем id по возрастанию. Результат: (4,6), (1,5), (2,4), (3,0). Не скрывайте отрицательный остаток: он нужен для диагностики данных.
Проверка результата
- Зал без броней остаётся в результате.
- Отменённая бронь не занимает места и не исключает зал.
- Добавление таблицы гостей не должно случайно умножать суммы броней.
Подсказка — после своей попытки
При LEFT JOIN положение фильтра по статусу влияет на сохранение пустых залов.
Усложнение: Сравните точный запрос к основной базе и кэшированный отчёт с допустимой задержкой 30 секунд.
Последние брони со стабильным курсором
Таблица reservations(id, restaurant_id, created_at, status) содержит 20 млн строк. Нужны последние 25 confirmed-бронирований одного ресторана: порядок (created_at DESC, id DESC). Предложите запрос первой и следующей страницы, индекс и план измерений. Курсор содержит оба поля последней строки. Рассмотрите одинаковые timestamps, вставку новой брони между запросами и изменение статуса старой записи. Гарантировать один неизменный снимок между отдельными HTTP-запросами не требуется.
Проверка результата
- При равных timestamps порядок стабилен благодаря id.
- Следующая страница не повторяет последнюю строку предыдущей.
- Индекс обоснован фильтрами и сортировкой; приведены фактические строки, время и буферы плана.
Подсказка — после своей попытки
Курсор одной даты теряет строки с такой же датой.
Усложнение: Опишите контракт отчёта, если пользователю нужен фиксированный снимок на все страницы.