SQL Portal | Базы Данных
14.5K subscribers
581 photos
77 videos
41 files
490 links
Присоединяйтесь к нашему каналу и погрузитесь в мир баз данных

Связь: @devmangx

РКН: https://clck.ru/3H4Wo3
Download Telegram
Задача:
При работе с базой данных ритейл-клиента Accenture ты замечаешь, что в столбце category таблицы products есть NULL-значения.

Твоя задача — написать запрос, который вернёт таблицу products с заполненными значениями category.
Предполагается, что у первого продукта каждой категории всегда указана категория.

Таблица products:

🔸product_id

🔸category

🔸name

Объяснение:
Используем рекурсивный CTE с именем filled — это удобно, когда значение каждой строки зависит от предыдущей.

-- Базовый случай:
-- выбираем первую строку (product_id = 1), у которой уже есть категория (например, 'Shoes')
-- это стартовая точка рекурсии

-- Рекурсивный шаг:
-- для каждой следующей строки (product_id + 1):
-- если p.category НЕ NULL → берём её
-- иначе → подхватываем f.category из предыдущей строки

-- Всё это реализуется через COALESCE() — он возвращает первое непустое значение

В рекурсивном CTE базовый случай исполняется один раз,
а рекурсивная часть повторяется до тех пор, пока не перестают возвращаться новые строки.

Q) Почему ты написал ON p.product_id = f.product_id + 1?
A) Я хотел симулировать поведение forward fill — проход по строкам в порядке ID, строка за строкой.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75🔥3
Теперь в Oracle Database появился сервер Model Context Protocol (MCP), доступный через Oracle SQLcl.

С его помощью ты можешь безопасно подключаться к базе данных и взаимодействовать с ней через любой клиент с поддержкой MCP — включая твоего любимого AI-ассистента и LLM.

> подробнее

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
9
This media is not supported in your browser
VIEW IN TELEGRAM
Сгенерированные столбцы в Postgres — это специальные столбцы в таблице, которые автоматически рассчитывают свои значения на основе других столбцов той же строки.

Напрямую вставлять данные в такие столбцы через INSERT или изменять через UPDATE нельзя — Postgres сам отвечает за генерацию значений. Они задаются с помощью синтаксиса GENERATED ALWAYS AS (...). Ключевое слово STORED означает, что значение вычисляется при записи строки и сохраняется на диск — так же, как и обычные столбцы.

А зачем вообще нужны сгенерированные столбцы?

➜ Удобная агрегация данных: можно автоматически формировать, например, full_name, объединяя first_name и last_name. Больше не нужно каждый раз писать конкатенацию в запросах!

full_name TEXT GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED


➜ Упрощение запросов: можно заранее посчитать сложные выражения. Например, сохранить цену с учётом налога (price * 1.07), чтобы не дублировать вычисления в каждом SELECT. Чисто и лаконично!

➜ Нормализация данных: можно хранить нормализованную версию данных для удобства поиска и индексации. Частый кейс — сохранение email'а в нижнем регистре для регистронезависимого поиска.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
8🔥2👍1
Узнайте, как и зачем использовать транзакции в Postgres, в этои интерактивном браузерном туториале:

https://www.crunchydata.com/developers/playground/transactions

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Уровни изоляции транзакций в Postgres

Уровни изоляции транзакций в Postgres определяют, как база данных обрабатывает одновременное выполнение нескольких транзакций.

В Postgres доступны четыре стандартных SQL-уровня изоляции:

🔸Read Uncommitted
Read Uncommitted позволяет запросам видеть изменения, сделанные в транзакциях, которые ещё не были зафиксированы (committed).
Хотя этот уровень присутствует в синтаксисе Postgres ради соответствия SQL-стандарту, фактически он не реализован.
В Postgres нельзя выполнить грязное чтение (dirty read).

