sqlportal | Unsorted

Telegram-канал sqlportal - SQL Portal | Базы Данных

14500

Присоединяйтесь к нашему каналу и погрузитесь в мир баз данных Связь: @devmangx РКН: https://clck.ru/3H4Wo3

Subscribe to a channel

SQL Portal | Базы Данных

Проектирование баз данных (SQL и NoSQL)

Что такое проектирование баз данных? Проектирование баз данных — это процесс организации данных для эффективного хранения, поиска и управления ими. Он включает выбор подходящего типа базы данных (SQL или NoSQL), определение связей между данными и обеспечение их целостности.

SQL-базы данных (реляционные)

→ Хранят данные в структурированных таблицах со строками и столбцами.
→ Используют заранее определённую схему с фиксированной структурой.
→ Для запросов применяют SQL (Structured Query Language).
→ Обеспечивают соблюдение ACID-свойств: атомарность, согласованность, изоляцию и долговечность.

Примеры SQL-баз данных:

MySQL
PostgreSQL
Oracle Database
Microsoft SQL Server

Преимущества SQL:

→ Высокая согласованность данных.
→ Хорошо подходят для структурированных данных и сложных запросов.
→ Надёжная работа транзакций благодаря поддержке ACID.

Недостатки SQL:

→ Менее гибкие при работе с неструктурированными или часто меняющимися данными.
→ Горизонтальное масштабирование сложнее реализовать.

NoSQL-базы данных (нереляционные)

→ Хранят данные в гибких форматах: документах, парах «ключ — значение», широких столбцах или графах.
→ Используют схемы без жёсткой структуры или с динамической схемой.
→ Ориентированы на масштабируемость и высокую производительность.
→ Часто опираются на принципы BASE: преимущественная доступность, изменяемое состояние и eventual consistency (согласованность с течением времени).

Примеры NoSQL-баз данных:

MongoDB — документоориентированная.
Redis — хранилище «ключ — значение».
Cassandra — ширококолоночная.
Neo4j — графовая.

Преимущества NoSQL:

→ Высокая масштабируемость и скорость.
→ Гибкая схема для неструктурированных данных.
→ Хорошо подходят для Big Data и приложений реального времени.

Недостатки NoSQL:

→ Гарантии согласованности могут быть слабее, чем в SQL-базах.
→ Поддержка сложных запросов может быть ограничена.
SQL vs NoSQL
→ SQL: лучше подходит для структурированных данных и приложений, которым нужна высокая согласованность, например банковских систем.
→ NoSQL: подходит для неструктурированных и полуструктурированных данных, приложений реального времени и масштабных систем, например социальных сетей и IoT.

Примеры из реальной разработки

→ SQL: банковские системы, управление складскими запасами, ERP-системы.
→ NoSQL: платформы электронной коммерции, ленты социальных сетей, аналитика больших данных.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

SQL-команды для анализа данных.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Ловушка оператора NOT IN при использовании подзапросов в SQL

Оператор NOT IN может неожиданно повести себя при работе со значениями NULL. Если подзапрос возвращает хотя бы одно значение NULL, основной запрос может не вернуть ни одной строки.

Простой пример:

SELECT employee_name
FROM safety
WHERE id NOT IN (
SELECT days_lost
FROM safety
);


Если в столбце days_lost есть хотя бы один NULL, результат сравнения через NOT IN может стать UNKNOWN, а не TRUE или FALSE.

Поскольку WHERE возвращает только строки, для которых условие равно TRUE, результатом может оказаться пустая выборка.

Как избежать этой проблемы?

Исключите NULL из подзапроса:
SELECT employee_name
FROM safety
WHERE id NOT IN (
SELECT days_lost
FROM safety
WHERE days_lost IS NOT NULL
);


Добавив IS NOT NULL, вы не позволяете значениям NULL влиять на сравнение. Простое, но эффективное решение!

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Вы создали индекс для таблицы базы данных. Но запрос всё равно выполняется медленно.

Проверяете план выполнения и обнаруживаете, что PostgreSQL не использует индекс. Вот нюанс, который разработчики часто упускают из виду.

Рассмотрим такой индекс:

CREATE INDEX idx_orders ON orders (customer_id, status, created_at);


А теперь запрос:
SELECT * FROM orders WHERE status = 'PENDING';


Индекс начинается с customer_id, а запрос фильтрует данные только по status.

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

Порядок столбцов в составном индексе имеет значение.

