Базы данных (Data Base) – Telegram
Базы данных (Data Base)
8.22K subscribers
565 photos
468 videos
19 files
544 links
Базы данных (Data Base). По всем вопросам @evgenycarter
Download Telegram
Media is too big
VIEW IN TELEGRAM
Немного юмора)

#db

👉 @database_info
😁24🔥4😭21
Конференция, на которую нужно прийти Data Engineers🔥

23 сентября пройдет Data Internals X 2025 — единственная в России конференция, где создатели СУБД и движков обработки данных делятся опытом работы с реальными production-системами экстремального масштаба. Вас ждёт по-настоящему "хардкорная" программа.

🎯 Глубина технических решений

Программа конференции сфокусирована на внутренних механизмах работы с данными — от разработки СУБД до оптимизации запросов и устойчивости к высоким нагрузкам. Это редкая возможность погрузиться в технические детали, которые обычно остаются за кадром.

🏭 Практический опыт масштабирования

Все доклады основаны на реальном опыте работы с петабайтными данными, высоконагруженными системами и решением production-задач в крупных компаниях (Яндекс, Сбер, VK, Т-Банк).

🔧 Импортозамещение и Open Source

Особый акцент на отечественные решения и open-source технологии, что критически важно в текущих реалиях.

🧠 Концентрированный опыт

Максимум пользы для повышения квалификации за один день: 20+ докладов, рекордная плотность экспертных знаний и нетворкинг с 300+ участниками.

📌Изучить расписание и забронировать билеты на сайте конференции

Приходите сами и приглашайте своих коллег 🔥

До встречи 23 сентября в Москве!
👍2
🚨 Антипаттерн: хранить пароли в базе "как есть"

Да, звучит как очевидный совет, но на практике до сих пор встречаются проекты, где пароль сохраняется в чистом виде или максимум в 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
👍621
Не пропустите! 27 августа в 20:00 пройдет бесплатный урок “Инкрементальное бекапирование средствами PostgreSQL” от онлайн-курса “PostgreSQL для администраторов баз данных и разработчиков”. Запись: https://vk.cc/cOMq7X

На открытом уроке разберём, зачем резервное копирование по-прежнему критично в 2025 году, даже при отказоустойчивых системах и облачных решениях.

Вы узнаете, какие встроенные возможности для бэкапов предлагает PostgreSQL и как в 17-й версии появилась долгожданная функция инкрементального резервного копирования без стороннего ПО.

Что разберём:

- Когда и зачем нужны бэкапы, если у вас уже есть репликация и облачные сервисы
- Как в PostgreSQL 17 реализовано инкрементальное копирование «из коробки»
- Как создать полный и инкрементальный бэкап базы
- Как быстро восстановить данные из созданных копий — в том числе до конкретного момента времени

Результат участия:

- Поймёте, как встроенные средства PostgreSQL решают задачу инкрементального бэкапа
- Получите пошаговый сценарий создания и восстановления копий
- Сможете внедрить новую функцию в своих проектах без установки дополнительного ПО

Кому полезно:

- Администраторам баз данных, которым важно надёжно и быстро восстанавливать данные
- Разработчикам и DevOps-инженерам, отвечающим за сохранность данных
- Всем, кто хочет быть уверенным, что их PostgreSQL-базы защищены от потерь

Успейте записаться на урок: https://vk.cc/cOMq7X

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
💡 Универсальная шпаргалка по SQL

#db

👉 @database_info
👍14🔥9
Где вы окажетесь завтра, зависит от того, что вы изучаете сегодня. PostgreSQL — инструмент, который ищут компании, а грамотных специалистов по нему все еще немного.

Почему именно PostgreSQL? Потому что это не просто база данных, а сердце ваших проектов. Если вы администратор БД, разработчик, DevOps или администратор Linux, этот курс — ваш апгрейд.