🔸Read Committed
Это уровень изоляции по умолчанию в Postgres.
Транзакция видит только те данные, которые были зафиксированы до её начала.
Это стандарт для веб-приложений, CMS и типичных OLTP-нагрузок (Online Transaction Processing), где допустимы незначительные расхождения
(например, когда данные изменяются между двумя SELECT-запросами внутри одной и той же транзакции).

Пример:
Пользователь загружает дашборд — запросы, наполняющие разные виджеты на странице, не обязаны отображать строго одну и ту же "точку во времени".

Этот уровень даёт хороший баланс между производительностью и согласованностью данных в большинстве сценариев.

🔸Repeatable Read
Этот уровень гарантирует, что повторный запуск одного и того же SELECT-запроса в рамках одной транзакции всегда вернёт один и тот же результат.
Он исключает *неповторяемые чтения* (non-repeatable reads).

Подходит для многошаговых транзакций, где важна согласованность в рамках всей транзакции.

Пример:
Генерация финансового отчета — сначала запрашиваются балансы счетов, затем идут запросы по транзакционной истории тех же счетов.
Все данные должны быть согласованы с тем состоянием, в котором считались балансы, даже если в это время в системе происходят другие изменения.

🔸Serializable
Самый строгий и безопасный уровень изоляции.
Обеспечивает поведение транзакций как если бы они выполнялись последовательно, а не параллельно.

Подходит для критичных операций, где целостность данных важнее всего и необходимо исключить любые race conditions.

Примеры:
- Системы бронирования (например, исключение двойного бронирования места в самолете или гостиничного номера)
- Сложные финансовые операции, где перевод средств между счетами требует согласованности всех промежуточных шагов

Приложение должно быть готово к повторной попытке транзакций, завершившихся ошибкой сериализации.

Как задать уровень изоляции

Уровень изоляции можно задать на следующих уровнях:

1. По умолчанию для всей базы данных
2. Для отдельной сессии
3. Для конкретной транзакции (в момент BEGIN)

Во многих приложениях принято устанавливать дефолтный уровень изоляции для базы,
а для отдельных операций (например, финансовых транзакций) — использовать повышенный уровень изоляции.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥4👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Нашёл штуку, которая делает PostgreSQL понятным даже для чайников 🙂

Это визуальная надстройка над Postgres, которая превращает его в нечто среднее между Airtable и Excel. Таблицы, связи, формы — всё редактируется прямо в браузере, без SQL.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯105👍5
This media is not supported in your browser
VIEW IN TELEGRAM
В обновляемые представления можно вставлять строки

...но при этом возможно добавить данные, противоречащие условию WHERE

Из-за этого кажется, что значения просто исчезают!

Чтобы этого избежать, добавь:

CREATE VIEW ... AS SELECT ... WHERE ...
WITH CHECK OPTION


Тогда вставлять можно будет только те строки, которые соответствуют условию WHERE

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
9
This media is not supported in your browser
VIEW IN TELEGRAM
Ещё один отличный тренажёр для изучения SQL — SQL Teaching

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

Бесплатно и опенсорс. Забираем здесь 😊

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥105👍5
Когда стоит сбрасывать pg_stat_statements?

🔸В начале нового периода мониторинга
Если ты анализируешь производительность на ежедневной, недельной или месячной основе, имеет смысл сбрасывать pg_stat_statements в начале каждого периода. Это позволяет собирать метрики с «чистого листа» и получать более точную аналитику за конкретный интервал.

🔸После внесения значимых изменений в запросы
Если в приложении были переработаны запросы, оптимизирована логика или изменены индексы, сброс pg_stat_statements помогает точнее отследить влияние этих изменений. Это также исключает устаревшие запросы, которые могут исказить результаты.

🔸Во время бенчмарков и тестирования производительности
Если ты запускаешь тесты производительности или сравниваешь эффективность разных вариантов запросов, сброс pg_stat_statements гарантирует, что собираемая статистика будет относиться только к выполненным в рамках теста запросам.

