SQL Ready | Базы Данных
Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc
Show more📈 Analytical overview of Telegram channel SQL Ready | Базы Данных
Channel SQL Ready | Базы Данных (@sql_ready) in the Russian language segment is an active participant. Currently, the community unites 17 709 subscribers, ranking 7 345 in the Technologies & Applications category and 37 222 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 17 709 subscribers.
According to the latest data from 17 October, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 691 over the last 30 days and by 41 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 12.44%. Within the first 24 hours after publication, content typically collects 5.98% reactions from the total number of subscribers.
- Post reach: On average, each post receives 2 198 views. Within the first day, a publication typically gains 1 057 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 23.
- Thematic interests: Content is focused on key topics such as sql, строка, users, индекс, user_id.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc”
Thanks to the high frequency of updates (latest data received on 18 October, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
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
Оставляю ссылочку: GitHub 📱➡️ SQL Ready | #репозиторий
CHECK constraint требует, чтобы условие всегда было TRUE. Но это не так, CHECK запрещает только FALSE. А результат UNKNOWN — пропускается.
Именно поэтому nullable-колонки внутри CHECK могут вести себя не так, как ожидает разработчик.
Допустим, есть таблица товаров:
products(
id,
price,
discount
)
Хотим запретить скидку больше цены:
ALTER TABLE products
ADD CONSTRAINT chk_discount_price
CHECK (discount <= price);
На первый взгляд всё выглядит правильно.
Теперь такой INSERT действительно не пройдёт:
INSERT INTO products(id, price, discount)
VALUES (1, 100, 150);
Потому что проверка: 150 <= 100 даёт FALSE. А CHECK constraint запрещает строки, где выражение возвращает FALSE. Но дальше начинается важный нюанс SQL и трёхзначной логики.
Вот такой INSERT уже может пройти:
INSERT INTO products(id, price, discount)
VALUES (2, 100, NULL);
И такой тоже:
INSERT INTO products(id, price, discount)
VALUES (3, NULL, 50);
Многие ожидают, что CHECK отклонит такие строки. Но SQL работает иначе, если в сравнении участвует NULL, результатом становится не TRUE и не FALSE, а: UNKNOWN
То есть:
150 <= 100 -- FALSE
NULL <= 100 -- UNKNOWN
50 <= NULL -- UNKNOWN
NULL <= NULL -- UNKNOWN
И вот здесь самая важная мысль: CHECK constraint считает строку валидной, если результат выражения — TRUE или UNKNOWN. Запрещается только явно FALSE.
Это поведение связано с SQL three-valued logic — логикой с тремя состояниями: TRUE, FALSE и UNKNOWN. Именно поэтому CHECK сам по себе НЕ заменяет NOT NULL. Если колонка обязательная — это нужно указывать отдельно.
Правильный вариант:
CREATE TABLE products(
id bigint PRIMARY KEY,
price numeric NOT NULL,
discount numeric NOT NULL,
CONSTRAINT chk_discount_price
CHECK (discount <= price)
);
Теперь NULL уже не сможет пройти, потому что NOT NULL сработает раньше CHECK. Но в реальных системах скидка часто может отсутствовать. То есть NULL — это нормальное состояние: скидки нет.
В таком случае constraint лучше писать явно и читаемо:
ALTER TABLE products
ADD CONSTRAINT chk_discount_price
CHECK (
discount IS NULL
OR discount <= price
);
Такой вариант намного понятнее при чтении схемы. Он явно показывает бизнес-логику: либо скидки нет, либо она не больше цены. Но здесь есть ещё один тонкий момент.
Если price остаётся nullable: price numeric, то выражение: discount <= price снова может вернуть UNKNOWN. Например:
discount = 50
price = NULL
Результат проверки: 50 <= NULL, будет UNKNOWN, а строка снова станет валидной.
Поэтому если цена обязательна — нужен отдельный NOT NULL:
price numeric NOT NULL
Похожая ситуация встречается с датами. Например:
CHECK (end_date >= start_date)
Разработчик может думать, что constraint гарантирует корректный диапазон дат. Но если end_date nullable, такой CHECK спокойно пропускает:
end_date = NULL
потому что результат сравнения снова UNKNOWN.
И это может быть абсолютно нормальным поведением. Например, если NULL означает: период ещё не завершён. Но если обе даты обязательны, это нужно фиксировать явно:
start_date date NOT NULL,
end_date date NOT NULL,
CHECK (end_date >= start_date)
🔥 Вывод: если в CHECK участвуют nullable-поля, constraint может пропускать строки из-за UNKNOWN, CHECK не заменяет NOT NULL. Для обязательных значений всегда нужен отдельный NOT NULL constraint.
➡️ SQL Ready | #практикаSKIP LOCKED только для очередей через SELECT ... FOR UPDATE. Но мало кто использует его для параллельной пакетной обработки внутри PostgreSQL.
Если несколько воркеров одновременно обрабатывают огромную таблицу задач:
SELECT id
FROM jobs
WHERE processed = false
FOR UPDATE;
Без SKIP LOCKED процессы начинают ждать друг друга даже при наличии свободных строк.
PostgreSQL позволяет просто пропускать уже занятые записи:
SELECT id
FROM jobs
WHERE processed = false
FOR UPDATE SKIP LOCKED;
Теперь каждый воркер мгновенно получает только свободные строки без ожидания и конфликтов.
Это можно встроить прямо в UPDATE:
WITH cte AS (
SELECT id
FROM jobs
WHERE processed = false
LIMIT 100
FOR UPDATE SKIP LOCKED
)
UPDATE jobs
SET processed = true
WHERE id IN (SELECT id FROM cte);
Получается параллельная обработка на уровне PostgreSQL без внешних систем очередей.
🔥 Аналогично строят высоконагруженные фоновые обработчики, обработку писем, биллинг и массовые пакетные операции.
➡️ SQL Ready | #советusers(id, email)
orders(id, user_id)
Многие пытаются писать через NOT IN:
id="x8d2qa"
SELECT *
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Но здесь есть проблема: если подзапрос вернёт хотя бы один NULL, результат может стать пустым.
Причина — логика NULL в SQL ломает сравнение NOT IN.
Решением может служить антиджойн через NOT EXISTS:
id="m4z7pk"
SELECT *
FROM users u
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.id
);
SQL проверяет отсутствие связанной строки и сразу останавливается при первом совпадении.
Ту же задачу можно решить через LEFT JOIN:
id="f1q9vc"
SELECT u.*
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id
WHERE o.id IS NULL;
LEFT JOIN оставляет все строки users, а WHERE o.id IS NULL отбирает только те, где совпадений не нашлось.
Этот паттерн и называется антиджойн — верни строки, для которых связи не существует.
Особенно полезно это в проверках целостности данных:
id="k6n2yb"
SELECT *
FROM orders o
WHERE NOT EXISTS (
SELECT 1
FROM users u
WHERE u.id = o.user_id
);
Так можно быстро найти битые записи с отсутствующими foreign key.
🔥 Антиджойны пригодятся в аналитике, ETL, аудитах данных и поиске проблемных связей между таблицами.
➡️ SQL Ready | #практикаВ описании она выглядела скучно, а по факту - одна из самых интересных компаний, с которыми я общался.Весь процесс - от первого собеседования до оффера - занял 4 дня. P.S. Попробовать Софи бесплатно можно будет 16 июня. Не пропусти анонс здесь.
Оставляю ссылочку: GitHub 📱➡️ SQL Ready | #репозиторий
CHECK или FOREIGN KEY на большую таблицу рискованная операция, потому что PostgreSQL начинает сразу сканировать все старые данные.
ALTER TABLE orders
ADD CONSTRAINT orders_user_fk
FOREIGN KEY (user_id)
REFERENCES users(id);
На production-таблицах в сотни строк это может превратиться в очень долгую блокировку DDL.
Но в PostgreSQL есть фича — NOT VALID:
ALTER TABLE orders
ADD CONSTRAINT orders_price_check
CHECK (price > 0)
NOT VALID;
Без полного сканирования таблицы, сразу начинает проверять все новые записи. При этом старые строки пока не валидируются.
Позже ограничение можно провалидировать отдельно:
ALTER TABLE orders
VALIDATE CONSTRAINT orders_price_check;
Самое интересное — VALIDATE CONSTRAINT не блокирует обычный concurrent DML как классический ALTER TABLE.
То же самое работает и для FOREIGN KEY:
ALTER TABLE orders
ADD CONSTRAINT orders_user_fk
FOREIGN KEY (user_id)
REFERENCES users(id)
NOT VALID;
🔥 Это одна из самых полезных возможностей PostgreSQL для безопасных миграций, постепенного внедрения ограничений и наведения порядка в старых базах без длительного простоя.
➡️ SQL Ready | #советВ этой шпаргалке собраны ключевые команды для создания, изменения и удаления пользователей, назначения и отзыва прав, а также проверки текущих ролей и сессий. Они применяются при управлении безопасностью базы данных, настройке доступа и аналитической работе с ролями.
➡️ SQL Ready | #шпора