Квиз: Погружение в Postgres. Часть 2
Вы SQL-кремень? Или SQL-слабак?
Часть 2 из 2. Назад к части 1
Добро пожаловать во вторую часть моего глубокого квиза по PostgreSQL!
Этот квиз охватывает смесь знакомых и малоизвестных фич и нюансов PostgreSQL: JOIN, NULL, ANSI SQL, транзакции, внутреннее устройство, индексация, выборка данных… и не только!
Удачи! 🍀
Какое из выражений НЕ является ❌ валидным типом JOIN в PostgreSQL?
Вы ведь знали про CROSS JOIN, верно?
Возможно, JOIN ALL заставил вас задуматься о другой операции — UNION ALL?
Правильный ответ здесь — JOIN ALL ❌.
Корректные типы JOIN это:
INNER JOIN(JOIN по умолчанию)LEFT JOIN(илиLEFT OUTER JOIN)RIGHT JOIN(илиRIGHT OUTER JOIN)FULL JOIN(илиFULL OUTER JOIN)CROSS JOIN(декартово произведение, если только оно не фильтруется последующим предложениемWHERE)
За исключением варианта «Зависит от побочных эффектов», что происходит после возникновения ошибки?
BEGIN;UPDATE students SET status = 'alumni' WHERE grade = 12;UPDATE students SET graduation_date = CURRENT_DATE WHERE grade = 12;UPDATE students SET grade = 'GRADUATED'; -- 🚨 Error: type mismatchCOMMIT;Когда здесь возникает ошибка:
- Вся транзакция откатывается
- Никакие изменения не фиксируются
- Транзакция помечается как неудавшаяся
Для частичной фиксации:
BEGIN;UPDATE ...;SAVEPOINT my_save;UPDATE ...; -- ErrorROLLBACK TO my_save;COMMIT;Какое условие ON PostgreSQL может использовать для выполнения HASH JOIN?
SELECT *FROM students aJOIN grades bON /* What goes here? ⁉ */;Hash join возможен только при наличии условия равенства (=) в предложении ON.
=— это основной предикат для хеш-соединений>и>=не являются предикатами для hash joinHASH JOINне является валидным синтаксисом в PostgreSQL
Планировщик все равно может выбрать nested loop или merge join в зависимости от размера таблиц, статистики, индексов и настроек памяти.
Как указать имя столбца, содержащее точку?
CREATE TABLE teachers ( id INT GENERATED BY DEFAULT AS IDENTITY, first.name TEXT, -- How do you include the column: first.name? salary NUMERIC);PostgreSQL использует двойные кавычки для экранирования идентификаторов:
- Двойные кавычки
"..."для идентификаторов (имена столбцов, таблиц) - Одинарные кавычки
'...'для строковых литералов - Запись
first.nameинтерпретируется какимя_таблицы.имя_столбца
Без кавычек точка в имени столбца будет воспринята как разделитель схемы или таблицы! Кроме того, все идентификаторы без кавычек по умолчанию приводятся к нижнему регистру.
Чтобы избежать сюрпризов, лучше использовать snake_case и не применять специальные символы.
Какой синтаксис является допустимым для случайной выборки 10% студентов?
Этот вопрос с подвохом! Здесь расставлено около 6 ловушек, вот некоторые из них:
- Описание высокого уровня + фрагменты синтаксиса. Проверяет, как вы адаптируете и собираете неполную информацию.
- Требуется хорошее знание синтаксиса
TABLESAMPLE, так как ни один из вариантов сTABLESAMPLEне использует правильный синтаксис! (Коварно, я знаю! Продолжайте, я в вас верю!!! ❤️) - Варианты
ROW_NUMBER() OVER (ORDER BY RAND())иORDER BY RANDOM() > 10— это отвлекающие маневры. Они выглядят похожими на правду, но это не так. ФункцииRAND()не существует. АRANDOM() > 10— это логическое выражение, которое всегда будет ложным, так какRANDOM()всегда возвращает значение в диапазоне0.0-1.0. Еще одна проблема:ORDER BY RANDOM() > 10будет выполнять сортировку по логическому значению, а не по случайному числу. Но это> 10выглядело так, будто это проценты, верно? BERNOULLI— это валидный метод, однакоSAMPLETABLE— нет.WHERE RANDOM() >= 0.1— это ловушка!RANDOM()возвращает значение в диапазоне0.0 <= x < 1.0, поэтому>= 0.1вернет около 90% строк, а не 10%.
Что касается метода TABLESAMPLE, PostgreSQL поддерживает два метода выборки:
BERNOULLI: Каждая строка имеет равную вероятность попадания в выборку.SYSTEM: Выборка на уровне блоков (быстрее, но менее случайно).
Чтобы узнать больше о выборках, ознакомьтесь с этой статьей от Render.
Пример:
-- Sample 10% of rowsSELECT * FROM students TABLESAMPLE BERNOULLI (10);
-- For repeatable results, use REPEATABLE:SELECT * FROM studentsTABLESAMPLE BERNOULLI (10) REPEATABLE (42);Также стоит упомянуть, что сообщалось, что TABLESAMPLE не всегда обеспечивает высокую степень случайности. Если вам нужна более случайная выборка фиксированного размера, рассмотрите использование ORDER BY RANDOM() LIMIT 10. Но имейте в виду, что это вернет 10 строк, а не 10%, и может работать медленно на больших таблицах.
Существуют также сторонние расширения, предоставляющие лучшие методы случайной выборки, но это выходит за рамки данного вопроса! 😅
Что делает EXPLAIN ANALYZE для операторов UPDATE?
EXPLAIN ANALYZEUPDATE studentsSET grade = grade + 1WHERE status = 'active';EXPLAIN ANALYZE на самом деле выполняет запрос! Будьте осторожны при анализе операций записи, а именно операторов UPDATE, DELETE и INSERT. Возможно, вам придется выполнять операции очистки после каждого EXPLAIN ANALYZE, чтобы получить повторяемые результаты.
Лучшие практики:
- Используйте
EXPLAIN(без ANALYZE) для UPDATE/DELETE/INSERT - Оборачивайте модификации в транзакции:
BEGIN;EXPLAIN ANALYZE ...;ROLLBACK;Отлично! Вы глубоко погрузились в нюансы PostgreSQL! 🐘
Надеюсь, вы узнали что-то новое или хотя бы набрали достаточно баллов, чтобы было чем похвастаться! 🏆
Хочется еще? Загляните в мою коллекцию квизов за порцией бесконечного* веселья!
