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

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

Відкрити в Telegram

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

Показати більше

📈 Аналітичний огляд Telegram-каналу SQL Ready | Базы Данных

Канал SQL Ready | Базы Данных (@sql_ready) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 16 616 підписників, посідаючи 7 640 місце в категорії Технології та додатки та 39 717 місце у регіоні Росія.

📊 Показники аудиторії та динаміка

З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 16 616 підписників.

За останніми даними від 01 вересня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на 1 233, а за останні 24 години на -2, загальне охоплення залишається високим.

  • Статус верифікації: Не верифікований
  • Рівень залученості (ER): Середній показник залученості аудиторії становить 12.49%. Протягом перших 24 годин після публікації контент зазвичай збирає 6.17% реакцій від загальної кількості підписників.
  • Охоплення публікацій: В середньому кожен допис отримує 2 075 переглядів. Протягом першої доби публікація в середньому набирає 1 025 переглядів.
  • Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 23.
  • Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як sql, строка, users, индекс, user_id.

📝 Опис та контентна політика

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

Завдяки високій частоті оновлень (останні дані отримано 02 вересня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.

16 616
Підписники
-224 години
+907 днів
+1 23330 днів
Архів дописів
0nix — Новая экосистема для профи. Здесь не просто форум. Это готовая биржа, где заказчики находят исполнителей, а исполнители — живые деньги. 🛡Для кибербезопасников: Threat Intelligence, Осинтеров , Геоинтеров, Red Team, разработчиков инструментов. Ваша аудитория ждет ваши услуги. 💻 Для разработчиков и дизайнеров: Отдельные разделы с заказами на разработку, дизайн и графику. Портфолио — в топ! Условия для первых участников: Минимальные комиссии на сделки, быстрый арбитраж и модерация. Регистрируйся и забирай свою скидку на привилегии уже сегодня → 0nix.cc , 0nix.top

Разбираем почему ORDER BY RANDOM() на больших таблицах не лучшая идея! Если нужно вытащить случайные строки из таблицы, многие пишут так, например в PostgreSQL:
SELECT *
FROM products
ORDER BY RANDOM()
LIMIT 10;
На первый взгляд всё отлично: перемешали строки и взяли первые 10. Но под капотом всё не так красиво. Обычно база читает много строк, а часто вообще всю таблицу, затем вычисляет случайное значение для каждой строки, сортирует результат и только после этого применяет LIMIT. То есть даже если нужна всего одна строка:
SELECT *
FROM products
ORDER BY RANDOM()
LIMIT 1;
на большой таблице это всё равно может оказаться тяжёлым запросом. Если строк миллионы, начинаются проблемы с CPU, памятью, сортировками и latency. Индексы здесь обычно не помогают. Один из более дешёвых вариантов — случайный выбор через id:
SELECT *
FROM products
WHERE id >= 1 + FLOOR(RANDOM() * (SELECT MAX(id) FROM products))::int
ORDER BY id
LIMIT 1;
Этот вариант уже может использовать индекс по id. Но есть нюанс: если после удалений в id много дырок, распределение будет неидеальным. Например:
id
1
2
3
10000
10001
В таком случае чаще будет выпадать первая существующая строка после большого разрыва — здесь это 10000. То есть выборка получается смещённой. Ещё один вариант — случайный OFFSET:
SELECT *
FROM products
OFFSET FLOOR(RANDOM() * (SELECT COUNT(*) FROM products))::int
LIMIT 1;
Звучит неплохо. Но у OFFSET тоже есть проблема: чем больше offset, тем больше строк базе придётся пропустить. Плюс в PostgreSQL COUNT(*) на большой таблице тоже может быть дорогой операцией. В PostgreSQL есть ещё TABLESAMPLE:
SELECT *
FROM products TABLESAMPLE SYSTEM (1);
Или:
SELECT *
FROM products TABLESAMPLE BERNOULLI (1);
На больших таблицах это часто работает заметно быстрее. Но важно понимать: TABLESAMPLE выбирает примерный процент таблицы, а не конкретное количество строк. Если нужно, например, 10 строк, обычно добавляют LIMIT:
SELECT *
FROM products TABLESAMPLE SYSTEM (1)
LIMIT 10;
Но и тут есть нюанс: если sample слишком маленький, запрос может вернуть меньше 10 строк. И здесь тоже есть компромисс между скоростью и качеством случайной выборки. SYSTEM работает быстрее, но выбирает данные блоками, поэтому распределение менее равномерное. BERNOULLI ближе к построчной случайной выборке, но обычно дороже. В общем, мысль простая:
ORDER BY RANDOM()
выглядит красиво и удобно. Но на больших таблицах это один из тех запросов, которые начинают стоить очень дорого. 🔥 Именно такие простые запросы часто становятся причиной деградации производительности в продакшн. ➡️ SQL Ready | #практика

❤️‍🔥"Это разъ*бный сетап, бро!" 😤 Так сказал мой друг из Африки, когда увидел этот стол) Не знаю уж че за сетап, меня зовут Саша и качественную необычную мебель из натурального дерева я делаю уже больше 12-ти лет, столько же занимаюсь и темой здоровья. Когда я услышал, что до 10% смертности связано с сидячим образом жизни, меня это поразило и я задался целью делать максимально функциональные и полезные рабочие пространства, ибо геморрой в 30 это конечно довольно нишево, но все же сомнительно 😂 Ну а собрать такой комплект под свои задачи и при этом сразу прикинуть цены вы можете в удобном Mini App конструкторе