Индекс — это не просто набор столбцов. Их порядок может определять, насколько эффективно база данных сможет использовать индекс.

Не спрашивайте только, существует ли индекс. Проверяйте, соответствует ли его структура шаблонам ваших запросов.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Это лучшая статья про MVCC в MySQL, что я читал.

MySQL и Postgres используют разные инженерные подходы для решения одной и той же задачи: undo log против нескольких версий кортежей.

Ещё одна отличная работа от Jeremy Cole.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Sharding, Partitioning и Replication: в чём разница?

В системном дизайне эти три понятия часто путают, хотя каждое решает свою задачу.

1. Partitioning (партиционирование)
Разделение большой таблицы на более мелкие части. Это помогает оптимизировать выполнение запросов и упростить управление данными.

2. Sharding (шардирование)
Распределение частей данных между несколькими серверами. Позволяет масштабировать хранилище и увеличить пропускную способность операций записи.

3. Replication (репликация)
Создание копий данных на нескольких серверах. Повышает доступность системы и позволяет распределять нагрузку на чтение.

Как запомнить разницу:

• Partitioning = разделить данные.
• Sharding = распределить данные.
• Replication = скопировать данные.

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

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

В каком порядке SQL выполняет запросы?
SQL-запрос выполняется не совсем в том порядке, в котором написаны его инструкции.

Логический порядок обработки запроса:

FROM и JOIN — определение источников данных и объединение таблиц.
WHERE — фильтрация строк.
GROUP BY — группировка данных.
HAVING — фильтрация полученных групп.
SELECT — выбор столбцов и вычисление выражений.
ORDER BY — сортировка результата.
LIMIT и OFFSET — ограничение количества возвращаемых строк и пропуск записей.

Понимание этого порядка помогает лучше разбираться в работе SQL-запросов, находить ошибки и правильно использовать агрегатные функции, фильтрацию и сортировку.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Дорожная карта изучения SQL

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Вопрос с собеседования в Amazon по SQL

Что не так с этим SQL-запросом?

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

SQL MASTER TREE

Большая карта SQL, которая охватывает практически всё, что нужно знать разработчику или аналитику при работе с базами данных.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Главный совет для разработчиков, которые только начинают работать с Postgres: всегда задавай statement timeout.

ALTER DATABASE mydatabase
SET statement_timeout = '60s';


👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Поиск узких мест в базе данных

Когда приложение начинает тормозить, первой под подозрение часто попадает база данных. Но высокая задержка на стороне БД не означает, что пора покупать более мощный сервер. Причина может быть в неэффективном запросе, блокировках, исчерпании пула соединений, дисковом I/O или нехватке ресурсов.

Разберёмся, как найти настоящую причину.

1. Найдите симптомы. Проверьте время выполнения запросов (особенно p95), количество активных соединений, число медленных запросов, загрузку CPU и дисковый I/O. Сопоставьте эти показатели с задержками приложения, всплесками трафика и недавними деплоями, чтобы понять, когда началась проблема.

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

3. Соберите данные. В PostgreSQL для диагностики пригодятся следующие инструменты:
pg_stat_statements — поиск ресурсоёмких запросов.
pg_stat_activity — просмотр активных запросов и сессий, ожидающих выполнения.
pg_locks — анализ блокировок.
EXPLAIN (ANALYZE, BUFFERS) — изучение плана выполнения запроса и активности буферов. Будьте осторожны: ANALYZE действительно выполняет запрос.

4. Найдите первопричину.

Медленные запросы:
отсутствующие индексы, неэффективные JOIN, полное сканирование таблиц или неудачные планы выполнения.
Блокировки: долгие транзакции или одновременные обновления данных.
Исчерпание соединений: неправильная настройка пулов, простаивающие или утёкшие соединения.
Высокая дисковая нагрузка: интенсивное чтение и запись, большие сканирования или ограничения хранилища.
Нехватка ресурсов: ограничения по CPU, памяти или дисковой ёмкости.

5. Примените подходящее решение. Оптимизируйте запросы и индексы, сокращайте время транзакций, устраняйте блокировки, настраивайте пулы соединений или повышайте производительность хранилища.

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

6. Убедитесь, что проблема решена. Сравните задержки запросов, использование соединений, загрузку CPU, дисковый I/O и частоту ошибок приложения с показателями до инцидента. Проверьте, сохраняется ли улучшение при типичной нагрузке.

Последовательность диагностики:
Наблюдение → Локализация → Исследование → Диагностика → Исправление → Проверка

