ar
Feedback

لا تقع ضحية للمخادعين! تيليمتريو يكتشف ويُميّز هذه القنوات 👉 إذا كنت تريد رؤية العلامة، اشترك

SQL Ready | Базы Данных

SQL Ready | Базы Данных

الذهاب إلى القناة على Telegram

Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc

إظهار المزيد

📈 نظرة تحليلية على قناة تيليجرام SQL Ready | Базы Данных

تُعد قناة SQL Ready | Базы Данных (@sql_ready) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 17 670 مشتركاً، محتلاً المرتبة 7 345 في فئة التكنولوجيات والتطبيقات والمرتبة 37 222 في منطقة روسيا.

📊 مؤشرات الجمهور والحراك

منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 17 670 مشتركاً.

بحسب آخر البيانات بتاريخ 17 أكتوبر, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار 691، وفي آخر 24 ساعة بمقدار 41، مع بقاء الوصول العام مرتفعاً.

  • حالة التحقق: غير موثّقة
  • معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 12.44‎%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 5.98‎% من ردود الفعل نسبةً إلى إجمالي المشتركين.
  • وصول المنشورات: يحصل كل منشور على متوسط 2 198 مشاهدة. وخلال اليوم الأول يجمع عادةً 1 057 مشاهدة.
  • التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 23.
  • الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل sql, строка, users, индекс, user_id.

📝 الوصف وسياسة المحتوى

يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc”

بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 18 أكتوبر, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.

17 670
المشتركون
+4124 ساعات
+1797 أيام
+69130 أيام
أرشيف المشاركات
✍️ Информативная статья вышла на Хабре: «Обратная сторона массивов в PostgreSQL»! В этой статье: • Разбирается, почему массив
✍️ Информативная статья вышла на Хабре: «Обратная сторона массивов в PostgreSQL»! В этой статье: • Разбирается, почему массивы в PostgreSQL — это отдельная модель хранения со своими ограничениями и компромиссами; • Показываются скрытые проблемы массивов: потеря ссылочной целостности, особенности GIN-индексов, TOAST, MVCC и дорогостоящие обновления; • Объясняется, как правильно работать с массивами, когда использовать JSONB, intarray, pgvector и в каких случаях массивы действительно оправданы.
🔊 Продолжайте читать на Habr!
➡️ SQL Ready | #статья

PostgreSQL умеет обновлять только реально изменившиеся строки и это может сильно сократить WAL и нагрузку! Многие приложения
PostgreSQL умеет обновлять только реально изменившиеся строки и это может сильно сократить WAL и нагрузку! Многие приложения делают UPDATE даже тогда, когда данные вообще не изменились.
UPDATE users
SET name = 'Alex'
WHERE id = 1;
Даже если name уже равен 'Alex', PostgreSQL всё равно создаст новую версию строки (MVCC), запишет WAL, обновит индексы и увеличит нагрузку на autovacuum. Проверить это можно через системную статистику:
SELECT n_tup_upd
FROM pg_stat_user_tables
WHERE relname = 'users';
Чтобы избежать “пустых” UPDATE, можно сравнивать старые и новые значения прямо в WHERE:
UPDATE users
SET
  name = $1,
  email = $2
WHERE id = $3
  AND (name, email) IS DISTINCT FROM ($1, $2);
IS DISTINCT FROM безопасно сравнивает даже NULL значения, в отличие от обычного !=:
SELECT
  NULL = NULL,
  NULL IS DISTINCT FROM NULL;
На highload-системах это может заметно уменьшить WAL, bloat, количество HOT/non-HOT update и нагрузку на autovacuum без изменения архитектуры. ➡️ SQL Ready | #совет

🎓 PostgreSQL должен быть спроектирован до первого инцидента. В enterprise-среде PostgreSQL — это уже не просто база данных,
🎓 PostgreSQL должен быть спроектирован до первого инцидента. В enterprise-среде PostgreSQL — это уже не просто база данных, а часть критичной инфраструктуры с требованиями к доступности, восстановлению, безопасности и мониторингу. На курсе «Архитектура PostgreSQL для корпоративных систем» разбираем, как строить устойчивую PostgreSQL-инфраструктуру под реальные корпоративные нагрузки. 📌 В фокусе курса: • High Availability (высокая доступность) • Disaster Recovery (аварийное восстановление) • failover-сценарии • RPO/RTO • резервирование и мониторинг • архитектурные ошибки и точки отказа
🐾 АИСыч напоминает: б бы «Backup — это не стратегия. Стратегия — это проверенное восстановление».
На курсе отдельно разбираем, как проектировать PostgreSQL-инфраструктуру так, чтобы система переживала сбои без потери критичных данных. 🎁 Для наших подписчиков действует скидка 20% по промокоду: SQLREADY20 Записаться на курс прямо сейчас А ещё больше практики, ИИ и ИБ — в MAX Академии, где сейчас проходит розыгрыш курса за 1 рубль 🔥 Реклама АНО ДПО ЦПК "АИС", ИНН: 7720346012, erid: 2SDnjdvRDWz