Разбор JSON в строки на стороне PostgreSQL! Когда из API прилетает массив объектов, не обязательно разбирать его в коде и дел
Разбор JSON в строки на стороне PostgreSQL! Когда из API прилетает массив объектов, не обязательно разбирать его в коде и делать много отдельных INSERT или UPDATE. PostgreSQL умеет превратить JSON-массив в обычную табличную выборку.
SELECT *
FROM jsonb_to_recordset($1::jsonb)
AS x(id bigint, amount numeric);
На вход можно передать JSON вида [{"id":1,"amount":500},{"id":2,"amount":900}], а на выходе получить нормальные типизированные строки.
INSERT INTO payments (id, amount)
SELECT id, amount
FROM jsonb_to_recordset($1::jsonb)
AS x(id bigint, amount numeric);
Это особенно удобно для пакетных загрузок, импорта данных, обработки вебхуков и синхронизации с внешними сервисами.
UPDATE payments p
SET amount = x.amount
FROM jsonb_to_recordset($1::jsonb)
AS x(id bigint, amount numeric)
WHERE p.id = x.id;
Главный плюс в том, что приложение передаёт один JSON-параметр, а вся пакетная обработка происходит внутри базы одним запросом. 🔥 Такой приём убирает циклы в коде, уменьшает количество запросов к базе и делает массовые операции намного чище. ➡️ SQL Ready | #совет

👍 ClickHouse + PostgreSQL — интеграция OLTP и OLAP для аналитики! На странице собрана официальная документация ClickHouse по работе с PostgreSQL. Здесь подробно разбираются импорт данных, репликация таблиц, синхронизация и выполнение запросов к PostgreSQL напрямую из ClickHouse. Также есть примеры настройки и практические сценарии использования. 📌 Оставляю ссылочку: clickhouse.com ➡️ SQL Ready | #ресурс

Lost Update: почему транзакций недостаточно без правильной модели конкурентного доступа! Очень распространённое заблуждение: если запросы выполняются внутри транзакции — значит данные уже защищены от гонок, но это не так. Одна из классических проблем конкурентного доступа — lost update. Например, есть таблица:
accounts(id, balance)
Текущий баланс:
id | balance
1  | 1000
Два запроса одновременно читают баланс:
SELECT balance
FROM accounts
WHERE id = 1;
Оба получают: 1000. Дальше: первый процесс хочет списать 100; второй — 200. Первый считает: 1000 - 100 = 900. Второй: 1000 - 200 = 800. После этого выполняются:
UPDATE accounts
SET balance = 900
WHERE id = 1;
а также:
UPDATE accounts
SET balance = 800
WHERE id = 1;
В итоге финальный баланс: 800, хотя математически должен быть: 700, одно обновление потерялось. Это и есть lost update. И самое неприятное — такое может происходить даже внутри транзакций. Всё зависит от уровня изоляции, паттерна обновления и механики блокировок конкретной СУБД. Очень частая ошибка выглядит так:
BEGIN;

