Базы данных (Data Base)
8.2K subscribers
579 photos
468 videos
19 files
558 links
Базы данных (Data Base). По всем вопросам @evgenycarter
Download Telegram
Представления в SQL

Здравствуйте, в этой статье будут разобраны представления или view в SQL. На простых примерах объясним как создавать представления и как к ним обращаться. Также затронем понятие модифицируемого представления в SQL.

https://telegra.ph/Predstavleniya-v-SQL-06-18

#SQL

👉 @database_info
5👍2👎1
Самоучитель по SQL

Наш самоучитель по SQL научит вас использовать SQL в: MySQL, SQL Server, MS Access, Oracle, Sybase, Informix, Postgres и других системах баз данных.

https://www.w3schools.com/sql/default.asp

#db #sql

👉 @database_info
👍4😁1
This media is not supported in your browser
VIEW IN TELEGRAM
Получение значений из строк N до/после текущей строки с помощью 2-го параметра LAG/LEAD

например.

LAG ( ..., 2 ) OVER ( ORDER BY ... ) = 2 before
LEAD ( ..., 3 ) OVER ( ORDER BY ... ) = 3 after


За пределами first/last row => возвращаем null

Используйте 3-й параметр, чтобы вернуть значение по умолчанию

#db #sql

👉 @database_info
👍5🥰2
Находим первое, N-ое или последнее значение в SQL

FIRST_VALUE ( val ) - Start val
NTH_VALUE ( val, N ) - Val at row N
LAST_VALUE ( val ) - Final val


Условие OVER определяет порядок

Будьте осторожны с использованием значения по умолчанию - оно останавливает NTH и LAST на текущем значении => неожиданные результаты

#db #sql

👉 @database_info
👍4🥰32
Media is too big
VIEW IN TELEGRAM
Практические примеры по оптимизации запросов в PostgeSQL
Иван Чувашов

источник

#db #sql #postgesql

👉 @database_info
👍4
Media is too big
VIEW IN TELEGRAM
SQL injection - почему, зачем и как защититься от SQL инъекции

В этом видио хотелось бы поговорить про очень опасную на мой взгляд хакерскую атаку SQL Injection. Это одна из старейших атак и она все ещё актуальна. Сегодня мы рассмотрим примеры использования SQL Injection на примере небольшого C# приложения. В других языках программирования и фреймворках все работает идентично.

источник

#sql

👉 @database_info
👍3
Media is too big
VIEW IN TELEGRAM
SQL Injection - теория и примеры

В прошлом видео я поспешил рассказать и показать SQL Injection на практике, а в этом видео я хочу сделать шаг назад и поговорить чуть больше о теории и больше рассмотреть небольших примеров.

источник

#sql

👉 @database_info
👍5
Как найти дубли в sql

Для того чтобы найти дубликаты в базе данных SQL, можно использовать операторы SELECT и GROUP BY совместно с оператором HAVING. Например, следующий запрос позволяет найти все строки, у которых значение определенного столбца повторяется более одного раза:


SELECT столбец, COUNT(*) AS количество
FROM таблица
GROUP BY столбец
HAVING COUNT(*) > 1;

Этот запрос выведет все уникальные значения столбца "столбец", а также количество раз, которое каждое значение повторяется в таблице. Результатом будут только те строки, где значение столбца повторяется более одного раза, что указывает на наличие дубликатов.

Также можно использовать операторы JOIN или подзапросы для более сложных запросов на поиск дубликатов. Важно помнить, что перед выполнением подобных операций на поиск дубликатов необходимо создать резервную копию базы данных или таблицы, чтобы избежать потери данных.

#sql

👉 @database_info
👍3
Совет по работе с базой данных💡

Дубликаты строк легко создаются по ошибке и почти так же легко удаляются: вы можете в *одном* SQL-запросе определить их, а также указать, какой из них оставить!

Вот самый быстрый способ 👆

#sql

👉 @database_info
👍3
Писать чистый SQL проще с pgx и sqlc в Go


Что такое pgx и sqlc?

pgx: это надежный набор инструментов и драйвер для PostgreSQL в Golang. Этот модуль также предоставляет полезные инструменты для облегчения работы со сложными запросами, делая их менее подверженными ошибкам.