🔸После серьёзных операций по обслуживанию базы
После таких операций, как pg_repack, переиндексация или изменение структуры таблиц, сброс pg_stat_statements позволяет объективно оценить, как они повлияли на производительность.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍1🔥1
Пользователи часто хотят получать отчёты из базы данных, адаптированные под их нужды; запросы на такую кастомизацию могут со временем превратить систему в нечто вроде

SQL-инъекции как сервис


Товарищ рассказывает историю одной такой системы, где в итоге один из пользователей удалил критичные данные:

https://idiallo.com/blog/sql-injection-as-a-feature

Берегите свои данные, коллеги! 🐒

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Подготовленные выражения / параметризованные запросы в Postgres

Подготовленные выражения — это повторно используемые SQL-запросы, которые позволяют обойти стадию планирования, повторно используя уже построенный план выполнения и подставляя разные данные.

Полноценный SQL-запрос в Postgres проходит через следующие этапы:

- Парсинг — преобразование в внутреннее представление;
- Переписывание / трансформация — применение правил переписывания запроса, создание внутренних представлений (например, CTE или view);
- Планирование — планировщик Postgres использует статистику по таблицам и другую информацию, чтобы выбрать оптимальный план выполнения;
- Выполнение — непосредственный запуск запроса.

Подготовленные выражения используют тот же SQL и сохраняют первые три шага. Это значит, что при выполнении остаётся только извлечь данные — Postgres может полностью пропустить стадию планирования.

Пример

Подготовить запрос и сохранить план выполнения

PREPARE get_user_by_email (text) AS
SELECT * FROM users WHERE email = $1;


Выполнить с одним параметром

EXECUTE get_user_by_email('alice@test.com');


Выполнить с другим параметром

EXECUTE get_user_by_email('bob@test.com');


Освободить ресурсы

DEALLOCATE get_user_by_email;


ORM'ы часто работают с подготовленными выражениями, и это может значительно повысить производительность приложений. Со стороны приложения такие запросы обычно называют параметризованными. Параметризованный запрос содержит плейсхолдеры, которые заполняются значениями позже. Такой запрос на стороне БД превращается в подготовленное выражение.

Примеры в коде

В Rails:

User.where("email = ?", "alice@test.com")


В Python:

cur.execute("SELECT * FROM users WHERE email = %s", ("alice@test.com",))


👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
8
Изучаем базы данных

Дорожная карта, которая поможет глубже разобраться в мире СУБД

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Новичок в использовании pg_stat_statements для анализа производительности запросов в Postgres?

Попробуй этот простой веб-учебник:
https://crunchydata.com/developers/playground/query-performance-analytics

💡Там есть пара отличных запросов, которые стоит сохранить для дальнейшего использования.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Новая фича в PostgreSQL 17 — геймчейнджер

Эта новая возможность в PostgreSQL 17 настоящая революция.

🔸Механика страниц в PostgreSQL

PostgreSQL, как и большинство СУБД, работает с страницами фиксированного размера.
Практически всё — таблицы, индексы и т.д. хранится в виде страниц размером 8 КБ.

Каждая страница содержит:
- строки таблицы или кортежи индекса
- фиксированный заголовок

Страницы это просто байты в файлах. Они читаются и кэшируются в буферном пуле

Примеры чтения страниц:
- Страница 0: read(offset=0, size=8192)
- Страница 1: read(offset=8193, size=8192)
- Страница 7: read(offset=57345, size=8192)

Если таблица занимает 100 страниц, то для full table scan придётся выполнить 100 системных вызовов.
А каждый системный вызов имеет накладные расходы.

🔸Что изменилось в Postgres 17

Добавили возможность объединения I/O:
- Можно указать, сколько страниц читать за один системный вызов
- Теоретически можно просканировать всю таблицу за один системный вызов

Это не всегда хорошая идея, подробнее об этом ниже.

Также добавили поддержку векторизованного I/O:
- Используется системный вызов preadv
- Он принимает массив оффсетов и длин — удобно для произвольного чтения

🔸Проблема: не читать лишнего

Допустим, мы делаем seq scan, чтобы найти значение:
1. Читаем страницу 0
2. Находим нужное → выходим
3. Остальные страницы не нужны