😎 SQL Cheatsheet — удобная шпаргалка для повседневной работы! Этот репозиторий хорошо подойдёт тем, кто постоянно работает с базами данных и хочет быстро освежать в памяти нужные SQL-конструкции. Здесь всё подано компактно и по делу: запросы, JOIN’ы, агрегации, подзапросы и др. Особенно удобно использовать для подготовки к собеседованиям.
Оставляю ссылочку: GitHub 📱
➡️ SQL Ready | #репозиторий

Почему индекс может не использоваться, даже если он есть! Очень частая ситуация: индекс создан, запрос написан вроде нормально, но SQL всё равно делает Seq Scan или Full Table Scan. Имеем такую таблицу:
users(
    id,
    email,
    created_at
)
Индекс:
CREATE INDEX idx_users_email
ON users(email);
Кажется, что такой запрос точно должен использовать индекс:
SELECT *
FROM users
WHERE email = 'test@example.com';
И обычно действительно будет Index Scan. Но достаточно небольшой детали — и индекс может перестать использоваться. Например:
SELECT *
FROM users
WHERE LOWER(email) = 'test@example.com';
Проблема в том, что индекс построен по колонке: email. А в условии используется выражение:
LOWER(email)
Для оптимизатора это уже не то же самое условие. В итоге серверу часто приходится: применять LOWER() к строкам; сравнивать результат; читать гораздо больше данных, чем ожидалось. Исправляется это expression/functional index:
CREATE INDEX idx_users_email_lower
ON users(LOWER(email));
То же самое часто происходит с датами:
SELECT *
FROM orders
WHERE DATE(created_at) = '2025-01-10';
Из-за:
DATE(created_at)
обычный индекс по created_at может не помочь, потому что функция применяется к колонке. Правильнее писать диапазон:
SELECT *
FROM orders
WHERE created_at >= '2025-01-10'
  AND created_at <  '2025-01-11';
Так условие остаётся sargable — то есть пригодным для эффективного использования индекса. Ещё одна частая проблема — преобразования типов. Например, плохо:
WHERE user_id::text = '100'
Если user_id — integer, то здесь преобразование применяется к колонке. В такой ситуации обычный индекс по user_id может не использоваться. Правильнее:
WHERE user_id = 100
Важно: простое условие вида:
WHERE user_id = '100'
в некоторых СУБД может нормально привести литерал к integer и всё равно использовать индекс. Проблема чаще начинается там, где преобразуется сама колонка или выражение становится сложнее. Популярная ошибка с LIKE:
WHERE email LIKE '%gmail.com'
Здесь обычный B-Tree индекс обычно бесполезен. Так как поиск начинается не с начала строки; сервер не может эффективно использовать упорядоченность индекса. Если таблица маленькая: 100–1000 строк, то Full Scan может быть дешевле, чем прыжки по индексу. 🔥 Наличие индекса ещё не гарантирует его использование. Функции над колонками, преобразования типов, неправильные LIKE, OR-условия и устаревшая статистика могут сделать индекс бесполезным или менее выгодным для оптимизатора. ➡️ SQL Ready | #практика

PostgreSQL может избежать полной сортировки таблицы при ORDER BY ... LIMIT! Большинство думает, что ORDER BY всегда сортирует
PostgreSQL может избежать полной сортировки таблицы при ORDER BY ... LIMIT! Большинство думает, что ORDER BY всегда сортирует вообще всю таблицу. Но в PostgreSQL для LIMIT есть отдельная оптимизация — Top-N Heap Sort.
SELECT *
FROM orders
ORDER BY created_at DESC
LIMIT 10;
Если нужен только top-10 результат, PostgreSQL не обязан сортировать миллионы строк полностью. Вместо этого он держит в памяти только N лучших строк во время scan. Это видно прямо в execution plan:
Sort Method: top-N heapsort
Особенно интересно становится на огромных таблицах, где полный sort мог бы уйти на диск:
SET work_mem = '4MB';