Примеры в этом материале основаны на PostgreSQL, но сам подход применим и к MySQL, SQL Server и Oracle. При этом диагностические инструменты и команды будут отличаться.
Не гадайте, в чём проблема с базой данных. Соберите доказательства, устраните причину и измерьте результат.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

🚀 29 октября Arenadata проведёт техническую онлайн-конференцию ArenaTech

На ArenaTech инженеры Arenadata расскажут, как устроены продукты компании изнутри, поделятся опытом решения сложных инженерных задач и представят ключевые направления технологического развития.

🟢Основные темы конференции:

🔜СУБД: архитектура, развитие и эксплуатация. Обсудим планы развития Arenadata DB (ADB) и Greengage DB, новые возможности MPP-СУБД, включая hot standby, вопросы безопасности и устранения уязвимостей. Отдельное внимание уделим утилите ggrebalance, которая позволяет сокращать число сегментов кластера и заменять хосты с сохранением равномерного распределения данных.

🔜Платформа данных: безопасность и Kubernetes. Расскажем об управлении секретами и доступом в Arenadata Hyperwave (ADH) с использованием OpenBao. Разберём особенности переноса Impala, Trino и Spark в Kubernetes: интеграцию с Kerberos, разработку операторов, адаптацию Spark и использование Celeborn и YuniKorn.

🔜Инструменты: кластерный менеджер, документация, ИИ-поиск. Поделимся опытом организации процессов разработки технической документации и расскажем, как создавались интеллектуальный поиск и ИИ-ассистент, упрощающие поиск информации в документации многокомпонентной платформы данных. Также расскажем про развитие нашего кластерного менеджера ADCM.

После каждого доклада участники смогут задать вопросы спикерам в рамках Q&A-сессии.

Конференция будет интересна разработчикам, дата-инженерам, администраторам СУБД, архитекторам, DevOps-инженерам и техническим руководителям.

🗓 29 октября, 12:00 МСК

Формат: онлайн 🔛

Программа и регистрация

Читать полностью…

SQL Portal | Базы Данных

Команда, ваш выход 👋

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Вопрос по SQL:

Что вернёт этот SQL-запрос?

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Если вы работали с SQL или базами данных, то наверняка знаете: правильный запрос и правильные данные — это две совершенно разные вещи.

ИИ-агент может написать корректный SQL-запрос, успешно выполнить его и всё равно выдать неправильный ответ.
Проблема может быть не в самой LLM, а в том, что она не понимает ваши данные.

Представим простой вопрос: «Какую выручку мы получили за прошлый квартал?» В базе есть таблицы orders, invoices, payments и refunds.

Какие таблицы должен использовать агент? Какие столбцы определяют выручку? Нужно ли учитывать отменённые заказы? Как правильно объединить таблицы?

SQL-запрос может быть синтаксически корректным, но результат всё равно окажется неверным. Именно эту проблему пытается решить NVIDIA AutoOntology.

Это опенсорсный Python-фреймворк, который создаёт семантический слой поверх корпоративных баз данных. Он помогает ИИ-агентам понимать бизнес-понятия, столбцы таблиц, связи между ними и определения SQL-запросов.

Как это работает?

1. Определяет смысл структуры базы данных: AutoOntology анализирует метаданные базы, изучает столбцы, выявляет бизнес-понятия и определяет связи между таблицами. В результате формируется онтология, которая связывает понятия вроде «Клиент», «Заказ» и «Выручка» с соответствующими данными в базе.

2. Предоставляет агентам готовые определения вместо догадок: Для бизнес-метрик можно задать проверенные SQL-выражения, а связи между таблицами описать явно. Агенту больше не нужно каждый раз самостоятельно разбираться, как рассчитать выручку или объединить таблицы. Он может использовать уже подготовленные определения.

3. Добавляет проверку и сертификацию: Сгенерированная онтология — это отправная точка, а не абсолютная истина. Специалисты могут проверять и утверждать термины, описания и SQL-определения.

Получив вопрос, агент извлекает нужный контекст, генерирует SQL, проверяет его и возвращает ответ вместе с запросом и результатами выполнения.

4. Передаёт контекст другим агентам: AutoOntology предоставляет возможности через API и MCP-сервер. Совместимые ИИ-агенты могут получать определения, проверять, можно ли ответить на вопрос, и выполнять запросы к данным.