Мы научим настраивать кластеры, оптимизировать производительность, разбираться с блокировками и решать задачи работы с большими объемами данных. А также живые лекции, практические задания и диплом, который признают лидеры рынка. Учитесь у практиков, которые знают, как решать реальные задачи, и получите навыки, за которые платят топовые компании.

Присоединяйтесь к курсу сейчас и начните свой путь к высокооплачиваемой карьере! Оставить заявку на курс и получить скидку: https://vk.cc/cOQuW3

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🔥 Индексы в PostgreSQL: когда они реально помогают, а когда мешают

Многие ставят индексы “на всё подряд”, а потом удивляются, почему БД тормозит.

Типичные ошибки:

- Индекс на колонке, которая почти всегда уникальна (например, 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 брокера, но это не наш путь, смотрим сразу на практике.

Забрать урок👉🏻в боте
👍1
🔥 Неправильные типы данных в БД — тихий убийца производительности

Одна из самых частых ошибок — выбирать тип “на всякий случай побольше”.

Примеры антипаттернов:

- 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🔥62
Антипаттерн: N+1 запросов — как заметить и починить

Вы берёте список сущностей, а потом в цикле для каждой тянете связанные данные. В итоге - 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
👍83
Не пропустите! 09 сентября в 20:00 пройдет бесплатный урок “Механизмы блокировок в PostgreSQL” от онлайн-курса “PostgreSQL для администраторов баз данных и разработчиков”. Запись: https://vk.cc/cPiHmD

Практический разбор механизмов блокировок в СУБД PostgreSQL: от основ до диагностики проблем. Как избежать взаимоблокировок (deadlocks), снизить конфликты и повысить параллельную работу с данными.

Цели:

- Понять типы блокировок (объектов, строк, в памяти) и их влияние на производительность.
- Научиться выявлять и устранять конфликты блокировок в реальных сценариях.
- Освоить методы мониторинга и предотвращения взаимоблокировок.

Целевая аудитория:

- Разработчики – для написания кода, минимизирующего блокировки.
- Администраторы БД – для диагностики и оптимизации проблемных транзакций.
- Архитекторы – для проектирования систем с эффективным параллелизмом.

Чему научится слушатель:

- Типам блокировок: Различать блокировки объектов, строк и в памяти, понимать их уровни изоляции.
- Диагностике проблем: Находить "узкие места" (долгие транзакции, deadlocks) через локи и системные представления.
- Профилактике: Предотвращать взаимоблокировки через проектирование схемы и транзакций.

Успейте записаться на урок: https://vk.cc/cPiHmD

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Типы JOIN в SQL и когда их применять

- INNER JOIN - пересечение множеств (только совпавшие строки).
- LEFT JOIN - все слева + совпавшие справа (несовпавшие → NULL).
- RIGHT JOIN - симметричен LEFT, лучше переворачивать под LEFT.
- FULL OUTER JOIN - все слева и справа (где нет пары → NULL).
- CROSS JOIN — декартово произведение (каждая со всеми).
- SELF JOIN - таблица соединяется сама с собой.
- SEMI / ANTI JOIN - “есть/нет соответствия” (через EXISTS / NOT EXISTS).
- LATERAL / APPLY - зависимая подзапросная таблица на строку слева.


1️⃣ INNER JOIN - «строго есть пара»

«Покажи оплаченные заказы с данными клиента».


SELECT o.id, c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'paid';


Используйте, когда отсутствие пары - повод исключить строку.

2️⃣ LEFT JOIN - «все слева, даже без пары»

«Список клиентов и количество их заказов (включая с нулём)».


SELECT c.id, c.name, COALESCE(COUNT(o.id), 0) AS orders_cnt
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name;


По умолчанию для «обогащения» справочниками и опциональных связей.

3️⃣ RIGHT JOIN - почти не нужен

Заменяйте на LEFT, поменяв стороны:


-- было:
-- SELECT ... FROM A RIGHT JOIN B ON ...
-- стало:
SELECT ...
FROM B
LEFT JOIN A ON ...


4️⃣ FULL OUTER JOIN - «объединить всё»

«Свод по всем клиентам и всем заказам, даже если без пары».


SELECT COALESCE(c.id, o.customer_id) AS customer_key, c.name, o.id AS order_id
FROM customers c
FULL JOIN orders o ON o.customer_id = c.id;


Редко нужен в отчётах/сверках. Поддержка зависит от СУБД.

5️⃣ CROSS JOIN - «все комбинации»

«Собрать сетку метрик по всем регионам и кварталам».


SELECT r.region, q.quarter
FROM regions r
CROSS JOIN quarters q;


Осторожно: взрыв строк.

6️⃣ SELF JOIN - «сравнить строки внутри таблицы»

«Найти менеджера и его подчинённого».


SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;


7️⃣ SEMI JOIN (EXISTS) - «фильтрация по факту наличия»

«Клиенты, у кого были заказы за 30 дней».


SELECT c.*
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
AND o.created_at >= CURRENT_DATE - INTERVAL '30 day'
);