sqlc: это инструмент для генерации кода, который преобразует ваши SQL-запросы в файлах .sql в Go-код с типобезопасностью как для параметров запроса, так и для результатов. Пример можно посмотреть здесь: sqlc playground. sqlc также поддерживает pgx "из коробки", что делает эту комбинацию отличным решением для работы с базами данных.

https://remvn.dev/posts/writing-raw-sql-easier-with-pgx-and-sqlc-in-go/

#sql

👉 @database_info
👍2
Курс по SQLAlchemy. Часть 1

Зачем Учить SQLAlchemy ORM
Подключение к Базе Данных, сырые SQL запросы через engine #2
Создание таблиц и вставка данных через Core #3
Session и первые шаги в ORM #4
Создание таблиц через КЛАССЫ - Mapped и mapped_column #5
SELECT и UPDATE запросы через ORM и Core #6
Базовые SELECT запросы #7

источник

#SQL

👉 @database_info
👍9🔥1
Антипаттерн: N+1 запросов — как заметить и починить

Вы берёте список сущностей, а потом в цикле для каждой тянете связанные данные. В итоге - 1 запрос за «родителями» + N запросов за «детьми». Латентность растёт линейно от размера выборки.

Симптомы

- В логах много одинаковых коротких запросов.
- Кол-во запросов ≈ размеру списка.
- Страница/endpoint сильно «замедляется» при росте данных.

Плохой пример (SQL + псевдокод)


-- Берём пользователей
SELECT id, name FROM users WHERE active = true;

-- Потом в цикле по каждому:
SELECT count(*) FROM orders WHERE user_id = :id;


Правильно (SQL, PostgreSQL) — сетевое мышление:


SELECT u.id,
u.name,
count(o.*) AS orders_cnt
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.active = true
GROUP BY u.id, u.name;


Django ORM


# Плохо: в шаблоне/цикле обращаемся к user.orders -> N+1
users = User.objects.filter(active=True)

# Хорошо: подгрузим связи заранее
users = (User.objects
.filter(active=True)
.prefetch_related('orders')) # для 1:N
# для 1:1 / ForeignKey используйте select_related('profile')

# Агрегация без цикла
from django.db.models import Count
users = (User.objects.filter(active=True)
.annotate(orders_cnt=Count('orders')))


SQLAlchemy


from sqlalchemy.orm import selectinload, joinedload

# 1:N — безопаснее selectinload (батчирует IN (...))
users = (session.query(User)
.options(selectinload(User.orders))
.filter(User.active.is_(True))
.all())

# 1:1 — joinedload
user = (session.query(User)
.options(joinedload(User.profile))
.get(user_id))


Практические советы

- Логируйте кол-во запросов на эндпойнт/страницу. В Django - django-debug-toolbar, assertNumQueries в тестах; в SQLAlchemy - echo/интеграция с логгером.
- Индексы: обязательно orders(user_id); если фильтруете по статусу - составной (user_id, status).
- Батчинг вместо циклов: тяните детей одним запросом WHERE user_id IN (...), затем мапьте в памяти.
- Осторожно с joinedload для 1:N на больших выборках - риск «взрыва» строк. Для 1:N чаще выбирайте selectinload.
- Колонки по делу: не тащите SELECT *, берите только нужные поля.
- Пагинация: уменьшает N и давление на сеть/память.
- EXPLAIN (ANALYZE, BUFFERS) - проверяйте планы и кардинальности.


💡Думайте наборами, а не циклами. Eager loading + агрегаты закрывают 90% случаев N+1. Настройте мониторинг количества запросов - и ловите проблему до продакшена.

Сохрани, чтобы не наступить снова. Поделись с коллегами. А как вы ловите N+1 у себя?

#SQL

👉 @database_info
👍83
Типы JOIN в SQL и когда их применять

- INNER JOIN - пересечение множеств (только совпавшие строки).
- LEFT JOIN - все слева + совпавшие справа (несовпавшие → NULL).
- RIGHT JOIN - симметричен LEFT, лучше переворачивать под LEFT.
- FULL OUTER JOIN - все слева и справа (где нет пары → NULL).
- CROSS JOIN — декартово произведение (каждая со всеми).
- SELF JOIN - таблица соединяется сама с собой.
- SEMI / ANTI JOIN - “есть/нет соответствия” (через EXISTS / NOT EXISTS).
- LATERAL / APPLY - зависимая подзапросная таблица на строку слева.