В проекте используются PostgreSQL и pgvector для хранения каталога, онтологии и векторных представлений, FastAPI в качестве backend и настраиваемые языковые модели.

Зачем это разработчикам? Мы уже много внимания уделили тому, как улучшить рассуждения агентов, использование инструментов и поиск по документам. Но корпоративным ИИ-агентам также необходимо понимать смысл данных, с которыми они работают.

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

AutoOntology объединяет эти подходы, помогая делать работу ИИ-агентов с базами данных более обоснованной, последовательной и прозрачной.

Он не устраняет галлюцинации и не гарантирует правильность ответов. Его главная ценность — в том, что агенту больше не приходится каждый раз самостоятельно угадывать бизнес-логику и структуру базы данных.

https://github.com/NVIDIA/auto-ontology

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Эти 8 SQL-команд охватывают 90% повседневных запросов

• SELECT — что нужно получить
• FROM — из какой таблицы
• WHERE — фильтрация строк
• ORDER BY — сортировка результатов
• LIMIT — ограничение количества строк
• GROUP BY — группировка и агрегация данных
• HAVING — фильтрация сгруппированных данных
• JOIN — объединение таблиц

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

18 практических работ по DevOps

Docker, Kubernetes, CI/CD, Terraform, Ansible, Helm, GitOps, мониторинг через Prometheus и Grafana, а также управление секретами и progressive delivery. Курс рассчитан на 16 недель.

В финале у вас будет не просто набор выполненных заданий, а собственный кластер с автоматизированным развёртыванием и мониторингом.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

WHERE vs HAVING в SQL: знаете разницу?

WHERE фильтрует отдельные строки до группировки, а HAVING — группы после выполнения агрегации.

Понимание разницы между ними помогает писать корректные SQL-запросы и решать реальные бизнес-задачи.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Совет для SQL в production:

column = NULL работает не так, как многие разработчики ожидают.

Используйте:

column IS NULL

NULL означает неизвестное или отсутствующее значение, а не обычное значение, которое можно сравнивать с помощью =.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

SQL-запросы выполняются не в том порядке, в котором написаны.

Понимание того, как работают FROM, WHERE, GROUP BY, HAVING, SELECT и ORDER BY, помогает писать более качественные запросы, находить ошибки и оптимизировать производительность.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Сохраняете данные в БД и публикуете событие в рамках одного запроса?

В таком случае вы рискуете столкнуться с проблемой Dual Write — когда одна операция успешно выполняется, а другая завершается ошибкой.

Например, запись в базе данных прошла успешно, но публикация события в брокер сообщений не удалась. В результате данные сохранены, а другие сервисы об этом не узнают.

Решение — Transactional Outbox Pattern.

Этот паттерн позволяет атомарно сохранить бизнес-данные и событие в одной транзакции БД. Отдельный процесс затем забирает событие из Outbox и публикует его в брокер сообщений.

Главное преимущество — гарантированная согласованность записи в БД и события, а также доставка по модели at-least-once.

Важно: потребители должны быть готовы к повторной доставке событий и обрабатывать дубликаты.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Spring Boot API отвечает тайм-аутами, а PostgreSQL выглядит здоровым?

CPU в норме, медленных запросов нет. Причина может быть в исчерпании пула соединений HikariCP. Когда все соединения заняты, новые запросы ждут освобождения одного из них. Если время ожидания превышает connectionTimeout, получение соединения завершается ошибкой.

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

В статье разбираются:

• Причины исчерпания пула.
• Влияние долгих транзакций.
• Диагностика по метрикам HikariCP.
• Практические способы устранения проблемы.

vishipatil/the-database-was-healthy-so-why-was-my-spring-boot-api-timing-out-a8b56f97ff30">Читать статью

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Что такое SQL: базы данных, таблицы и реляционные концепции

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Redis — возможно, одно из крупнейших предательств в истории Open Source

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

Так появился Redis.

Его использовали Twitter, GitHub, Snapchat, Stack Overflow. Практически каждая крупная технологическая компания так или иначе внедрила Redis в свою инфраструктуру.
К 2020 году Сальваторе выгорел после 11 лет практически единоличной поддержки проекта. Он передал его компании Redis Labs и отошёл от разработки.

А затем, в марте 2024 года, Redis Labs изменила лицензию. Redis перестал быть Open Source в привычном понимании. Облачные провайдеры больше не могли свободно предлагать его в качестве управляемого сервиса без коммерческих соглашений с Redis Labs.