EXPLAIN ANALYZE
SELECT *
FROM events
ORDER BY created_at DESC
LIMIT 50;
Даже при маленьком work_mem PostgreSQL может избежать полной сортировки всех строк и работать заметно быстрее именно благодаря оптимизации Top-N. А если добавить подходящий индекс:
CREATE INDEX idx_events_created_at
ON events (created_at DESC);
🔥 PostgreSQL вообще сможет обойтись без Sort и просто сделать Index Scan в нужном порядке. ➡️ SQL Ready | #совет

Кажется, аналитика подошла к моменту больших изменений. Ещё недавно подготовка отчётов занимала дни: данные собирались вручну
Кажется, аналитика подошла к моменту больших изменений. Ещё недавно подготовка отчётов занимала дни: данные собирались вручную, цифры перепроверялись, а бизнес слишком долго ждал ответы. Сегодня искусственный интеллект меняет сам подход к работе с данными — делает аналитику быстрее, проще и доступнее. 3 июня Visiology проведёт большой онлайн-эфир Cortex LIVE о новом поколении аналитики. На бесплатном эфире покажут: — как ускорить получение аналитики — как сократить объём ручной работы — как быстрее находить ответы для бизнеса — как компании уже меняют подход к работе с данными Без сложной теории — только реальные примеры и практические сценарии. Если вы работаете с аналитикой, отчётностью или управлением, этот эфир точно стоит посмотреть. До мероприятия осталось совсем немного времени — успейте зарегистрироваться заранее, чтобы не пропустить эфир.

📂 Напоминалка по оптимизации баз данных! Например, индексы ускоряют поиск данных, а репликация помогает распределять нагрузк
📂 Напоминалка по оптимизации баз данных! Например, индексы ускоряют поиск данных, а репликация помогает распределять нагрузку и повышать отказоустойчивость. На картинке — 9 основных подходов для улучшения производительности базы данных, которые полезно держать под рукой. Сохрани, чтобы не потерять! ➡️ SQL Ready | #ресурс

❤️ SQL DEV — большая база для изучения SQL и PostgreSQL! Здесь собрано огромное количество материалов по SQL: запросы, JOIN’ы, подзапросы, оконные функции, индексы, оптимизация и работа с PostgreSQL. Репозиторий отлично подходит как для изучения базы, так и для углубления в более сложные темы. Особенно полезно то, что здесь много практических примеров и разборов реальных SQL-конструкций.
Оставляю ссылочку: GitHub 📱
➡️ SQL Ready | #репозиторий

Почему NOT IN может вернуть пустой результат из-за NULL! Одна из самых неприятных ловушек SQL — поведение NOT IN при наличии NULL. Запрос выглядит абсолютно корректно, но внезапно перестаёт возвращать строки. Таблицы:
users(id)
bans(user_id)
Допустим, нужно получить пользователей, которых нет в bans. Часто пишут так:
SELECT *
FROM users
WHERE id NOT IN (
    SELECT user_id
    FROM bans
);
Пока в bans.user_id нет NULL — всё работает нормально. Но представим данные:
bans
-------
1
2
NULL
Теперь запрос внезапно вернет:
0 rows
Хотя пользователи без бана есть. Почему так происходит — SQL сравнивает условие примерно как:
id <> 1
AND id <> 2
AND id <> NULL
Но:
id <> NULL
не даёт TRUE или FALSE. Результат: UNKNOWN. А в WHERE проходят только TRUE. Из-за этого всё условие целиком перестаёт выполняться. Это особенность трёхзначной логики SQL: TRUE, FALSE, UNKNOWN Любое сравнение с NULL даёт UNKNOWN:
NULL = 1
NULL <> 1
NULL = NULL
Поэтому NOT IN с NULL внутри подзапроса становится опасным. Безопасный вариант — NOT EXISTS:
SELECT *
FROM users u
WHERE NOT EXISTS (
    SELECT 1
    FROM bans b
    WHERE b.user_id = u.id
);
Почему EXISTS работает нормально: сравнение идёт построчно; NULL не ломает всю проверку; оптимизатор обычно хорошо превращает это в anti-join. Ещё вариант — явно убрать NULL:
SELECT *
FROM users
WHERE id NOT IN (
    SELECT user_id
    FROM bans
    WHERE user_id IS NOT NULL
);
Но на практике: NOT EXISTS обычно считается более безопасным и читаемым решением. Отдельный момент: NOT IN () и NOT EXISTS могут давать разные планы выполнения в зависимости от СУБД. Но логически для nullable данных: NOT EXISTS почти всегда предпочтительнее. Быстрая проверка проблемы:
SELECT COUNT(*)
FROM bans
WHERE user_id IS NULL;
Если такие строки есть — NOT IN уже потенциально опасен. 🔥 NOT IN и NULL плохо сочетаются. Если в подзапросе появляется хотя бы один NULL, условие может перестать возвращать строки вообще. Для таких проверок надёжнее использовать NOT EXISTS. ➡️ SQL Ready | #практика