Не размножает строки, часто быстрее, чем JOIN + DISTINCT.

8️⃣ ANTI JOIN (NOT EXISTS) - «кто без соответствий»

«Товары, которые ни разу не покупали в этом году».


SELECT p.*
FROM products p
WHERE NOT EXISTS (
SELECT 1 FROM order_items oi
JOIN orders o ON o.id = oi.order_id
WHERE oi.product_id = p.id
AND o.created_at >= date_trunc('year', CURRENT_DATE)
);


Избегайте NOT IN с NULL - может дать пустой результат.

9️⃣ LATERAL / APPLY - «топ-N на строку»

«Последний заказ на клиента» (PostgreSQL: LATERAL, SQL Server: APPLY).


SELECT c.id, c.name, o_last.id AS last_order_id
FROM customers c
LEFT JOIN LATERAL (
SELECT o.id
FROM orders o
WHERE o.customer_id = c.id
ORDER BY o.created_at DESC
LIMIT 1
) o_last ON true;



💡Подводные камни

- LEFT JOIN + фильтр в WHERE ⇒ превращается в INNER.
Если нужно оставить «без пары», переносите условие в ON:


-- неверно
SELECT ... FROM c LEFT JOIN o ON o.customer_id = c.id
WHERE o.status = 'paid';

-- верно
SELECT ... FROM c LEFT JOIN o
ON o.customer_id = c.id AND o.status = 'paid';

- Дубликаты из «один-ко-многим». Перед JOIN делайте агрегацию в подзапросе/CTE.
- Индексы на ключах соединений (FK и соответствующие PK/UK) - must.
- Сопоставимость типов/колляций. Функции на ключе (LOWER(col)) ломают sargability - лучше нормализовать данные заранее.
- EXISTS чаще лучше, чем JOIN + DISTINCT для фильтрации.
- Проверяйте план. EXPLAIN (ANALYZE, BUFFERS) и сравнение альтернатив.

Сохрани, чтобы не забыть. А как вы чаще фильтруете - через JOIN+DISTINCT или EXISTS?

#SQL

👉 @database_info
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥41
Многопользовательская игра, похожая на DOOM, написанная на чистом SQL

DOOMQL - это экспериментальный проект, который позволяет играть в DOOM, используя SQL-запросы.
Идея проста: управление игрой происходит не через клавиатуру или мышь, а через выполнение SQL-команд, которые интерпретируются как действия внутри движка.

🔹 Например, можно отправить INSERT или UPDATE запрос, чтобы двигаться, стрелять или поворачивать персонажа.
🔹 Вся логика игрового процесса завязана на базу данных, превращая DOOM в своеобразный SQL-интерфейс.
🔹 Это скорее арт-проект, чем практичный инструмент, но отличный пример того, как базы данных можно использовать в самых неожиданных сценариях.

https://github.com/cedardb/DOOMQL

👉 @Githublib
👍8🥴1