Теперь с новой фичей:
- Мы читаем сразу 10 страниц одним I/O
- Загружаем всё в shared buffers
- А нужное было уже на первой странице

> Результат — потрачены ресурсы (диск, память) впустую

🔸Как это сбалансировать

Нужно будет находить баланс:
- Между эффективным I/O
- И избежанием избыточного чтения

🔸Примечание

PostgreSQL действительно вызывает системный вызов ядра, чтобы читать по 8 КБ за раз.
Но ядро может быть настроено на read-ahead — заранее читать больше и кэшировать это в файловом кэше ОС.

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63
Media is too big
VIEW IN TELEGRAM
Интерактивная тренировка SQL

Если хочешь прокачать SQL на практике без установки СУБД и настройки окружения заходи на sqltest.online

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
6🔥5🌭3
Все надоело и пропал интерес, чувствуешь себя амебой и хочется только залипать в телефоне. Бывает?

Психолог взрослого человека — канал для айтишников, у которых периодически опускаются руки и отключается мозг, ибо переработки и постоянная тревожность не приводят к другим исходам 🤗

✓ Как научиться отвлекаться от работы и отдыхать?
✓ Как совместить кучу рабочих задач и время с семьей?
✓ Как справиться с прокрастинацией?
✓ Как не растерять запал, даже если начальник и коллеги 💩 и кажется, что ничего не выходит?

Подписывайтесь на канал @vadimpetrovpsi и научитесь работать без упахивания, выгорания и ущерба для личной жизни!

Псс. Заходите в закреп — там много полезного, и даже бесплатный мини-курс по выходу из апатии:
👉 https://t.me/+k0OmqMJdwsAxMDM6
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41👍1
Amazon Aurora стала первой OLTP базой данных, которая популяризировала разделение хранения данных и вычислительных ресурсов.

Главным новшеством стала переработка слоя хранения с целью минимизировать операции записи (write I/O) для преодоления задержек, связанных с сетью.

Как бы круто это ни было, она всё же не может превзойти локальные NVMe SSD.

Ссылка на статью:
https://pages.cs.wisc.edu/~yxy/cs764-f20/papers/aurora-sigmod-17.pdf

На видео показана PlanetScale Metal на AWS против Aurora. Те же CPU и объем памяти при I/O-насыщенной нагрузке, похожей на TPCC.

Значительно выше QPS при при этом в 3 раза ниже p99 задержка

👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
5
This media is not supported in your browser
VIEW IN TELEGRAM
База данных имеет право выполнять части SQL-выражения WHERE в любом порядке.

Так как же избежать ошибок, если известно, что выражение может выбросить ошибку,

например, извлечение квадратного корня из отрицательного числа?

Используй CASE, чтобы выполнять вычисление только для допустимых значений:

WHERE CASE 
WHEN col > 0 THEN SQRT(col)
ELSE ...
END ...


👉 @SQLPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍74🔥4
🥇 Пройди ЛЮБОЕ собеседование!

Большая база вопросов с реальных собеседований:

Тинькофф, Авито, Сбер, Озон, Яндекс, VK и еще 100+ компаний

20+ направлений: Frontend, Backend, DevOps, QA, Mobile и другие

60+ технологий: React, Python, Docker, Git, Java, Go, JavaScript и не только

Выбирай направление:

👩‍💻 C# 🤖 ML Engineer

👩‍💻 C/C++ 🖥 Data Science

👩‍💻 Java 👩‍💻 Python

🖥 PHP 👩‍💻 Frontend

👣 Rust 👣 Golang

👩‍💻 Node.js 💻 DevOps

👩‍💻 QA 👩‍💻 Android

👩‍💻 iOS 👩‍💻 Game Dev

🖥 Общее IT 👨‍💻 Вакансии

База обновляется еженедельно — всегда актуальные вопросы с последних собеседований.

💸 Хочешь оффер в Big Tech? Готовься с нами!
Please open Telegram to view this post
VIEW IN TELEGRAM