Ты аналитик. Ты тащишь на себе дашборды, A/B-тесты и SQL в 10 вкладках. А при мыслях об автоматизации задач и усилении своих
Ты аналитик. Ты тащишь на себе дашборды, A/B-тесты и SQL в 10 вкладках. А при мыслях об автоматизации задач и усилении своих скиллов, осекаешься - повышение квалифкации стоит десятки тысяч. Больше 60% работодателей уже заложили бюджет на развитие команды в этом году. Просто большинство аналитиков никогда не просят. Потому что не знают, как. Мы собрали полный гайд: → 8 шагов от «хочу прокачаться» до «компания всё оплатила» → Готовые обоснования для руководителя → Скрипты ответов на возражения → Чек-лист перед разговором с HR Здесь - твоя грамотная заявка на корпоративный грант. 📄 Забирай методичку бесплатно → https://tglink.io/0516683a1ec128 Реклама. ООО "АЙТИ РЕЗЮМЕ". ИНН 4025460134. erid: 2W5zFHW9GuF

📂 Напоминалка по Data Engineering и аналитической архитектуре! Например, Data Warehouse хранит уже очищенные и структурирова
📂 Напоминалка по Data Engineering и аналитической архитектуре! Например, Data Warehouse хранит уже очищенные и структурированные данные для BI и отчетности, Data Lake позволяет складировать сырые данные любого типа и обрабатывать их по мере необходимости, а Data Mesh распределяет владение данными между бизнес-доменами и превращает данные в полноценные data products. На картинке — основные отличия: как хранятся данные, кто ими управляет, как происходит обработка и для каких задач лучше подходит каждый подход. Сохрани, чтобы не потерять! ➡️ SQL Ready | #ресурс

BUFFERS: как увидеть цену запроса? Обычный EXPLAIN ANALYZE показывает время выполнения, но почти ничего не говорит о том, ско
BUFFERS: как увидеть цену запроса? Обычный EXPLAIN ANALYZE показывает время выполнения, но почти ничего не говорит о том, сколько данных было прочитано с диска и из памяти.
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...
Опция BUFFERS добавляет статистику по страницам памяти: shared hit — страницы найдены в PostgreSQL shared buffers. shared read — страницы пришлось загрузить в shared buffers; это может быть физический диск или OS page cache.
Buffers: shared hit=15000 read=2
Такой запрос почти полностью работает из памяти, что хорошо. А здесь видно узкое место: запрос массово читает диск, даже если по времени более менее.
Buffers: shared hit=10 read=15000
🔥 Два запроса с одинаковым execution time могут иметь абсолютно разную нагрузку на систему. ➡️ SQL Ready | #совет

😍 SQL шпаргалка для начинающих — база по работе с бд! Удобный и понятный справочник, где разобраны основные SQL-запросы и конструкции: SELECT, WHERE, JOIN, INSERT, UPDATE и другие ключевые команды. Всё объясняется простым языком с примерами, чтобы быстро понять логику работы с данными и начать применять это в реальных задачах 📌 Оставляю ссылочку: ermita.one ➡️ SQL Ready | #ресурс

Генерация пропущенных дат в отчётах: почему LEFT JOIN не помогает! Классическая задача — построить отчёт по дням. Например, количество заказов по датам. И внезапно оказывается, что в выдаче нет некоторых дней. Таблица:
orders(id, created_at)
Плохой вариант:
SELECT
    DATE(created_at) AS day,
    COUNT(*) AS orders_count
FROM orders
GROUP BY DATE(created_at)
ORDER BY day;
Проблема: если в какой-то день не было заказов — строки просто не будет. В аналитике это почти всегда ошибка, потому что отсутствие строки не равно ноль значений. Попытка через LEFT JOIN сама по себе не помогает — без таблицы дат нечего достраивать. Правильный подход — сначала явно сгенерировать календарь, а потом присоединить данные. В PostgreSQL для этого есть generate_series:
WITH calendar AS (
    SELECT generate_series(
        DATE '2026-01-01',
        DATE '2026-01-10',
        INTERVAL '1 day'
    )::date AS day
)
SELECT
    c.day,
    COUNT(o.id) AS orders_count
FROM calendar c
LEFT JOIN orders o
  ON DATE(o.created_at) = c.day
