Data Science. SQL hub
33K subscribers
846 photos
40 videos
36 files
912 links
По всем вопросам- @workakkk

@itchannels_telegram - 🔥лучшие ит-каналы

@ai_machinelearning_big_data - Machine learning

@pythonl - Python

@pythonlbooks- python книги📚

@datascienceiot - ml книги📚

РКН: https://vk.cc/cIi9vo
Download Telegram
🖥 Как обезопасить приложение от тяжёлых миграций, приводящих к блокированию запросов?

#PostgreSQL

Этот код не даёт 100% гарантии, а только уменьшает количество заблокированных запросов. После того, как блокировка взята, другие запросы, могут встать в очередь, ожидая отпускания блокировки.

Вначале каждой миграции, которая выполняется внутри транзакции, нужно изменить настройки конфигурации lock_timeout и statement_timeout и idle_in_transaction_session_timeout командой SET LOCAL. Действие SET LOCAL продолжается только до конца текущей транзакции, независимо от того, фиксируется она или нет. При выполнении такой команды вне блока транзакции выдаётся предупреждение и больше ничего не происходит.

/*
Здесь SQL команды для наката (или отката), которые не могут работать внутри транзакции
*/

BEGIN;
DO $$
DECLARE
exception_message text;
exception_context text;
BEGIN
/*
Задаёт максимальную длительность ожидания любым оператором получения блокировки таблицы, индекса, строки или другого объекта базы данных.
Если ожидание не закончилось за указанное время, оператор прерывается.
Это ограничение действует на каждую попытку получения блокировки по отдельности и применяется как к явным запросам блокировки
(например, LOCK TABLE или SELECT FOR UPDATE без NOWAIT), так и к неявным.
Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах.
*/
SET LOCAL lock_timeout TO '3s';
-- Максимальное время выполнения любого SQL запроса в этой транзакции. Если будет превышено, то транзакция откатится.
SET LOCAL statement_timeout TO '30min';
-- Максимальное время простаивания транзакции, PostgreSQL >= 10. Если будет превышено, то транзакция откатится.
SET LOCAL idle_in_transaction_session_timeout TO '10s';
EXCEPTION WHEN undefined_object THEN
GET STACKED DIAGNOSTICS
exception_message = MESSAGE_TEXT,
exception_context = PG_EXCEPTION_CONTEXT;
RAISE NOTICE '%', exception_context;
RAISE NOTICE '%', exception_message;
END $$;


/*
Здесь SQL команды для наката (или отката) внутри транзакции
*/
COMMIT;

/*
Здесь SQL команды для наката (или отката), которые не могут работать внутри транзакции
*/


Если транзакция откатится, то есть 2 варианта: запустить повторно во время меньших нагрузок или оптимизировать код миграции, чтобы свести к минимуму блокировки.

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
Работа_с_PostgreSQL_в_Python.pdf
804.4 KB
🖥 Работа с PostgreSQL в Python на русском

Подключение к БД
Создание таблиц
Вставка и извлечение данных
Обновление таблиц
Удаление строк

#doc #python #postgresql #russian

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Неожиданная находка, которая освобождает 20 GB неиспользованного индексного пространства.

Как освободить место без удаления индексов или данных
Раз в несколько месяцев мы получаем предупреждения от системы мониторинга базы данных о том, что свободное место скоро закончится. Обычно мы просто выделяем больше места и забываем об этом, однако в этот раз мы были на карантине и система была нагружена меньше, чем обычно. И тут мы подумали, что это хорошая возможность провести чистку.

Начнем с конца: в итоге нам удалось освободить более чем 70 GB не оптимизированного и неиспользуемого пространства без удаления индексов и данных.

Используя обычные приемы, такие как перестроение индексов и таблиц, мы очистили много пространства, но затем одна удивительная находка помогла нам освободить дополнительно примерно 20 GB неиспользуемых индексированных значений.

Читать

#postgresql

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 СОВЕТ: В SQL, если вы ищите «все строки без определенного значения» вывод не будет включать строки, содержащие NULL 😳

Мой коллега постоянно работает с базами данных и обнаружил это вчера на собственном горьком опыте.

Некоторым это может показаться неожиданным поведением для движков: #mysql, #postgresql.

Если вы хотите вывести NULL, используйте `val != 'crazy' OR val IS NULL`

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Как можно избежать усложнения запроса лишними CASE

Тут ниже представлена попытка заNULLить значение, если оно равно чему-то.
, CASE WHEN sdate = '1900-01-01' THEN NULL ELSE sdate END sdate
, CASE WHEN mdate = '1900-01-01' THEN NULL ELSE mdate END mdate


Но ведь в PostgreSQL есть функция nullif, которая делает ровно то же самое.
NULLIF(значение1, значение2)

Функция NULLIF выдаёт значение NULL, если значение1 равно значение2; в противном случае она возвращает значение1. Это может быть полезно для реализации обратной операции к COALESCE. В частности, для примера, показанного выше:

SELECT NULLIF(value, '(none)') ...