SELECT balance
FROM accounts
WHERE id = 1;

-- вычисления в приложении

UPDATE accounts
SET balance = :new_balance
WHERE id = 1;

COMMIT;
Проблема в том, что между SELECT и UPDATE другая транзакция может изменить строку. Один из самых надёжных вариантов — атомарное обновление:
UPDATE accounts
SET balance = balance - 100
WHERE id = 1;
Теперь вычисление происходит внутри самого UPDATE. СУБД выполняет обновление на основе актуального значения строки и использует необходимые механизмы блокировок для корректной синхронизации конкурентных изменений. Это намного безопаснее. Ещё один вариант — pessimistic locking:
SELECT balance
FROM accounts
WHERE id = 1
FOR UPDATE;
FOR UPDATE ставит row-level lock. Пока транзакция не завершится, другая транзакция не сможет изменить эту строку или получить несовместимую блокировку на неё. Но здесь есть trade-off, чем больше блокировок: тем выше contention; тем ниже concurrency; тем выше риск deadlock. Ещё один подход — optimistic locking. Например:
accounts(id, balance, version)
Чтение:
SELECT balance, version
FROM accounts
WHERE id = 1;
Обновление:
UPDATE accounts
SET
  balance = :new_balance,
  version = version + 1
WHERE
  id = 1
  AND version = 5;
Если другая транзакция уже изменила строку — UPDATE затронет 0 строк. Приложение понимает: данные устарели, нужно перечитать и повторить операцию. Ещё важно понимать: READ COMMITTED, REPEATABLE READ, SERIALIZABLE ведут себя по-разному в разных СУБД. Например, PostgreSQL и MySQL (InnoDB) используют разные механизмы MVCC и имеют различия в поведении блокировок и уровней изоляции. 🔥 Главное правило, если логика выглядит как: прочитал значение — изменил в приложении — записал обратно, то всегда стоит проверять, не появляется ли lost update при параллельных запросах. ➡️ SQL Ready | #практика

Изоляция рунета произошла быстрее, чем ты думал
Loading ██████████████] 99%
Роскомнадзору воспользовался карт-бланшем на блокировку, а «белые списки» сайтов внедрены уже во всех регионах. И гайки будут закручиваться только сильнее. Чтобы в одночасье не лишиться доступа к свободному Интернету, просто сохрани Only Hack. Тут профессиональный хакер делится фишками, с которыми доступ к глобальной сети у тебя будет даже в случае ядерного апокалипсиса. Не жди момента «Х». Перестрахуйся подпиской.

👍 PostgreSQL Performance Essentials — практическое руководство по оптимизации PostgreSQL! Этот репозиторий особенно полезен тем, кто уже работает с PostgreSQL и хочет больше разобраться в производительности базы данных. Здесь хорошо показано, как анализировать запросы, понимать execution plan и находить узкие места, которые замедляют работу приложения.
Оставляю ссылочку: GitHub 📱
➡️ SQL Ready | #репозиторий

Транзакционная блокировка без блокировки строк! Иногда нужно запретить параллельную обработку одного объекта, но подходящей с
Транзакционная блокировка без блокировки строк! Иногда нужно запретить параллельную обработку одного объекта, но подходящей строки для FOR UPDATE ещё может не быть.
SELECT pg_advisory_xact_lock(10, 42);
pg_advisory_xact_lock создаёт транзакционную пользовательскую блокировку. Первый аргумент удобно использовать как namespace, второй — как id объекта.
SELECT pg_advisory_xact_lock(20, user_id);
Пока транзакция не завершится, другой процесс с тем же ключом будет ждать. После COMMIT или ROLLBACK блокировка снимается автоматически.
SELECT pg_try_advisory_xact_lock(20, user_id);
Если ждать нельзя, используй pg_try_advisory_xact_lock: он сразу вернёт true или false, и приложение сможет аккуратно пропустить задачу.
BEGIN;
SELECT pg_advisory_xact_lock(30, 123);
UPDATE invoices SET status = 'paid' WHERE id = 123;
COMMIT;
advisory lock не блокирует таблицу и не заменяет ограничения БД. Это кооперативная блокировка, поэтому все участники должны использовать один и тот же ключ. 🔥 Полезно для идемпотентных операций, генерации документов, биллинга, обработки вебхуков и любых мест, где один и тот же объект нельзя обрабатывать параллельно. ➡️ SQL Ready | #совет