GROUP BY c.day
ORDER BY c.day;
Теперь: каждый день присутствует; если заказов нет — COUNT(o.id) вернёт 0. Почему именно COUNT(o.id), а не COUNT(*): COUNT(*) посчитает строку календаря даже без совпадений — всегда ≥ 1; COUNT(o.id) считает только реальные заказы — корректный 0 при отсутствии данных. Ещё один важный момент — условие в JOIN: ON DATE(o.created_at) = c.day. Так писать удобно, но это ломает использование индекса по created_at. Лучше диапазон:
ON o.created_at >= c.day
AND o.created_at <  c.day + INTERVAL '1 day'
Это позволяет использовать индекс и ускоряет запрос на больших таблицах. Расширение задачи — накопительный итог по дням (используется тот же CTE calendar):
SELECT
    c.day,
    COUNT(o.id) AS orders_count,
    SUM(COUNT(o.id)) OVER (ORDER BY c.day) AS running_total
FROM calendar c
LEFT JOIN orders o
  ON o.created_at >= c.day
 AND o.created_at <  c.day + INTERVAL '1 day'
GROUP BY c.day
ORDER BY c.day;
Если нужно ограничение по периоду по данным, а не вручную:
WITH bounds AS (
    SELECT
        MIN(created_at)::date AS min_day,
        MAX(created_at)::date AS max_day
    FROM orders
),
calendar AS (
    SELECT generate_series(min_day, max_day, INTERVAL '1 day')::date AS day
    FROM bounds
)
SELECT ...
Календарь строится автоматически по данным. Если created_at — timestamptz, границы дня зависят от timezone. 🔥 Если в отчёте есть время — сначала формируйте ось времени, потом присоединяйте данные. Иначе вы работаете не с нулями, а с отсутствием строк, что даёт искажённую картину. ➡️ SQL Ready | #практика

Совет на 2027 год — переходите в ML. Пока обычные разрабы конкурируют с ИИ-копилотами, ML-инженеры эти самые нейронки создают. В эпоху нейростей это самые востребованые люди в мире программирования. Зарплаты мидлов начинаются от 250 000 ₽, а у сеньоров в BigTech доходят до 700 000 ₽. А чтобы освоить его всего за 4 месяца без лишней суеты — изучите канал Марка Миргалеева. Он помог 20+ ученикам найти работу от 250к в ML/NLP/AI-агентах На канале вы найдёте: — Всё про самые востребованные стеки(Python, ИИ-агенты, NLP) и почему математика — это не страшно, если учить только нужное. — Как оформить резюме, чтобы оно пролетало через любые LLM-фильтры и ATS-системы прямо к тимлидам. — Скрипты переговоров, которые помогли его ученикам прыгнуть с 0 до 360к всего за 8 месяцев. Во времена острой нехватки ML-разработчиков, это лучшее время, чтобы перекатиться. Переходи и изучай: https://t.me/+TwxQ8W6MF6hhY2My

📂 Напоминалка по DB Sharding! Шардинг помогает масштабировать базу данных, распределяя данные между несколькими серверами. Н
📂 Напоминалка по DB Sharding! Шардинг помогает масштабировать базу данных, распределяя данные между несколькими серверами. На картинке — основные стратегии партиционирования и шардинга. Например, key-based sharding использует hash-функцию для равномерного распределения записей, а range-based sharding делит данные по диапазонам значений. Сохрани, чтобы не потерять! ➡️ SQL Ready | #ресурс

LAG() в SQL — сравниваем строку с предыдущей без JOIN! Оконная функция LAG() позволяет получить значение из предыдущей строки внутри группы. Это один из самых полезных инструментов для аналитики, логов и временных рядов. Таблица: payments(id, user_id, amount, created_at) Посмотрим предыдущий платёж каждого пользователя:
SELECT
    user_id,
    amount,
    LAG(amount) OVER (
        PARTITION BY user_id
        ORDER BY created_at
    ) AS prev_amount
FROM payments;
LAG() сдвигает значение на одну строку назад внутри окна пользователя. Теперь можно сразу посчитать разницу между текущим и прошлым платежом:
SELECT
    user_id,
    amount,
    amount - LAG(amount) OVER (
        PARTITION BY user_id
        ORDER BY created_at
    ) AS diff
FROM payments;
Так удобно анализировать рост, падение и аномалии в данных без дополнительных JOIN. Можно находить моменты изменения значения, например смену статуса:
SELECT *
FROM (
    SELECT
        user_id,
        status,
        LAG(status) OVER (
            PARTITION BY user_id
            ORDER BY created_at
        ) AS prev_status
    FROM user_logs
) t
WHERE status <> prev_status;
Запрос покажет только строки, где статус изменился относительно предыдущего события. 🔥 LAG() часто используют для анализа трендов, поиска изменений, расчёта дельт и работы с временными рядами. ➡️ SQL Ready | #практика