В данном примере если value равно (none), выдаётся null, а иначе возвращается значение value.

То есть в примере выше можно переписать короче и понятнее:
, NULLIF(sdate, '1900-01-01') sdate
, NULLIF(mdate, '1900-01-01') mdate


#PostgreSQL

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🌐 openHalo позволяет приложениям, написанным для MySQL, работать с PostgreSQL, предлагая при этом лучшую производительность, чем MySQL!

openHalo поддерживает диалект SQL MySQL и использует тот же протокол соединения, что позволяет легко адаптировать приложения с MySQL к openHalo с минимальными изменениями кода. Это значительно упрощает миграцию с MySQL 5.7 или новее на openHalo, делая процесс быстрее, безопаснее и экономичнее.

С openHalo вы получаете повышенную производительность без дополнительных усилий и затрат, особенно для сложных SQL-запросов. Вы можете продолжать использовать знакомые инструменты, команды и драйверы MySQL для разработки.

🔗 GitHub

#openHalo #MySQL #PostgreSQL #database #migration

@sqlhub
✔️ Wal-listener — это инструмент для прослушивания логов транзакций PostgreSQL (WAL) и конвертации их в удобный для обработки формат JSON.

Возможности

- Прослушивание изменений в PostgreSQL в режиме реального времени.
- Поддержка нескольких слотов репликации.
- Удобный вывод в формате JSON.
- Готов к использованию в качестве сервиса.

Пример использования

1. Создаём слот репликации:

SELECT * FROM pg_create_logical_replication_slot('test_slot', 'wal2json');


2. Запускаем wal-listener:

wal-listener --dsn "host=localhost port=5432 user=postgres dbname=test" --slot test_slot


3. Получаем JSON-объекты при изменениях в базе данных.

https://github.com/ihippik/wal-listener

#devops #девопс #PostgreSQL #sql

@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🧠 SQL-задача с подвохом: "Невидимые дубликаты"

В таблице users хранятся email-адреса пользователей. Некоторые юзеры регистрируются повторно, маскируя один и тот же email по-разному:

| id | name | email |
|----|----------|--------------------------|
| 1 | Alice | alice@example.com |
| 2 | Bob | ALICE@EXAMPLE.COM |
| 3 | Charlie | alice@example.com |
| 4 | Dave | alice+promo@example.com |
| 5 | Eve | a.l.i.c.e@example.com |


🎯 Цель:
Найти количество уникальных пользователей, если:
- Регистр не учитывается (`alice` = `ALICE`)
- Пробелы игнорируются
- Для @gmail.com:
— Убираются точки в имени
— Всё после + отрезается

SQL-решение:


SELECT COUNT(DISTINCT normalized_email) AS unique_users
FROM (
SELECT
CASE
WHEN email ILIKE '%@gmail.com' THEN
REGEXP_REPLACE(
SPLIT_PART(SPLIT_PART(LOWER(TRIM(email)), '+', 1), '@', 1),
'\.', '', 'g'
) || '@gmail.com'
ELSE
LOWER(REPLACE(TRIM(email), ' ', ''))
END AS normalized_email
FROM users
) AS cleaned;


🔍 Как это работает:

LOWER(TRIM(email)) — убираем пробелы и регистр

SPLIT_PART(..., '+', 1) — отрезаем всё после +

REGEXP_REPLACE(..., '\.', '', 'g') — удаляем точки

Считаем DISTINCT, чтобы получить число уникальных email'ов

🔥 Используй такие трюки для:
• антифрода
• чистки базы
• аналитики поведения пользователей

#SQL #PostgreSQL #Gmail #EmailNormalization #DevTools #AntiFraud #DataCleaning #Analytics
📦 Outbox — надёжная реализация outbox-паттерна на Go для микросервисов

Если твои сервисы пишут в базу и одновременно публикуют события в Kafka, RabbitMQ или другие брокеры — знай: без outbox-паттерна ты рискуешь потерять данные.

🔧 Outbox — это лёгкая и удобная библиотека на Go, которая помогает сделать доставку сообщений атомарной и надёжной, без лишней сложности.

🧠 Что она делает:

1. Сохраняет событие в таблицу outbox в рамках транзакции
2. Отдельный воркер читает сообщения и отправляет их в брокер
3. После успешной доставки — сообщение помечается как доставленное

💡 Особенности:

- Поддержка PostgreSQL
- Готовые адаптеры для Kafka и RabbitMQ
- Возможность использовать свой брокер (реализуй интерфейс)
- Поддержка сериализации / форматирования событий
- Использует sqlx и стандартную database/sql

🧩 Подходит для:

- надёжной синхронизации БД событий
- микросервисов, где важна консистентность
- систем, где нужна повторная доставка без дублей

🔥 Отличный выбор, если ты хочешь atomic-публикацию событий без тяжёлых фреймворков и сервисов.

#Go #OutboxPattern #Kafka #RabbitMQ #Microservices #EventDriven #PostgreSQL

🔗 https://github.com/oagudo/outbox

@sqlhub