Например, разработчик пишет запрос начиная с
SELECT, но SQL-движок выполняет его иначе: сначала формирует источник данных через FROM, объединяет таблицы через JOIN, фильтрует записи через WHERE, группирует данные через GROUP BY и только после этого формирует итоговый результат.На картинке — логический порядок выполнения SQL-операций.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤8🔥7
Почему JSONB в PostgreSQL не всегда быстрее JSON!
В PostgreSQL тип
Рассмотрим таблицу с JSONB-структурой:
Добавим документ с вложенными данными:
При хранении
Оператор
Для ускорения подобных запросов используется GIN-индекс:
После создания индекса PostgreSQL может выполнять поиск внутри JSONB-структуры без полного последовательного просмотра всех строк. Но у
При изменении одного поля PostgreSQL не изменяет отдельный элемент внутри JSONB-документа. Из-за механизма MVCC создаётся новая версия строки с новым значением
Для небольших объектов это обычно не оказывает заметного влияния. Но большие JSONB-документы с частыми обновлениями могут увеличивать нагрузку на операции записи из-за необходимости создавать новые версии данных.
Ещё одно отличие связано с сохранением структуры документа. В типе
В этом случае исходный порядок ключей сохраняется.
В JSONB порядок ключей не сохраняется, поскольку PostgreSQL работает с внутренним структурированным представлением данных. Поэтому он лучше подходит для случаев, когда требуется поиск, индексация и работа с содержимым документа, а JSON — когда важно сохранить исходное представление данных.
Отдельно стоит учитывать особенности работы индексов. Например, запрос с извлечением значения через оператор
А запрос с проверкой содержимого JSONB-объекта использует другой механизм доступа:
GIN-индекс эффективно работает с операторами
Однако GIN-индекс не ускоряет автоматически любые выражения с извлечением значений через
Например, индекс для конкретного поля
Если поле активно используется в фильтрации, сортировке или связях между таблицами, отдельная колонка часто будет эффективнее и проще для поддержки.
🔥
➡️ SQL Ready | #практика
В PostgreSQL тип
JSONB часто выбирают вместо JSON из-за возможности индексации и работы с операторами поиска. Но отличие между ними не только в скорости чтения — оно связано с тем, как PostgreSQL хранит, обрабатывает и изменяет данные.Рассмотрим таблицу с JSONB-структурой:
CREATE TABLE events (
id SERIAL PRIMARY KEY,
payload JSONB
);
Добавим документ с вложенными данными:
INSERT INTO events (payload)
VALUES (
'{
"user": {
"id": 100,
"role": "admin"
},
"active": true
}'
);
При хранении
JSONB PostgreSQL разбирает документ и сохраняет его во внутреннем бинарном представлении. Благодаря этому можно выполнять поиск по содержимому документа:SELECT *
FROM events
WHERE payload @> '{"active": true}';
Оператор
@> проверяет наличие указанного фрагмента внутри JSONB-объекта.Для ускорения подобных запросов используется GIN-индекс:
CREATE INDEX idx_events_payload
ON events
USING GIN (payload);
После создания индекса PostgreSQL может выполнять поиск внутри JSONB-структуры без полного последовательного просмотра всех строк. Но у
JSONB есть особенности, которые важно учитывать.При изменении одного поля PostgreSQL не изменяет отдельный элемент внутри JSONB-документа. Из-за механизма MVCC создаётся новая версия строки с новым значением
JSONB:UPDATE events
SET payload = jsonb_set(
payload,
'{user,role}',
'"moderator"'
)
WHERE id = 1;
Для небольших объектов это обычно не оказывает заметного влияния. Но большие JSONB-документы с частыми обновлениями могут увеличивать нагрузку на операции записи из-за необходимости создавать новые версии данных.
Ещё одно отличие связано с сохранением структуры документа. В типе
JSON PostgreSQL сохраняет текстовое представление документа:SELECT '{"b":2,"a":1}'::json;
В этом случае исходный порядок ключей сохраняется.
JSONB хранит уже разобранную структуру документа:SELECT '{"b":2,"a":1}'::jsonb;
В JSONB порядок ключей не сохраняется, поскольку PostgreSQL работает с внутренним структурированным представлением данных. Поэтому он лучше подходит для случаев, когда требуется поиск, индексация и работа с содержимым документа, а JSON — когда важно сохранить исходное представление данных.
Отдельно стоит учитывать особенности работы индексов. Например, запрос с извлечением значения через оператор
->> выглядит следующим образом:SELECT *
FROM events
WHERE payload->>'active' = 'true';
А запрос с проверкой содержимого JSONB-объекта использует другой механизм доступа:
SELECT *
FROM events
WHERE payload @> '{"active": true}';
GIN-индекс эффективно работает с операторами
JSONB, такими как проверка вхождения @>, проверка существования ключей ?, а также операторы проверки нескольких ключей ?| и ?&.Однако GIN-индекс не ускоряет автоматически любые выражения с извлечением значений через
->>. Для таких случаев могут использоваться отдельные функциональные индексы.Например, индекс для конкретного поля
JSONB можно создать следующим образом:CREATE INDEX idx_events_active
ON events ((payload->>'active'));
Если поле активно используется в фильтрации, сортировке или связях между таблицами, отдельная колонка часто будет эффективнее и проще для поддержки.
JSONB отлично подходит для хранения динамических структур, когда требуется гибкость схемы и возможность выполнять поиск по содержимому. Главное правило: JSONB — это инструмент для работы с полуструктурированными данными, а не способ заменить полноценную структуру реляционной базы данных.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🤝7🔥3
На картинке — путь изучения SQL: от основ устройства базы данных и типов данных до запросов, операторов, функций, транзакций и управления доступом.
Собраны основные темы, которые стоит пройти: структура базы данных и объекты, команды работы с данными (
DDL, DML, DQL, DCL, TCL), построение запросов, операторы, функции, типы данных и др.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤7👍6
Старые и новые значения в RETURNING!
До PostgreSQL 18
В PostgreSQL 18 старые и новые значения доступны прямо внутри
Это особенно удобно для журналирования изменений, аудита, API, которые сразу возвращают результат обновления, и любых сценариев, где нужно сравнить состояние строки до и после изменения.
Та же идея работает и для
🔥 Небольшое изменение PostgreSQL 18, которое избавляет от лишних
➡️ SQL Ready | #совет
До PostgreSQL 18
RETURNING не позволял получить одновременно старое и новое состояние строки. Если нужно было сравнить значения до и после UPDATE, приходилось писать CTE или выполнять дополнительный запрос.WITH old_data AS (
SELECT id, price
FROM products
WHERE category = 'books'
)
UPDATE products p
SET price = p.price * 1.1
FROM old_data o
WHERE p.id = o.id
RETURNING
o.price AS old_price,
p.price AS new_price;
В PostgreSQL 18 старые и новые значения доступны прямо внутри
RETURNING.UPDATE products
SET price = price * 1.1
WHERE category = 'books'
RETURNING
id,
old.price AS old_price,
new.price AS new_price;
Это особенно удобно для журналирования изменений, аудита, API, которые сразу возвращают результат обновления, и любых сценариев, где нужно сравнить состояние строки до и после изменения.
DELETE FROM products
WHERE discontinued
RETURNING
old.id,
old.name,
old.price;
Та же идея работает и для
DELETE: старое состояние строки доступно напрямую через old.CTE и делает RETURNING заметно полезнее.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍10❤8
This media is not supported in your browser
VIEW IN TELEGRAM
Сайт посвящён изучению PostgreSQL и администрированию баз данных. Здесь собраны учебные материалы по установке и настройке PostgreSQL, работе с сервером, архитектуре СУБД, управлению пользователями, резервному копированию, репликации и другим задачам, с которыми сталкиваются DBA и backend-разработчики.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍6🤝4❤2
Разобраны способы объединения таблиц, получение связанных данных, поиск совпадающих и отсутствующих записей, а также использование
EXISTS и NOT EXISTS для проверки связей между таблицами.На картинке — основные типы JOIN в MySQL с примерами SQL-запросов и визуальным объяснением.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18❤7👍7
This media is not supported in your browser
VIEW IN TELEGRAM
Этот репозиторий содержит учебные материалы и практические задания по разработке высоконагруженных систем. Основной фокус — внутреннее устройство баз данных, распределённые системы, хранение данных, производительность и инженерные подходы, которые используются в реальных проектах.
Оставляю ссылочку: GitHub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤7🔥5
Разбираем почему REINDEX не заменяет VACUUM в PostgreSQL!
После большого количества операций
Создадим таблицу:
Добавим данные:
Удалим половину строк:
После выполнения
Для их обработки используется:
При этом обычный
Или сразу все индексы таблицы:
При этом
Важно понимать, что в большинстве случаев регулярное обслуживание выполняет
🔥 Главное отличие:
➡️ SQL Ready | #практика
После большого количества операций
UPDATE и DELETE в PostgreSQL часто используют команды VACUUM и REINDEX. Несмотря на то что обе относятся к обслуживанию базы данных, они решают разные задачи и не являются взаимозаменяемыми.Создадим таблицу:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT
);
Добавим данные:
INSERT INTO users (email)
SELECT 'user' || g || '@mail.com'
FROM generate_series(1, 100000) AS g;
Удалим половину строк:
DELETE
FROM users
WHERE id <= 50000;
После выполнения
DELETE строки не исчезают из файла таблицы сразу. PostgreSQL использует механизм MVCC, поэтому удалённые версии строк продолжают существовать до тех пор, пока они могут быть нужны активным транзакциям.Для их обработки используется:
VACUUM users;
VACUUM обрабатывает мёртвые версии строк, освобождая занимаемое ими пространство для повторного использования внутри таблицы. Кроме того, он может очищать соответствующие мёртвые записи в индексах. При этом обычный
VACUUM обычно не уменьшает размер файла таблицы на диске — освободившееся место остаётся внутри таблицы и используется последующими операциями INSERT и UPDATE. Теперь перестроим индекс:REINDEX INDEX users_pkey;
Или сразу все индексы таблицы:
REINDEX TABLE users;
REINDEX перестраивает индекс на основе актуальных данных таблицы. Эта команда применяется при значительном раздувании индексов, их повреждении, а также в ситуациях, когда анализ показывает, что перестроение может улучшить производительность.При этом
REINDEX не очищает таблицу от мёртвых версий строк и не заменяет выполнение VACUUM. Если же необходимо физически уменьшить размер таблицы и вернуть свободное место операционной системе, используется другая команда:VACUUM FULL users;
VACUUM FULL полностью переписывает таблицу в новый компактный файл, освобождает место на диске, но требует блокировку уровня ACCESS EXCLUSIVE, поэтому на время выполнения таблица становится недоступной для чтения и записи.Важно понимать, что в большинстве случаев регулярное обслуживание выполняет
autovacuum. Ручной запуск VACUUM, VACUUM FULL или REINDEX обычно является следствием анализа конкретной проблемы, а не стандартной процедурой после большого количества изменений данных.VACUUM обслуживает таблицу и связанные с ней индексы, освобождая пространство, занятое мёртвыми версиями строк, для повторного использования. REINDEX занимается исключительно перестроением индексов. Эти команды решают разные задачи и используются в разных ситуациях.Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍5🔥4🤝1
В этой статье:
• Разбираются реальные проблемы, которые DBA чаще всего находят при проверке PostgreSQL в продакшене;• Показывается, почему бэкапы могут оказаться бесполезными, а широкие права, открытый доступ и отсутствие логов создают серьезные риски;• Разбираются настройки производительности, долгие транзакции, BLOAT, автовакуум и архитектурные ошибки, которые могут привести к сбоям.Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍7🔥5😁1
От отправки запроса до результата SQL проходит несколько этапов: парсинг, оптимизация, построение плана выполнения, доступ к данным, кэширование и управление транзакциями.
На схеме — архитектура обработки SQL-запроса и основные компоненты базы данных.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤8🔥7🤝1
This media is not supported in your browser
VIEW IN TELEGRAM
На сайте собраны статьи и документация по работе с базами данных и SQL. Материалы помогают разобраться не только с написанием запросов, но и с тем, как работают внутренние механизмы СУБД: транзакции, индексы, оптимизация запросов, распределённые базы данных и эксплуатация систем.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13❤10👍7👎1
Разобраны основные элементы Git-экосистемы: структура репозитория, работа с индексом (staging area), создание коммитов, управление ветками, слияние изменений, взаимодействие с remote-репозиториями и основные команды для ежедневной разработки.
На картинке — визуальное представление Git workflow, жизненный цикл изменений от рабочей директории до удалённого репозитория, а также базовые операции
commit, branch, merge, fetch, pull и push.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13🔥9👍7
This media is not supported in your browser
VIEW IN TELEGRAM
Большая подборка учебных материалов по базам данных: книги, лекции, лабораторные работы и задания по SQL, PostgreSQL и Microsoft SQL Server. Внутри собраны материалы по ключевым темам, которые нужны разработчику при работе с базами данных: основы реляционной модели и проектирования БД, нормализация данных и ограничения (constraints), агрегатные функции, JOIN, подзапросы и др.
Оставляю ссылочку: GitHub
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13🔥10👍5
Сравнивайте несколько колонок как одно значение!
В PostgreSQL необязательно расписывать сравнение нескольких полей через длинные цепочки
Например, условие для
Но PostgreSQL умеет выразить то же самое напрямую:
Сравнение идёт слева направо: сначала
И это не просто сокращение синтаксиса. Под такой запрос можно сделать обычный составной
Тот же приём работает с диапазонами составных ключей:
🔥
➡️ SQL Ready | #совет
В PostgreSQL необязательно расписывать сравнение нескольких полей через длинные цепочки
AND и OR. Можно использовать row constructor comparison — сравнить сразу кортежи значений.Например, условие для
keyset pagination часто пишут так:WHERE user_id > :user_id
OR (user_id = :user_id AND id > :id)
Но PostgreSQL умеет выразить то же самое напрямую:
WHERE (user_id, id) > (:user_id, :id)
ORDER BY user_id, id
LIMIT 100;
Сравнение идёт слева направо: сначала
user_id, а если значения равны — id. Поэтому конструкция естественно совпадает с лексикографическим порядком составного ORDER BY.И это не просто сокращение синтаксиса. Под такой запрос можно сделать обычный составной
B-tree индекс:CREATE INDEX orders_user_id_id_idx
ON orders (user_id, id);
Тот же приём работает с диапазонами составных ключей:
WHERE (year, month) >= (2026, 4)
AND (year, month) < (2027, 1)
Row comparison позволяет заменить громоздкую булеву логику сравнением кортежей и особенно хорошо ложится на keyset pagination и составные B-tree индексы. Важно только помнить про NULL: обычные сравнения с ним могут дать UNKNOWN.Please open Telegram to view this post
VIEW IN TELEGRAM
❤18👍7🔥6
В этой статье:
• Разбирается механизм поиска корневых блокирующих сессий с помощью системных представлений MS SQL Server;• Показывается, как реализовать автокиллер на T-SQL с логированием, анализом цепочек блокировок и безопасным удалением зависших транзакций;• Объясняется, как автоматизировать мониторинг блокировок через SQL Server Agent и сохранить историю для последующего анализа.Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥6🤝1
Например, PostgreSQL отлично подходит не только для обычных CRUD-приложений (OLTP), но и для аналитики (OLAP), работы с геоданными, временными рядами, распределёнными таблицами и интеграции с внешними источниками данных через Foreign Data Wrapper (FDW).
На картинке — обзор основных направлений применения PostgreSQL и популярных расширений.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍8❤7
This media is not supported in your browser
VIEW IN TELEGRAM
Полезный материал для тех, кто хочет разобраться с оконными функциями SQL и научиться применять их в запросах. Здесь объясняется, чем оконные функции отличаются от обычной агрегации, как устроена конструкция OVER и как работать с отдельными группами строк без их объединения.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤10🔥7
Например, Load Balancing распределяет нагрузку между сервисами, Caching ускоряет доступ к данным, а Replication и Sharding помогают масштабировать базы данных.
На картинке — карта основных тем System Design: архитектура приложений, микросервисы, базы данных, масштабирование, безопасность, мониторинг и инфраструктура.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍7🤝5❤1👎1
В этой статье:
• Разбирается архитектура Avalon — масштабируемого Feature Store для централизованного хранения и быстрого получения миллиардов признаков;• Показывается, как с помощью YDB организованы шардирование, точечные и batch-запросы, импорт данных, ACL и Change Data Capture;• Рассказывается, какие архитектурные решения позволяют системе работать с 6,5 млрд ключей и выдерживать до 100 тысяч RPS на чтение при P95 около 5 мс.
🔊 Продолжайте читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥7👍5