Сидеть и работать в корпорации — страшно, жизнь-то мимо проходит. Уходить строить бизнес — страшно, а вдруг прогорит. Один из вариантов — разрабатывать свой пет-проект по вечерам. Многие успешные компании, например, Twitter, создавались именно так. Это не значит, что ваш проект обязательно заработает миллиарды, но заработать больше, чем в найме, и получить ценный опыт — вполне реально. Перед началом разработки появляется множество вопросов, например: • Как выбрать идею для пет-проекта? • Что нужно знать про маркетинг • Как запуститься и довести до первых продаж не имея бюджета на рекламу? В телеграм-канале «Твой пет проект», Михаил Табунов делится своим опытом с разработчиками и менеджерами. Он рассказывает, где искать идею для нового проекта, что нужно знать о маркетинге, как запустить стартап и привлечь первых 10 клиентов, а также о многих других важных вещах. Подписывайтесь на «Твой пет проект», получайте пользу от практиков рынка! https://t.me/+8Frwa03ciVlhNTky

🐱 SQL Window Functions — информативный гайд по оконным функциям в SQL! Отличный ресурс для тех, кто хочет разобраться в SQL и освоить оконные функции. На сайте подробно объясняются инструменты для аналитики и сложной обработки данных. Всё сопровождается наглядными примерами и практическими кейсами. 📌 Оставляю ссылочку: antonz.org ➡️ SQL Ready | #ресурс

📂 Напоминалка по MongoDB и шардированию! Например, Query Router (mongos) принимает запросы от приложения и распределяет их п
📂 Напоминалка по MongoDB и шардированию! Например, Query Router (mongos) принимает запросы от приложения и распределяет их по нужным шардам, а Replica Set внутри каждого shard обеспечивает отказоустойчивость и репликацию данных. На картинке — базовая архитектура MongoDB Cluster: Client Application, Driver, Query Router, Config Server и Shards с Primary/Secondary-нодами. Сохрани, чтобы не потерять! ➡️ SQL Ready | #ресурс

💅 Структурированный справочник по MySQL! Репозиторий представляет собой структурированную базу знаний по MySQL, где собраны как основы работы с базами данных, так и более сложные темы. Материал подан в формате конспекта, поэтому его удобно использовать и для изучения, и для быстрого повторения перед собеседованием или рабочими задачами.
Оставляю ссылочку: GitHub 📱
➡️ SQL Ready | #репозиторий

N+1 проблема в SQL: почему приложение внезапно начинает делать тысячи запросов! Одна из самых частых проблем backend-приложений — N+1 queries. Особенно часто это появляется при работе через ORM, потому что код выглядит нормально, а реальные SQL-запросы скрыты внутри слоя абстракции. Например, есть таблицы:
users(id, name)
orders(id, user_id, amount)
Сначала приложение получает пользователей:
SELECT
    id,
    name
FROM users;
Допустим, запрос вернул 1000 пользователей. Дальше приложение начинает отдельно загружать заказы для каждого пользователя:
SELECT
    id,
    user_id,
    amount
FROM orders
WHERE user_id = ?;
И этот запрос выполняется уже 1000 раз. То есть итоговая схема выглядит так: 1 запрос на получение users, N запросов на получение orders. Это и есть классическая N+1 problem. В ORM это обычно выглядит примерно так:
users = User.objects.all()

for user in users:
    orders = list(user.order_set.all())
    print(orders)
Внешне код выглядит абсолютно нормально, но внутри ORM может выполнять отдельный SELECT для каждого user.order_set.all(). На маленьких объемах данных проблема почти незаметна. Но на продакшене начинают быстро расти: latency, network overhead, нагрузка на connection pool, время ответа API, нагрузка на БД. Особенно неприятно это проявляется при pagination, background jobs и high-load API. Обычно данные эффективнее загружать набором. Например, через JOIN:
SELECT
    u.id,
    u.name,
    o.id,
    o.amount
FROM users u
LEFT JOIN orders o
    ON o.user_id = u.id;
Либо через batch loading:
SELECT
    id,
    user_id,
    amount
FROM orders
WHERE user_id IN (?, ?, ?, ...);
Во многих случаях batch loading даже эффективнее огромного JOIN, потому что JOIN может раздувать result set и создавать большое количество дублирующихся строк при one-to-many связях. Поэтому современные ORM обычно уже имеют встроенные механизмы борьбы с N+1. Например, в Django:
User.objects.prefetch_related("order_set")
User.objects.select_related("profile")
prefetch_related() обычно используется для reverse FK и many-to-many; select_related() — для FK и OneToOne. В SQLAlchemy:
select(User).options(
    selectinload(User.orders)
)
Отдельная проблема — nested N+1:
users
→ orders
→ payments
→ items
И приложение внезапно начинает выполнять уже сотни, тысячи или даже десятки тысяч SQL-запросов. Самое опасное — проблема часто долго остается незаметной, пока объем данных не вырастает. 🔥 Если внутри цикла потенциально выполняется SQL-запрос — почти всегда стоит проверить код на N+1. Именно поэтому profiling SQL-запросов и понимание того, как ORM реально работает с базой, критично для продакшн backend-разработки. ➡️ SQL Ready | #практика

В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн Но где их находить? Как узнавать о них ран
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда? Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России 📆 в канале размещаются как онлайн, так и оффлайн мероприятия; 👩‍💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие; 🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах: 🚀 IT-мероприятия Россииподписывайся и будь в курсе всех предстоящих мероприятий!

🧐 PostgreSQL в Selectel — статьи, гайды и практические кейсы по PostgreSQL! Это подборка материалов по PostgreSQL: настройка и администрирование баз данных, оптимизация запросов, репликация, резервное копирование, индексы, мониторинг и др. темы. Помимо теории, здесь много практических статей и кейсов, которые помогают лучше понять работу PostgreSQL и применять полученные знания. 📌 Оставляю ссылочку: selectel.ru ➡️ SQL Ready | #ресурс

PostgreSQL умеет замораживать часть запроса и запрещать оптимизатору его разворачивать! Начиная с PostgreSQL 12 оптимизатор п
PostgreSQL умеет замораживать часть запроса и запрещать оптимизатору его разворачивать! Начиная с PostgreSQL 12 оптимизатор получил право разворачивать CTE прямо внутрь основного запроса.
WITH data AS (
  SELECT *
  FROM orders
)
SELECT *
FROM data
WHERE user_id = 42;
Такой WITH может вообще исчезнуть из плана выполнения, потому что PostgreSQL встроит его обратно в запрос. Но иногда это плохо. Например, если внутри CTE дорогой расчёт, который нельзя выполнять повторно. Тут появляется малоизвестная фича:
WITH expensive AS MATERIALIZED (
  SELECT *
  FROM huge_events
  WHERE created_at >= now() - interval '1 day'
)
SELECT COUNT(*)
FROM expensive;
MATERIALIZED заставляет PostgreSQL сначала физически вычислить CTE, а потом использовать результат дальше. А обратная фича:
WITH data AS NOT MATERIALIZED (
  SELECT *
  FROM orders
)
SELECT *
FROM data
WHERE user_id = 42;
наоборот подсказывает оптимизатору агрессивно встраивать CTE обратно в запрос. 🔥 Одна и та же CTE с MATERIALIZED и без него иногда отличается по производительности в десятки раз на больших объёмах данных. ➡️ SQL Ready | #совет

📝 Собран список свежих сервисов и нейронок за неделю: 🥩 Сгенерируй готовую презентацию по одной ссылке [открыть] 📇 Собери
📝 Собран список свежих сервисов и нейронок за неделю:
🥩 Сгенерируй готовую презентацию по одной ссылке [открыть] 📇 Собери досье на любого человека по никнейму [открыть] 🕵️‍♂️ Открой сборник детективных загадок и разгадай их [открыть] 🎧 Получи бесконечный плейлист под любой вайб [открыть] 💻 Создай любой сайт со смартфона за 10 минут [открыть]
На канале «Будущее сегодня» публикуют все последние новости из мира технологий для русскоязычной аудитории 🌐 📁 Собрано 99+ самых полезных и интересных сервисов, сохрани: @futurenow

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