SQL Ready | Базы Данных
Авторский канал про Базы Данных и SQL Ресурсы, гайды, задачи, шпаргалки. Информация ежедневно пополняется! Cотрудничество: @energy_c РКН: https://clck.ru/3QREBc
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام SQL Ready | Базы Данных
تُعد قناة SQL Ready | Базы Данных (@sql_ready) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 17 741 مشتركاً، محتلاً المرتبة 7 336 في فئة التكنولوجيات والتطبيقات والمرتبة 37 136 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 17 741 مشتركاً.
بحسب آخر البيانات بتاريخ 18 أكتوبر, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار 696، وفي آخر 24 ساعة بمقدار 5، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 12.57%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 6.05% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 2 222 مشاهدة. وخلال اليوم الأول يجمع عادةً 1 069 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 23.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل sql, строка, users, индекс, user_id.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 19 أكتوبر, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
UNION удаляет дубликаты по всем выбранным колонкам, сравнивая строки целиком, поэтому результат может отличаться от ожиданий.
SELECT message FROM logs_app
UNION
SELECT message FROM logs_system;
Одинаковые message схлопнутся в одну строку, даже если это разные события — ошибки не будет.
UNION ALL не удаляет строки из результата запросов, поэтому почти всегда работает быстрее:
SELECT message FROM logs_app
UNION ALL
SELECT message FROM logs_system;
Для логов полезно явно добавлять источник:
SELECT 'app' AS src, id, message FROM logs_app
UNION ALL
SELECT 'system' AS src, id, message FROM logs_system
ORDER BY src, id;
Пересечение (INTERSECT) в MySQL не поддерживается, альтернатива:
SELECT DISTINCT a.message
FROM logs_app a
WHERE EXISTS (SELECT 1 FROM logs_system s WHERE s.message = a.message)
LIMIT 10;
Если хотите увидеть, какие строки пропадут при UNION из-за совпадений между таблицами, используйте UNION ALL и проверяйте строки, встречающиеся в обоих источниках:
SELECT message, COUNT(*) AS cnt, COUNT(DISTINCT src) AS sources
FROM (
SELECT message, 'app' AS src FROM logs_app
UNION ALL
SELECT message, 'system' AS src FROM logs_system
) t
GROUP BY message
HAVING sources > 1;
🔥 UNION — когда нужна дедупликация, UNION ALL — когда важна каждая строка и производительность.
➡️ SQL Ready | #практикаSkiplist ускоряет поиск в памяти, Hash-индекс даёт доступ за O(1), а B-tree и LSM-дерево оптимизируют работу с диском и записью.
На картинке — 8 структур данных, которые стоит держать под рукой, чтобы понимать, как устроены индексы и хранение в БД.
Сохрани, чтобы не забыть!
➡️ SQL Ready | #ресурсJOIN по колонке, которая логически должна совпадать в обоих наборах:
JOIN table_b b ON a.id = b.id
Выберите только ключи, чтобы исключить лишние проекции и ускорить анализ наборов:
SELECT a.id
Проверьте сами на интерактивном примере:
CREATE TABLE table_a(id int);
CREATE TABLE table_b(id int);
INSERT INTO table_a VALUES (1),(2),(3);
INSERT INTO table_b VALUES (2),(3),(4);
Повторите исходный JOIN, вы увидите только 2,3 как пересечение наборов.
🔥 Пригодится, когда нужно сверить итерации, найти общие сущности перед миграциями и тд.
➡️ SQL Ready | #советПолучаем платную версию:🤩🤩🤩🤩🤩🤩🔐
Оживляем фото, генерим студийную фотосессию с собой 💪
Делаем из нейронки флирт бота влюбляем в себя любую ❤️
Зарабатываем на крипте с помощью прогнозов нейронки 💸
Снимаем цензуру одним промтом🤬
Как сделать из нейронки помощника или друга ✍️
Решаем любую домашку одной фоткой 📸
UPDATE:
WITH c AS (SELECT id FROM products WHERE price < 0 LIMIT 3)
CTE c вернёт проблемные id.
Теперь обновим только найденные строки, не дублируя условие в клиенте:
UPDATE products SET price = 0
Ссылаемся на выборку из CTE, чтобы не рассинхронизировать find/update:
WHERE id IN (SELECT id FROM c);
Попробуйте сами на тестовой таблице:
CREATE TABLE products(id int PRIMARY KEY, price int);
INSERT INTO products VALUES (1,-10),(2,-5),(3,100);
Запустите find+update снова и убедитесь, что исправление точечное и атомарное.
🔥 Экономит время выравнивания таблиц при интеграциях, корректировки классификаторов или миграций и др.
➡️ SQL Ready | #советОставляю ссылочку: GitHub 📱➡️ SQL Ready | #репозиторий
FOR UPDATE SKIP LOCKED
Строки, которые уже залочены, исключаются из выборки немедленно, без ожидания.
Хотите повторить интерактивно? Откройте 2 SQL-сессии:
Сессия A:
BEGIN;
SELECT id FROM jobs WHERE status='queued' FOR UPDATE;
Сессия B (параллельно):
BEGIN;
SELECT id FROM jobs WHERE status='queued' FOR UPDATE SKIP LOCKED LIMIT 1;
B никогда не вернёт строку, залоченную A, и не будет ждать, вы увидите разные результаты в разных сессиях.
🔥 База данных сама может быть механизмом синхронизации, если выборка делается с SKIP LOCKED. Нет двойной обработки, ожиданий и внешних зависимостей.
➡️ SQL Ready | #советTRANSACTION при автокоммите каждый UPDATE фиксируется отдельно — и есть риск получить несогласованное состояние.
Таблицы:
wallet(user_id, balance)
payments(id, user_id, amount, status)
Сценарий: списать баланс и перевести платёж в done.
Если соединение обрывается между запросами:
UPDATE wallet SET balance = balance - 100 WHERE user_id = 7;
-- сбой соединения тут
UPDATE payments SET status = 'done' WHERE id = 55;
Первое изменение уже сохранено, второе — нет. Итог: деньги списаны, платёж не подтверждён.
Правильный подход — транзакция:
BEGIN;
UPDATE wallet SET balance = balance - 100 WHERE user_id = 7;
UPDATE payments SET status = 'done' WHERE id = 55;
COMMIT;
До COMMIT изменения видны только в текущей сессии и не становятся устойчивыми. Если все шаги успешны — фиксируется сразу всё.
Откат при ошибке:
BEGIN;
UPDATE wallet SET balance = balance - 100 WHERE user_id = 7;
UPDATE payments SET status = 'done' WHERE id = 55;
ROLLBACK;
Пока сессия жива, открытая транзакция не откатывается сама по себе и может удерживать блокировки. Автоматический ROLLBACK происходит именно при разрыве соединения или явном откате.
Нюанс для защиты от гонок и повторной обработки:
UPDATE wallet
SET balance = balance - 100
WHERE user_id = 7 AND balance >= 100;
UPDATE payments
SET status = 'done'
WHERE id = 55 AND status = 'pending';
Оба UPDATE выполняем в одной транзакции, затем проверяем rowcount: если любой запрос затронул 0 строк — ROLLBACK и обработка как ошибка.
🔥 SELECT ... FOR UPDATE также работает только в той же транзакции, где будет обновление. Любая операция списания + фиксации платежа = транзакция.
➡️ SQL Ready | #практикаUPDATE может перезаписывать строку, даже если значение не изменилось.
IS DISTINCT FROM сравнивает значения NULL-безопасно и без UNKNOWN:
AND u.name IS DISTINCT FROM 'Alice';
Если name уже Alice — условие ложно, и строка не обновляется вообще.
Это правило можно применить к любым колонкам:
AND u.email IS DISTINCT FROM EXCLUDED.email;
Паттерн остаётся тем же: обновление только при расхождении.
Проверьте сами на тесте:
CREATE TABLE users(id int PRIMARY KEY, name text);
INSERT INTO users VALUES (1, 'Bob');
Запустите 2 раза UPDATE сверху, второй раз таблица не изменится и ничего не запишет.
🔥 UPDATE должен менять только то, что отличается и SQL уже даёт для этого инструменты.
➡️ SQL Ready | #советproducts(id, category, price)
Нужно выбрать самый дорогой товар в каждой категории, но при этом видеть все колонки строки:
SELECT *
FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC, id DESC) AS rn
FROM products
) t
WHERE rn = 1;
PARTITION BY формирует независимые окна для каждой категории.
ROW_NUMBER() нумерует строки внутри каждой партиции, а не по всей таблице.
Если нужны не только первые, а, например, топ-3 в каждой категории:
SELECT id, category, price
FROM (
SELECT
id, category, price,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC, id DESC) AS rn
FROM products
) t
WHERE rn <= 3
ORDER BY category, price DESC;
Тут важно: без PARTITION BY запрос взял бы топ-3 по всей таблице, а не по категориям.
Оконные функции не требуют GROUP BY, потому что не агрегируют (не схлопывают) строки, а дополняют их аналитическими метками.
Ещё полезный трюк — находить максимум в группе без GROUP BY и JOIN, через коррелированный подзапрос:
SELECT *
FROM products
WHERE price = (
SELECT MAX(price)
FROM products p2
WHERE p2.category = products.category
);
Этот запрос не агрегирует основную таблицу и вернёт несколько строк, если в категории есть товары с одинаковой максимальной ценой (ties).
🔥 Используйте PARTITION BY в оконных функциях, когда логика должна применяться внутри каждой группы независимо, а строки нужно сохранить целиком.
➡️ SQL Ready | #практика