Сообщество, которое годами развивало экосистему вокруг проекта, оказалось перед фактом.
Но вместо споров и бесконечных обсуждений разработчики просто сделали форк.

Всего через восемь дней Linux Foundation объявила о создании Valkey — форка Redis с открытой лицензией. Проект поддержали AWS, Google, Oracle, Ericsson и Snap. В течение нескольких недель к инициативе присоединились более 50 компаний.

Вскоре Fedora, Ubuntu, Debian и Arch начали отказываться от Redis в пользу Valkey. AWS перевела миллионы узлов на новую реализацию. Valkey достиг производительности 1,19 млн запросов в секунду — согласно приведённым в публикации данным, это на 230% быстрее версии Redis, от которой отказались.

Затем Redis попыталась вернуть доверие сообщества, снова привлекая Сальваторе к проекту. Он вернулся, выступал на Hacker News в защиту изменения лицензии и пытался восстановить доверие разработчиков.

Но сообщество уже начало двигаться дальше без него. Redis строил доверие Open Source 15 лет. Одно изменение лицензии — и всего за восемь дней потерял значительную часть этого доверия.

В мире Open Source сообщество — это не просто пользователи. Сообщество — главное конкурентное преимущество проекта.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

SQL Mindmap: фундамент SQL на одной карте

Изучите основные концепции SQL с помощью наглядной интеллект-карты. В ней собраны ключевые темы для начинающих:

Основы баз данных:

SELECT — выборка данных
WHERE — фильтрация записей
JOIN — объединение таблиц
GROUP BY — группировка данных
Агрегатные функции: COUNT, SUM, AVG, MIN, MAX
ORDER BY — сортировка результатов
Подзапросы — запросы внутри других запросов

Практичный способ разобраться в SQL последовательно, увидеть связи между темами и закрепить фундамент для дальнейшего изучения языка.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Excel, Python или SQL — какой инструмент выбрать под задачу?

Логика часто одна и та же, меняется лишь подход к её реализации.

Сравниваем три инструмента на практике: фильтрацию, сортировку, агрегацию, обработку пропусков, вычисления и объединение данных.

Полезная шпаргалка для тех, кто работает с данными и хочет понимать, как решать одни и те же задачи в Excel, Python и SQL.

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

50 ключевых навыков, которыми должен владеть аналитик данных

От SQL, Excel, Python и Power BI до статистики, визуализации данных и бизнес-аналитики — этот чек-лист охватывает навыки, необходимые для уверенной работы аналитиком данных.

Сохраняй, чтобы использовать в своём обучении и отслеживать прогресс!

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

19 функций Excel, которые должен знать каждый

От SUM, AVERAGE и IF до XLOOKUP, INDEX + MATCH и функций для работы с датами — освойте формулы, которые упрощают очистку данных, расчёты и анализ.

Сохраняйте шпаргалку, чтобы всегда держать нужные функции под рукой!

👉 @SQLPortal

Читать полностью…

SQL Portal | Базы Данных

Индексы не делают базы данных «быстрыми». Они ускоряют конкретные запросы — и за это приходится платить.

Как на самом деле работает индекс

• Индекс — отдельная структура данных, чаще всего B-Tree (B-дерево).
• Он хранит значения столбца и ссылки на соответствующие строки.
• Вместо полного сканирования таблицы база данных может сразу перейти к нужным данным.

Чтение ускоряется за счёт того, что приходится просматривать меньше данных.

Что происходит при INSERT / UPDATE
Запись данных в таблицу.
Поиск нужной позиции в индексе.
Обновление узлов индекса.
При необходимости — перебалансировка дерева.
Запись изменений в журнал транзакций (WAL / redo log) для обеспечения надёжности.
Каждый индекс увеличивает объём работы при записи.

Стоимость операций:

Чтение — примерно (O(\log n)).
Запись — примерно (O(\log n)) для каждого обновляемого индекса.

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

Почему индексы тормозят системы с большим количеством записей

• Повышают нагрузку на CPU.
• Увеличивают количество операций ввода-вывода.
• Могут усиливать конкуренцию за блокировки и другие ресурсы.
• Увеличивают время выполнения транзакций.

Поэтому в высоконагруженных системах количество индексов тщательно контролируют.

Ошибки при работе с индексами в production

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

Главное правило для production: проектируйте индексы исходя из реальных запросов и сценариев работы с данными, а не только из структуры таблиц.

👉 @SQLPortal

Читать полностью…
Subscribe to a channel