SQL Academy: всё о реляционных БД и SQL
11.9K subscribers
184 photos
1 video
2 files
30 links
По всем вопросам и коммерческим предложениям писать @LadanovNick

Купить рекламу: https://telega.in/c/sqlacademyofficial

Чат студентов SQL Academy
https://t.me/sqlacademyorg
Download Telegram
🪞 Иллюзия скорости: почему обычный VIEW не ускорит запросы

Спрятал огромный JOIN в представление, чтобы база работала быстрее? Плохие новости: обычный VIEW вообще ничего не кэширует.

⚙️ Как это работает на самом деле
Многие путают представление с физической таблицей. Но обычный VIEW — это просто текстовый макрос.
🔹 Каждый раз, когда ты делаешь SELECT * FROM my_view, база берёт исходный запрос и выполняет его с нуля.
🔹 Никакие результаты на диск не сохраняются. Все тяжёлые вычисления будут происходить заново при каждом обращении.

⚠️ Опасность «матрёшки»
Самая частая ошибка — строить одни вьюшки поверх других.
🔸 База вынуждена разворачивать этот клубок в один гигантский запрос.
🔸 Планировщик запросов теряется в абстракциях и может выбрать худший план выполнения. То, что должно работать секунду, выполняется часами.

🚀 Что делать?
🔹 Для реального ускорения и сохранения результата на диск используй:
CREATE MATERIALIZED VIEW my_cache AS
SELECT ...

🔹 Обычный VIEW оставляй только для удобства: чтобы скрыть сложную логику от других разработчиков или упростить чтение кода.

💡 Обычное представление создано для чистоты кода, а не для производительности.
❤7👍6🔥1
♾️ Дырявый UNIQUE: как индекс пропускает дубликаты

Ты создал ограничение UNIQUE и уверен, что база под надёжной защитой. Но она радостно пропустит в таблицу хоть миллион строк с пустыми значениями.

⚙️ Почему так происходит
🔹 По стандарту SQL значение NULL означает «неизвестность».
🔹 Равна ли одна неизвестность другой? Нет. Правило гласит: NULL != NULL.
🔹 Раз пустые значения не равны друг другу, ограничение уникальности их пропускает. PostgreSQL, MySQL и Oracle позволят создавать бесконечные пустые профили.

CREATE TABLE users (
email VARCHAR(100) UNIQUE
);
-- База сохранит обе строки:
INSERT INTO users (email) VALUES (NULL), (NULL);


⚠️ Сюрприз от SQL Server
В MS SQL Server логика другая. Он считает NULL конкретным значением и разрешает добавить его только один раз. Вторая пустая строка выдаст ошибку.

🚀 Что делать
🔸 Если поле всегда должно быть заполнено — добавляй ограничение NOT NULL.
🔸 В PostgreSQL 15+ можно явно запретить дубликаты пустых строк правилом UNIQUE NULLS NOT DISTINCT.

💡 Уникальность защищает только известные данные, а для пустых нужны свои правила.
❤8👍7🤯2
⏳ Конец хаосу: почему UUIDv7 — хороший выбор для Primary Key
Обычный автоинкремент (ID=1, 2, 3), если показывать его наружу, позволяет конкурентам легко высчитать ваши продажи. А популярный случайный UUIDv4 незаметно снижает производительность базы.

⚠️ Две крайности старых подходов
🔷 Автоинкремент: быстрый и компактный, но раскрывает объёмы. Если зарегистрироваться дважды с разницей в день, конкурент узнает точное число ваших новых клиентов.
🔷 UUIDv4: абсолютно случаен. Каждая новая запись попадает в случайное место индекса. Это как вписывать новые контакты на случайные страницы бумажной телефонной книги: страницы приходится постоянно делить, индекс раздувается, а INSERT на больших таблицах замедляется.

🚀 Магия UUIDv7
Свежий стандарт (RFC 9562, 2024) решает обе проблемы. В начало ключа записывается текущее время (Timestamp) с точностью до миллисекунды, а остальная часть остаётся случайной.
-- PostgreSQL 18+
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT uuidv7(),
amount NUMERIC
);

В версиях до 18 нужно расширение pg_uuidv7 с функцией uuid_generate_v7().

📈 Что мы получаем
🔶 Новые записи ложатся в B-дерево почти последовательно, в конец индекса.
🔶 Индекс меньше раздувается, и вставка заметно быстрее, чем с UUIDv4.
🔶 Идентификаторы уникальны, и посчитать по ним объёмы нельзя. Но время создания записи из них читается.
💡 UUIDv7 — хороший компромисс: вставка почти как у счётчика, и объёмы не утекают. Но он вдвое больше bigint и не секрет: доступ к данным всё равно проверяйте на сервере.
🔥10❤7👍3🏆1