1️⃣ INNER JOIN - «строго есть пара»

«Покажи оплаченные заказы с данными клиента».


SELECT o.id, c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'paid';


Используйте, когда отсутствие пары - повод исключить строку.

2️⃣ LEFT JOIN - «все слева, даже без пары»

«Список клиентов и количество их заказов (включая с нулём)».


SELECT c.id, c.name, COALESCE(COUNT(o.id), 0) AS orders_cnt
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name;


По умолчанию для «обогащения» справочниками и опциональных связей.

3️⃣ RIGHT JOIN - почти не нужен

Заменяйте на LEFT, поменяв стороны:


-- было:
-- SELECT ... FROM A RIGHT JOIN B ON ...
-- стало:
SELECT ...
FROM B
LEFT JOIN A ON ...


4️⃣ FULL OUTER JOIN - «объединить всё»

«Свод по всем клиентам и всем заказам, даже если без пары».


SELECT COALESCE(c.id, o.customer_id) AS customer_key, c.name, o.id AS order_id
FROM customers c
FULL JOIN orders o ON o.customer_id = c.id;


Редко нужен в отчётах/сверках. Поддержка зависит от СУБД.

5️⃣ CROSS JOIN - «все комбинации»

«Собрать сетку метрик по всем регионам и кварталам».


SELECT r.region, q.quarter
FROM regions r
CROSS JOIN quarters q;


Осторожно: взрыв строк.

6️⃣ SELF JOIN - «сравнить строки внутри таблицы»

«Найти менеджера и его подчинённого».


SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;


7️⃣ SEMI JOIN (EXISTS) - «фильтрация по факту наличия»

«Клиенты, у кого были заказы за 30 дней».


SELECT c.*
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
AND o.created_at >= CURRENT_DATE - INTERVAL '30 day'
);


Не размножает строки, часто быстрее, чем JOIN + DISTINCT.

8️⃣ ANTI JOIN (NOT EXISTS) - «кто без соответствий»

«Товары, которые ни разу не покупали в этом году».


SELECT p.*
FROM products p
WHERE NOT EXISTS (
SELECT 1 FROM order_items oi
JOIN orders o ON o.id = oi.order_id
WHERE oi.product_id = p.id
AND o.created_at >= date_trunc('year', CURRENT_DATE)
);


Избегайте NOT IN с NULL - может дать пустой результат.

9️⃣ LATERAL / APPLY - «топ-N на строку»

«Последний заказ на клиента» (PostgreSQL: LATERAL, SQL Server: APPLY).


SELECT c.id, c.name, o_last.id AS last_order_id
FROM customers c
LEFT JOIN LATERAL (
SELECT o.id
FROM orders o
WHERE o.customer_id = c.id
ORDER BY o.created_at DESC
LIMIT 1
) o_last ON true;



💡Подводные камни

- LEFT JOIN + фильтр в WHERE ⇒ превращается в INNER.
Если нужно оставить «без пары», переносите условие в ON:


-- неверно
SELECT ... FROM c LEFT JOIN o ON o.customer_id = c.id
WHERE o.status = 'paid';

-- верно
SELECT ... FROM c LEFT JOIN o
ON o.customer_id = c.id AND o.status = 'paid';

- Дубликаты из «один-ко-многим». Перед JOIN делайте агрегацию в подзапросе/CTE.
- Индексы на ключах соединений (FK и соответствующие PK/UK) - must.
- Сопоставимость типов/колляций. Функции на ключе (LOWER(col)) ломают sargability - лучше нормализовать данные заранее.
- EXISTS чаще лучше, чем JOIN + DISTINCT для фильтрации.
- Проверяйте план. EXPLAIN (ANALYZE, BUFFERS) и сравнение альтернатив.

Сохрани, чтобы не забыть. А как вы чаще фильтруете - через JOIN+DISTINCT или EXISTS?

#SQL

👉 @database_info
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥41