Media is too big
VIEW IN TELEGRAM
Базы данных. Школа бэкенд-разработки 2025
На лекции обсудим основные понятия и принципы работы с базами данных. Рассмотрим факторы, влияющие на выбор подходящей базы данных для конкретной задачи. Познакомимся с индексами и их ролью в ускорении запросов. Поделимся советами по оптимальному использованию баз данных и рекомендациями для эффективной работы
источник
#db
👉 @database_info
На лекции обсудим основные понятия и принципы работы с базами данных. Рассмотрим факторы, влияющие на выбор подходящей базы данных для конкретной задачи. Познакомимся с индексами и их ролью в ускорении запросов. Поделимся советами по оптимальному использованию баз данных и рекомендациями для эффективной работы
источник
#db
👉 @database_info
👍3❤2
Почему индекс в PostgreSQL не всегда спасает
Индексы - мощный инструмент, но не панацея. Иногда запрос с индексом работает медленнее, чем без него. Почему?
1️⃣ Маленькая выборка - да, полное сканирование - нет
Если таблица маленькая (до нескольких тысяч строк), PostgreSQL может решить, что быстрее прочитать всё целиком, чем прыгать по индексу.
План покажет
2️⃣ Индекс не помогает с функциями в WHERE
Запрос вида:
не использует индекс по
3️⃣ Селективность
Если по условию отбирается больше ~5–10% строк, индекс становится невыгодным — чтение с диска и так почти сплошное.
4️⃣ Статистика устарела
PostgreSQL выбирает план по статистике. Если она старая - план может быть неэффективным.
- и жизнь наладится.
💡 Вывод: Индекс - не магическая кнопка «ускорить». Следи за планами запросов (
Сохрани, чтобы не наступить на этот грабельный индекс 🚀
#db
👉 @database_info
Индексы - мощный инструмент, но не панацея. Иногда запрос с индексом работает медленнее, чем без него. Почему?
1️⃣ Маленькая выборка - да, полное сканирование - нет
Если таблица маленькая (до нескольких тысяч строк), PostgreSQL может решить, что быстрее прочитать всё целиком, чем прыгать по индексу.
EXPLAIN ANALYZE
SELECT * FROM users WHERE status = 'active';
План покажет
Seq Scan, и это не баг.2️⃣ Индекс не помогает с функциями в WHERE
Запрос вида:
SELECT * FROM orders WHERE DATE(created_at) = '2025-08-12';
не использует индекс по
created_at. Решение — переписать условие:
WHERE created_at >= '2025-08-12' AND created_at < '2025-08-13'
3️⃣ Селективность
Если по условию отбирается больше ~5–10% строк, индекс становится невыгодным — чтение с диска и так почти сплошное.
4️⃣ Статистика устарела
PostgreSQL выбирает план по статистике. Если она старая - план может быть неэффективным.
ANALYZE table_name;
- и жизнь наладится.
💡 Вывод: Индекс - не магическая кнопка «ускорить». Следи за планами запросов (
EXPLAIN), обновляй статистику и оптимизируй условия.Сохрани, чтобы не наступить на этот грабельный индекс 🚀
#db
👉 @database_info
👍18❤1
Антипаттерны JOIN-ов в SQL и как их избежать
JOIN - мощная штука, но может легко превратиться в генератор тормозов и дублей. Вот топ-4 ловушек:
1️⃣ Забыли условие соединения
Без
✅ Как избежать: Всегда указывай условие соединения.
2️⃣ JOIN по неиндексированным колонкам
Если соединяешь большие таблицы по полю без индекса - готовься ждать.
✅ Как избежать: Добавь индекс на ключи соединения.
3️⃣ Фильтры в WHERE вместо ON
LEFT JOIN превратился в INNER JOIN, потому что фильтр в WHERE отсекает NULL-строки.
✅ Как избежать: Фильтруй в ON, если хочешь сохранить LEFT JOIN:
4️⃣ SELECT *** в сложных JOIN-ах
Такая выборка тянет все колонки всех таблиц. Много лишних данных + риск коллизии имён колонок.
✅ Как избежать: Явно указывай нужные поля.
💡 Вывод: JOIN - как скальпель. В умелых руках ускоряет, в неумелых - режет производительность.
Сохрани, чтобы не резануть базу не туда ✂️
#db
👉 @database_info
JOIN - мощная штука, но может легко превратиться в генератор тормозов и дублей. Вот топ-4 ловушек:
1️⃣ Забыли условие соединения
SELECT *
FROM orders
JOIN customers;
Без
ON это картезианское произведение - каждая строка первой таблицы умножается на все строки второй. Легко получить миллионы ненужных записей.✅ Как избежать: Всегда указывай условие соединения.
2️⃣ JOIN по неиндексированным колонкам
Если соединяешь большие таблицы по полю без индекса - готовься ждать.
✅ Как избежать: Добавь индекс на ключи соединения.
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
3️⃣ Фильтры в WHERE вместо ON
-- Плохо
FROM orders
LEFT JOIN customers ON orders.customer_id = customers.id
WHERE customers.region = 'EU';
LEFT JOIN превратился в INNER JOIN, потому что фильтр в WHERE отсекает NULL-строки.
✅ Как избежать: Фильтруй в ON, если хочешь сохранить LEFT JOIN:
LEFT JOIN customers
ON orders.customer_id = customers.id AND customers.region = 'EU';
4️⃣ SELECT *** в сложных JOIN-ах
Такая выборка тянет все колонки всех таблиц. Много лишних данных + риск коллизии имён колонок.
✅ Как избежать: Явно указывай нужные поля.
💡 Вывод: JOIN - как скальпель. В умелых руках ускоряет, в неумелых - режет производительность.
Сохрани, чтобы не резануть базу не туда ✂️
#db
👉 @database_info
👍15❤6
Media is too big
VIEW IN TELEGRAM
😁24🔥4😭2❤1
Конференция, на которую нужно прийти Data Engineers🔥
23 сентября пройдет Data Internals X 2025 — единственная в России конференция, где создатели СУБД и движков обработки данных делятся опытом работы с реальными production-системами экстремального масштаба. Вас ждёт по-настоящему "хардкорная" программа.
🎯 Глубина технических решений
Программа конференции сфокусирована на внутренних механизмах работы с данными — от разработки СУБД до оптимизации запросов и устойчивости к высоким нагрузкам. Это редкая возможность погрузиться в технические детали, которые обычно остаются за кадром.
🏭 Практический опыт масштабирования
Все доклады основаны на реальном опыте работы с петабайтными данными, высоконагруженными системами и решением production-задач в крупных компаниях (Яндекс, Сбер, VK, Т-Банк).
🔧 Импортозамещение и Open Source
Особый акцент на отечественные решения и open-source технологии, что критически важно в текущих реалиях.
🧠 Концентрированный опыт
Максимум пользы для повышения квалификации за один день: 20+ докладов, рекордная плотность экспертных знаний и нетворкинг с 300+ участниками.
📌Изучить расписание и забронировать билеты на сайте конференции
Приходите сами и приглашайте своих коллег 🔥
До встречи 23 сентября в Москве!
23 сентября пройдет Data Internals X 2025 — единственная в России конференция, где создатели СУБД и движков обработки данных делятся опытом работы с реальными production-системами экстремального масштаба. Вас ждёт по-настоящему "хардкорная" программа.
🎯 Глубина технических решений
Программа конференции сфокусирована на внутренних механизмах работы с данными — от разработки СУБД до оптимизации запросов и устойчивости к высоким нагрузкам. Это редкая возможность погрузиться в технические детали, которые обычно остаются за кадром.
🏭 Практический опыт масштабирования
Все доклады основаны на реальном опыте работы с петабайтными данными, высоконагруженными системами и решением production-задач в крупных компаниях (Яндекс, Сбер, VK, Т-Банк).
🔧 Импортозамещение и Open Source
Особый акцент на отечественные решения и open-source технологии, что критически важно в текущих реалиях.
🧠 Концентрированный опыт
Максимум пользы для повышения квалификации за один день: 20+ докладов, рекордная плотность экспертных знаний и нетворкинг с 300+ участниками.
📌Изучить расписание и забронировать билеты на сайте конференции
Приходите сами и приглашайте своих коллег 🔥
До встречи 23 сентября в Москве!
👍2
🚨 Антипаттерн: хранить пароли в базе "как есть"
Да, звучит как очевидный совет, но на практике до сих пор встречаются проекты, где пароль сохраняется в чистом виде или максимум в
🔑 Как правильно:
1. Никогда не храните пароль в открытом виде.
2. Используйте алгоритмы адаптивного хэширования:
–
–
–
3. Настраивайте "cost factor" (число итераций), чтобы усложнить брутфорс.
4. Добавляйте "соль" (salt) к каждому паролю. Обычно библиотеки делают это автоматически.
5. Для дополнительной защиты можно применять pepper — секрет, хранящийся вне БД (например, в конфиге или KMS).
❌ Плохой пример:
✅ Хороший пример (псевдокод):
💡 Итог: база данных не должна "знать" пароли пользователей. Она должна хранить только безопасные хэши.
Сохрани пост, чтобы потом показать тем, кто всё ещё пишет
#db
👉 @database_info
Да, звучит как очевидный совет, но на практике до сих пор встречаются проекты, где пароль сохраняется в чистом виде или максимум в
MD5(). Это огромная брешь в безопасности: одна утечка = полный доступ злоумышленника.🔑 Как правильно:
1. Никогда не храните пароль в открытом виде.
2. Используйте алгоритмы адаптивного хэширования:
–
bcrypt–
scrypt–
Argon2 (считается современным стандартом).3. Настраивайте "cost factor" (число итераций), чтобы усложнить брутфорс.
4. Добавляйте "соль" (salt) к каждому паролю. Обычно библиотеки делают это автоматически.
5. Для дополнительной защиты можно применять pepper — секрет, хранящийся вне БД (например, в конфиге или KMS).
❌ Плохой пример:
INSERT INTO users (login, password) VALUES ('admin', MD5('123456'));
✅ Хороший пример (псевдокод):
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
store_in_db(user, hashed)
💡 Итог: база данных не должна "знать" пароли пользователей. Она должна хранить только безопасные хэши.
Сохрани пост, чтобы потом показать тем, кто всё ещё пишет
MD5(password) 😉#db
👉 @database_info
👍6❤2⚡1
Не пропустите! 27 августа в 20:00 пройдет бесплатный урок “Инкрементальное бекапирование средствами PostgreSQL” от онлайн-курса “PostgreSQL для администраторов баз данных и разработчиков”. Запись: https://vk.cc/cOMq7X
На открытом уроке разберём, зачем резервное копирование по-прежнему критично в 2025 году, даже при отказоустойчивых системах и облачных решениях.
Вы узнаете, какие встроенные возможности для бэкапов предлагает PostgreSQL и как в 17-й версии появилась долгожданная функция инкрементального резервного копирования без стороннего ПО.
Что разберём:
- Когда и зачем нужны бэкапы, если у вас уже есть репликация и облачные сервисы
- Как в PostgreSQL 17 реализовано инкрементальное копирование «из коробки»
- Как создать полный и инкрементальный бэкап базы
- Как быстро восстановить данные из созданных копий — в том числе до конкретного момента времени
Результат участия:
- Поймёте, как встроенные средства PostgreSQL решают задачу инкрементального бэкапа
- Получите пошаговый сценарий создания и восстановления копий
- Сможете внедрить новую функцию в своих проектах без установки дополнительного ПО
Кому полезно:
- Администраторам баз данных, которым важно надёжно и быстро восстанавливать данные
- Разработчикам и DevOps-инженерам, отвечающим за сохранность данных
- Всем, кто хочет быть уверенным, что их PostgreSQL-базы защищены от потерь
Успейте записаться на урок: https://vk.cc/cOMq7X
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
На открытом уроке разберём, зачем резервное копирование по-прежнему критично в 2025 году, даже при отказоустойчивых системах и облачных решениях.
Вы узнаете, какие встроенные возможности для бэкапов предлагает PostgreSQL и как в 17-й версии появилась долгожданная функция инкрементального резервного копирования без стороннего ПО.
Что разберём:
- Когда и зачем нужны бэкапы, если у вас уже есть репликация и облачные сервисы
- Как в PostgreSQL 17 реализовано инкрементальное копирование «из коробки»
- Как создать полный и инкрементальный бэкап базы
- Как быстро восстановить данные из созданных копий — в том числе до конкретного момента времени
Результат участия:
- Поймёте, как встроенные средства PostgreSQL решают задачу инкрементального бэкапа
- Получите пошаговый сценарий создания и восстановления копий
- Сможете внедрить новую функцию в своих проектах без установки дополнительного ПО
Кому полезно:
- Администраторам баз данных, которым важно надёжно и быстро восстанавливать данные
- Разработчикам и DevOps-инженерам, отвечающим за сохранность данных
- Всем, кто хочет быть уверенным, что их PostgreSQL-базы защищены от потерь
Успейте записаться на урок: https://vk.cc/cOMq7X
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Где вы окажетесь завтра, зависит от того, что вы изучаете сегодня. PostgreSQL — инструмент, который ищут компании, а грамотных специалистов по нему все еще немного.
Почему именно PostgreSQL? Потому что это не просто база данных, а сердце ваших проектов. Если вы администратор БД, разработчик, DevOps или администратор Linux, этот курс — ваш апгрейд.
Мы научим настраивать кластеры, оптимизировать производительность, разбираться с блокировками и решать задачи работы с большими объемами данных. А также живые лекции, практические задания и диплом, который признают лидеры рынка. Учитесь у практиков, которые знают, как решать реальные задачи, и получите навыки, за которые платят топовые компании.
Присоединяйтесь к курсу сейчас и начните свой путь к высокооплачиваемой карьере! Оставить заявку на курс и получить скидку: https://vk.cc/cOQuW3
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Почему именно PostgreSQL? Потому что это не просто база данных, а сердце ваших проектов. Если вы администратор БД, разработчик, DevOps или администратор Linux, этот курс — ваш апгрейд.
Мы научим настраивать кластеры, оптимизировать производительность, разбираться с блокировками и решать задачи работы с большими объемами данных. А также живые лекции, практические задания и диплом, который признают лидеры рынка. Учитесь у практиков, которые знают, как решать реальные задачи, и получите навыки, за которые платят топовые компании.
Присоединяйтесь к курсу сейчас и начните свой путь к высокооплачиваемой карьере! Оставить заявку на курс и получить скидку: https://vk.cc/cOQuW3
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🔥 Индексы в PostgreSQL: когда они реально помогают, а когда мешают
Многие ставят индексы “на всё подряд”, а потом удивляются, почему БД тормозит.
❌ Типичные ошибки:
- Индекс на колонке, которая почти всегда уникальна (например,
- Индекс на поле с низкой селективностью (
- Создание 5+ индексов на таблицу без анализа запросов.
✅ Best practices:
- Делайте индекс под конкретный частый запрос.
- Для
- Для поиска по JSONB → GIN индекс.
- Для геоданных → GiST.
- Для частого условия — partial index:
⚡️ Помните: каждый индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE.
👉 Итог: индекс — это инструмент, а не магическая таблетка. Всегда проверяйте план выполнения (
Сохрани, чтобы не забыть 🚀
#db
👉 @database_info
Многие ставят индексы “на всё подряд”, а потом удивляются, почему БД тормозит.
❌ Типичные ошибки:
- Индекс на колонке, которая почти всегда уникальна (например,
id с PK — он уже индексирован).- Индекс на поле с низкой селективностью (
is_active = true/false) — толку ноль, только замедляет вставки.- Создание 5+ индексов на таблицу без анализа запросов.
✅ Best practices:
- Делайте индекс под конкретный частый запрос.
- Для
WHERE field LIKE 'abc%' — используйте btree.- Для поиска по JSONB → GIN индекс.
- Для геоданных → GiST.
- Для частого условия — partial index:
CREATE INDEX idx_orders_active
ON orders(status)
WHERE status = 'active';
⚡️ Помните: каждый индекс ускоряет SELECT, но замедляет INSERT/UPDATE/DELETE.
👉 Итог: индекс — это инструмент, а не магическая таблетка. Всегда проверяйте план выполнения (
EXPLAIN ANALYZE).Сохрани, чтобы не забыть 🚀
#db
👉 @database_info
👍7🔥2
Бесплатный урок по Apache Kafka⭐️
Учим работать с реальными исходными данными, а не на теоретических примерах.
✅Расскажем про язык Кафки: топики, партиции, продюсеры-консьюмеры, кластер, ноды.
✅Рассмотрим: как работают очереди сообщений, сколько должно быть консьюмеров для эффективной вычитки, как повысить надёжность кластера с помощью репликации данных.
✅Покажем, как развернуть кластер Кафки на своём ПК с 3 нодами, schema-registry и авторизацией.
Обычно в инструкциях кластер из 1 ноды, зукипера и 1 брокера, но это не наш путь, смотрим сразу на практике.
Забрать урок👉🏻в боте
Учим работать с реальными исходными данными, а не на теоретических примерах.
✅Расскажем про язык Кафки: топики, партиции, продюсеры-консьюмеры, кластер, ноды.
✅Рассмотрим: как работают очереди сообщений, сколько должно быть консьюмеров для эффективной вычитки, как повысить надёжность кластера с помощью репликации данных.
✅Покажем, как развернуть кластер Кафки на своём ПК с 3 нодами, schema-registry и авторизацией.
Обычно в инструкциях кластер из 1 ноды, зукипера и 1 брокера, но это не наш путь, смотрим сразу на практике.
Забрать урок👉🏻в боте
👍1
🔥 Неправильные типы данных в БД — тихий убийца производительности
Одна из самых частых ошибок — выбирать тип “на всякий случай побольше”.
❌ Примеры антипаттернов:
-
-
-
-
✅ Как лучше:
- Размер строки под задачу:
- Для денег →
- Для булевых значений →
- Для дат →
📌 Пример:
⚡️ Итог: грамотный выбор типов = меньше места, быстрее запросы, меньше багов.
Сохрани, чтобы не забыть 😉
#db
👉 @database_info
Одна из самых частых ошибок — выбирать тип “на всякий случай побольше”.
❌ Примеры антипаттернов:
-
VARCHAR(255) для всего подряд, даже если поле — код из 10 символов.-
TEXT для email-адресов.-
BIGINT для счётчика, где максимум 1000 записей.-
FLOAT для денег (теряешь точность).✅ Как лучше:
- Размер строки под задачу:
VARCHAR(50) для email, CHAR(2) для кода страны.- Для денег →
NUMERIC(10,2) или DECIMAL.- Для булевых значений →
BOOLEAN, а не INT.- Для дат →
DATE или TIMESTAMP, а не строка.📌 Пример:
-- Плохо
price FLOAT;
-- Хорошо
price NUMERIC(10,2);
⚡️ Итог: грамотный выбор типов = меньше места, быстрее запросы, меньше багов.
Сохрани, чтобы не забыть 😉
#db
👉 @database_info
👍9🔥6❤2
SQL: Бесплатные курсы
Курсы на русском языке:
Интерактивный тренажер по SQL
Введение в базы данных
SQLite на практике
Базы данных
SQL Учебник
Курсы на английском языке:
Khan Academy
SQL for Data Science (IBM)
SQL Tutorial (SQL ZOO)
Intro to SQL (Kaggle)
Advanced SQL (Kaggle)
Lern SQL (Codeacademy)
SQL for Data Science (UCDavice, University of California)
#SQL
👉 @database_info
Курсы на русском языке:
Интерактивный тренажер по SQL
Введение в базы данных
SQLite на практике
Базы данных
SQL Учебник
Курсы на английском языке:
Khan Academy
SQL for Data Science (IBM)
SQL Tutorial (SQL ZOO)
Intro to SQL (Kaggle)
Advanced SQL (Kaggle)
Lern SQL (Codeacademy)
SQL for Data Science (UCDavice, University of California)
#SQL
👉 @database_info
❤8
Антипаттерн: N+1 запросов — как заметить и починить
Вы берёте список сущностей, а потом в цикле для каждой тянете связанные данные. В итоге - 1 запрос за «родителями» + N запросов за «детьми». Латентность растёт линейно от размера выборки.
Симптомы
- В логах много одинаковых коротких запросов.
- Кол-во запросов ≈ размеру списка.
- Страница/endpoint сильно «замедляется» при росте данных.
Плохой пример (SQL + псевдокод)
Правильно (SQL, PostgreSQL) — сетевое мышление:
Django ORM
SQLAlchemy
Практические советы
- Логируйте кол-во запросов на эндпойнт/страницу. В Django - django-debug-toolbar, assertNumQueries в тестах; в SQLAlchemy - echo/интеграция с логгером.
- Индексы: обязательно
- Батчинг вместо циклов: тяните детей одним запросом
- Осторожно с joinedload для 1:N на больших выборках - риск «взрыва» строк. Для 1:N чаще выбирайте selectinload.
- Колонки по делу: не тащите
- Пагинация: уменьшает N и давление на сеть/память.
- EXPLAIN (ANALYZE, BUFFERS) - проверяйте планы и кардинальности.
💡Думайте наборами, а не циклами. Eager loading + агрегаты закрывают 90% случаев N+1. Настройте мониторинг количества запросов - и ловите проблему до продакшена.
Сохрани, чтобы не наступить снова. Поделись с коллегами. А как вы ловите N+1 у себя?
#SQL
👉 @database_info
Вы берёте список сущностей, а потом в цикле для каждой тянете связанные данные. В итоге - 1 запрос за «родителями» + N запросов за «детьми». Латентность растёт линейно от размера выборки.
Симптомы
- В логах много одинаковых коротких запросов.
- Кол-во запросов ≈ размеру списка.
- Страница/endpoint сильно «замедляется» при росте данных.
Плохой пример (SQL + псевдокод)
-- Берём пользователей
SELECT id, name FROM users WHERE active = true;
-- Потом в цикле по каждому:
SELECT count(*) FROM orders WHERE user_id = :id;
Правильно (SQL, PostgreSQL) — сетевое мышление:
SELECT u.id,
u.name,
count(o.*) AS orders_cnt
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.active = true
GROUP BY u.id, u.name;
Django ORM
# Плохо: в шаблоне/цикле обращаемся к user.orders -> N+1
users = User.objects.filter(active=True)
# Хорошо: подгрузим связи заранее
users = (User.objects
.filter(active=True)
.prefetch_related('orders')) # для 1:N
# для 1:1 / ForeignKey используйте select_related('profile')
# Агрегация без цикла
from django.db.models import Count
users = (User.objects.filter(active=True)
.annotate(orders_cnt=Count('orders')))
SQLAlchemy
from sqlalchemy.orm import selectinload, joinedload
# 1:N — безопаснее selectinload (батчирует IN (...))
users = (session.query(User)
.options(selectinload(User.orders))
.filter(User.active.is_(True))
.all())
# 1:1 — joinedload
user = (session.query(User)
.options(joinedload(User.profile))
.get(user_id))
Практические советы
- Логируйте кол-во запросов на эндпойнт/страницу. В Django - django-debug-toolbar, assertNumQueries в тестах; в SQLAlchemy - echo/интеграция с логгером.
- Индексы: обязательно
orders(user_id); если фильтруете по статусу - составной (user_id, status).- Батчинг вместо циклов: тяните детей одним запросом
WHERE user_id IN (...), затем мапьте в памяти.- Осторожно с joinedload для 1:N на больших выборках - риск «взрыва» строк. Для 1:N чаще выбирайте selectinload.
- Колонки по делу: не тащите
SELECT *, берите только нужные поля.- Пагинация: уменьшает N и давление на сеть/память.
- EXPLAIN (ANALYZE, BUFFERS) - проверяйте планы и кардинальности.
💡Думайте наборами, а не циклами. Eager loading + агрегаты закрывают 90% случаев N+1. Настройте мониторинг количества запросов - и ловите проблему до продакшена.
Сохрани, чтобы не наступить снова. Поделись с коллегами. А как вы ловите N+1 у себя?
#SQL
👉 @database_info
👍8❤3