SQL и транзакции
Аналитик редко пишет прод-запросы, но постоянно рассуждает о данных: читает требование и должен сразу видеть, JOIN это или подзапрос, нужен отчёту WHERE или HAVING, безопасно ли повторить запись. А за одиночным запросом стоит конкурентность: как только два пользователя касаются одной строки, корректность держится на транзакциях и уровнях изоляции. Эта тема даёт обе половины — сам язык запросов и гарантии, которые лежат под ним.
Заранее назовём ловушки, на которых спотыкаются на собеседовании: LEFT JOIN путают с INNER, агрегат пытаются фильтровать в WHERE, x = NULL считают проверкой на равенство, NOT IN ломается на NULL в подзапросе, SERIALIZABLE считают всегда правильным выбором, а 2PC — бесплатной атомарностью. Каждая из них — типичный провал. Полная карта — в двух слоях ниже.
Карта темы
- SQL для аналитика — виды
JOIN,GROUP BYс агрегатами иHAVING, подзапросы против CTE, нормализация против денормализации, ключи и ограничения, семантикаNULL, индексы и превращение требования в корректный запрос. - Транзакции и конкурентность — ACID, уровни изоляции и допускаемые каждым аномалии, блокировки (оптимистичные и пессимистичные), deadlock, MVCC, вред долгой транзакции и сложность распределённых транзакций с альтернативой saga.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Считать, что LEFT JOIN и INNER JOIN дают один результат | Молча теряются несопоставленные строки, отчёт занижает данные |
Фильтровать агрегат SUM(x) в WHERE | Ошибка: WHERE выполняется до группировки, условие идёт в HAVING |
Проверять x = NULL вместо x IS NULL | Сравнение даёт UNKNOWN, строка молча не проходит фильтр |
Считать SERIALIZABLE всегда правильным выбором | Падает пропускная способность и растёт число откатов на конфликтах |
Ждать, что READ COMMITTED защитит от неповторяющегося чтения | Повторный SELECT в одной транзакции вернёт другие данные |
Считать 2PC бесплатной атомарностью между сервисами | Блокировки по сети и зависание при падении координатора |
Значение для собеседований
Тему спрашивают, чтобы проверить, умеете ли вы перевести требование в корректный запрос и рассуждать о том, что происходит при одновременном доступе. Кандидат, который объясняет LEFT JOIN через «сохраняет все левые строки, подставляя NULL без совпадения», и уровень изоляции через «какую аномалию он ещё допускает», сразу опережает того, кто помнит лишь список ключевых слов.
Что обычно проверяют:
- Разницу
INNER/LEFT/RIGHT/FULLи когда какой корректен;WHEREпротивHAVING. - Семантику
NULL(трёхзначная логика) и почемуCOUNT(col)пропускаетNULL. - ACID и что означает каждая буква, особенно изоляция.
- Какую аномалию допускает каждый уровень изоляции и чем
SERIALIZABLEотличается отREPEATABLE READ. - Оптимистичную и пессимистичную блокировку, deadlock и идею MVCC.
- Почему распределённая транзакция сложна и когда предпочесть saga.
Типичный неверный ответ: «просто ставьте SERIALIZABLE и все проблемы конкурентности исчезнут». На деле высший уровень изоляции дорого стоит по пропускной способности и порождает откаты на конфликтах сериализации; грамотный выбор — минимальный уровень, который исключает аномалию, реально опасную для конкретного сценария.