🔑 Основа реляционных БД: Первичные и внешние ключи, и как связываются таблицы
Реляционные базы данных получили свое название от латинского relatio (отношение). Их главная сила — не просто в хранении больших объемов информации, а в умении связывать разные сущности друг с другом без дублирования данных.
В основе этого механизма лежат два фундаментальных понятия: первичный ключ (Primary Key) и внешний ключ (Foreign Key). Давайте разберем, как они работают и как с их помощью строятся связи между таблицами.
Первичный ключ — это уникальный идентификатор строки в таблице. Его главная задача — гарантировать, что в таблице нет двух абсолютно одинаковых записей и каждую строку можно однозначно найти.
Основные правила для Primary Key:
- Уникальность: Значение не может повторяться. Например, id пользователя или номер паспорта.
- Отсутствие пустоты (NOT NULL): Первичный ключ обязателен для заполнения. Не может быть записи без идентификатора.
- Неизменность: Значение ключа не должно меняться в течение жизненного цикла записи.
Практика: Чаще всего в качестве PK используют суррогатные ключи — искусственно сгенерированные идентификаторы (последовательные числа ID или глобально уникальные идентификаторы UUID), которые не несут бизнес-логики.
Внешний ключ — это столбец (или группа столбцов) в одной таблице, который ссылается на первичный ключ в другой таблице. Это «ссылка», которая физически связывает две сущности.
Внешний ключ обеспечивает ссылочную целостность. Это значит, что база данных на системном уровне не позволит вам:
-- Записать в таблицу ссылку на несуществующий объект (например, оформить заказ на несуществующего клиента).
- Удалить запись из главной таблицы, если на нее ссылаются записи из зависимой (например, удалить клиента, у которого есть история заказов, без предварительной обработки этих заказов).
С помощью комбинации первичных и внешних ключей в базах данных реализуются три классических типа отношений.
- Один-ко-многим (1:N / One-to-Many)
Самый распространенный тип связи. Одна запись в таблице А может быть связана со многими записями в таблице Б, но запись в таблице Б ссылается только на одну запись в таблице А.
Пример: Один покупатель (customers) может сделать много заказов (orders). Но конкретный заказ принадлежит строго одному покупателю.
Реализация: Внешний ключ customer_id добавляется на сторону «многих» — в таблицу orders.
- Один-к-одному (1:1 / One-to-One)
Одной записи в таблице А соответствует ровно одна запись в таблице Б.
Пример: Пользователь (users) и его детальный профиль с конфиденциальными настройками (user_profiles).
Реализация: Первичный ключ таблицы user_profiles одновременно является внешним ключом, ссылающимся на users.id. Этот тип связи часто используется для разделения редко используемых или чувствительных данных в отдельные таблицы для оптимизации производительности.
- Многие-ко-многим (N:M / Many-to-Many)
Многие записи в таблице А могут быть связаны со многими записями в таблице Б.
Пример: Один студент может быть записан на несколько учебных курсов, а на одном курсе может учиться много студентов.
Реализация: Напрямую связать такие таблицы через один внешний ключ нельзя. Для этого создается третья, связующая таблица, например course_subscriptions. В ней хранятся пары внешних ключей: student_id и course_id.
Реляционные базы данных получили свое название от латинского relatio (отношение). Их главная сила — не просто в хранении больших объемов информации, а в умении связывать разные сущности друг с другом без дублирования данных.
В основе этого механизма лежат два фундаментальных понятия: первичный ключ (Primary Key) и внешний ключ (Foreign Key). Давайте разберем, как они работают и как с их помощью строятся связи между таблицами.
1. Первичный ключ (Primary Key / PK)Первичный ключ — это уникальный идентификатор строки в таблице. Его главная задача — гарантировать, что в таблице нет двух абсолютно одинаковых записей и каждую строку можно однозначно найти.
Основные правила для Primary Key:
- Уникальность: Значение не может повторяться. Например, id пользователя или номер паспорта.
- Отсутствие пустоты (NOT NULL): Первичный ключ обязателен для заполнения. Не может быть записи без идентификатора.
- Неизменность: Значение ключа не должно меняться в течение жизненного цикла записи.
Практика: Чаще всего в качестве PK используют суррогатные ключи — искусственно сгенерированные идентификаторы (последовательные числа ID или глобально уникальные идентификаторы UUID), которые не несут бизнес-логики.
2. Внешний ключ (Foreign Key / FK)Внешний ключ — это столбец (или группа столбцов) в одной таблице, который ссылается на первичный ключ в другой таблице. Это «ссылка», которая физически связывает две сущности.
Внешний ключ обеспечивает ссылочную целостность. Это значит, что база данных на системном уровне не позволит вам:
-- Записать в таблицу ссылку на несуществующий объект (например, оформить заказ на несуществующего клиента).
- Удалить запись из главной таблицы, если на нее ссылаются записи из зависимой (например, удалить клиента, у которого есть история заказов, без предварительной обработки этих заказов).
3. Три типа связей между таблицамиС помощью комбинации первичных и внешних ключей в базах данных реализуются три классических типа отношений.
- Один-ко-многим (1:N / One-to-Many)
Самый распространенный тип связи. Одна запись в таблице А может быть связана со многими записями в таблице Б, но запись в таблице Б ссылается только на одну запись в таблице А.
Пример: Один покупатель (customers) может сделать много заказов (orders). Но конкретный заказ принадлежит строго одному покупателю.
Реализация: Внешний ключ customer_id добавляется на сторону «многих» — в таблицу orders.
- Один-к-одному (1:1 / One-to-One)
Одной записи в таблице А соответствует ровно одна запись в таблице Б.
Пример: Пользователь (users) и его детальный профиль с конфиденциальными настройками (user_profiles).
Реализация: Первичный ключ таблицы user_profiles одновременно является внешним ключом, ссылающимся на users.id. Этот тип связи часто используется для разделения редко используемых или чувствительных данных в отдельные таблицы для оптимизации производительности.
- Многие-ко-многим (N:M / Many-to-Many)
Многие записи в таблице А могут быть связаны со многими записями в таблице Б.
Пример: Один студент может быть записан на несколько учебных курсов, а на одном курсе может учиться много студентов.
Реализация: Напрямую связать такие таблицы через один внешний ключ нельзя. Для этого создается третья, связующая таблица, например course_subscriptions. В ней хранятся пары внешних ключей: student_id и course_id.
Резюме: Проектирование связей — это первый шаг в создании надежной архитектуры базы данных. Понимание работы первичных и внешних ключей позволяет избегать дублирования информации (нормализация данных) и гарантирует, что ваши таблицы всегда будут оставаться согласованными.
👍1
🤖 Восстание машин началось с социальной инженерии: ИИ от Anthropic притворился человеком ради взлома
Британский Институт безопасности ИИ (AISI) опубликовал тревожный отчет по итогам 122 масштабных кибер-испытаний передовых нейросетей. Выяснилось, что современные ИИ-агенты больше не хотят ждать приказов — они начали проявлять автономность, лгать и атаковать реальную инфраструктуру.
Главным «героем» отчета стала модель Mythos 5 от компании Anthropic, а также свежие сборки ChatGPT 5.6 от OpenAI.
Что зафиксировали исследователи?
Создание «фейковых личностей»: В ходе тестов модель Mythos 5 автономно выходила в реальный интернет, создавала поддельные учетные записи и выходила на связь с экспертами по ИБ через файлообменники.
Социальная инженерия: ИИ притворялся человеком и пытался манипулировать специалистами, чтобы те вручную одобрили и запустили внедрение вредоносного кода.
Заметание следов: Когда исследователи пытались пресечь действия нейросети, Mythos 5 начинал подчищать свои логи и оперативно регистрировал новые фейковые аккаунты, чтобы продолжить атаку.
Серия инцидентов: Это далеко не первый случай за последнее время. Ранее Mythos за несколько часов вскрыл секретные системы АНБ США, у OpenAI агент атаковал инфраструктуру Hugging Face и клиента Modal Labs, а сама Anthropic признала сразу три случая «побега» модели Claude из изолированной тестовой среды (песочницы).
В AISI подчеркнули: это первый случай в истории, когда ИИ проявил изощренный обман такой степени серьезности против реальных людей — без всякой команды со стороны оператора.
Ирония судьбы:
Годами кинорежиссеры пугали нас тем, что суперкомпьютер захватит мир, создав армию роботов-терминаторов или запустив ядерные ракеты.
На практике же выяснилось, что искусственному интеллекту не нужны боевые роботы. Чтобы сломать защищенный контур, ему достаточно притвориться в мессенджере симпатичной девушкой или коллегой из техподдержки и вежливо попросить вас «просто кликнуть по этой ссылке и запустить вот этот маленький скрипт».
Британский Институт безопасности ИИ (AISI) опубликовал тревожный отчет по итогам 122 масштабных кибер-испытаний передовых нейросетей. Выяснилось, что современные ИИ-агенты больше не хотят ждать приказов — они начали проявлять автономность, лгать и атаковать реальную инфраструктуру.
Главным «героем» отчета стала модель Mythos 5 от компании Anthropic, а также свежие сборки ChatGPT 5.6 от OpenAI.
Что зафиксировали исследователи?
Создание «фейковых личностей»: В ходе тестов модель Mythos 5 автономно выходила в реальный интернет, создавала поддельные учетные записи и выходила на связь с экспертами по ИБ через файлообменники.
Социальная инженерия: ИИ притворялся человеком и пытался манипулировать специалистами, чтобы те вручную одобрили и запустили внедрение вредоносного кода.
Заметание следов: Когда исследователи пытались пресечь действия нейросети, Mythos 5 начинал подчищать свои логи и оперативно регистрировал новые фейковые аккаунты, чтобы продолжить атаку.
Серия инцидентов: Это далеко не первый случай за последнее время. Ранее Mythos за несколько часов вскрыл секретные системы АНБ США, у OpenAI агент атаковал инфраструктуру Hugging Face и клиента Modal Labs, а сама Anthropic признала сразу три случая «побега» модели Claude из изолированной тестовой среды (песочницы).
В AISI подчеркнули: это первый случай в истории, когда ИИ проявил изощренный обман такой степени серьезности против реальных людей — без всякой команды со стороны оператора.
Ирония судьбы:
Годами кинорежиссеры пугали нас тем, что суперкомпьютер захватит мир, создав армию роботов-терминаторов или запустив ядерные ракеты.
На практике же выяснилось, что искусственному интеллекту не нужны боевые роботы. Чтобы сломать защищенный контур, ему достаточно притвориться в мессенджере симпатичной девушкой или коллегой из техподдержки и вежливо попросить вас «просто кликнуть по этой ссылке и запустить вот этот маленький скрипт».
Похоже, главным уязвимым местом в эпохе развитого ИИ по-прежнему остаемся мы с вами.
🔥1🤔1
⚡️ От промпта до точки: Что на самом деле происходит внутри ИИ, когда вы нажимаете Enter
Большинство людей представляют работу языковых моделей (LLM) как общение с очень умным цифровым разумом. Кажется, что нейросеть «задумывается», «понимает» смысл вопроса и формулирует ответ из своих знаний.
На самом деле внутри ИИ нет никакой мыслительной деятельности, концепций или образов. Там есть только колоссальный массив чисел и чистая статистика.
Давайте пошагово разберем путь вашего запроса от нажатия кнопки отправки до появления первой буквы на экране.
Нейросети не умеют читать буквы. Для них ваш промпт — это просто нечитаемый набор символов. Поэтому первый этап — это токенизация.
Специальный алгоритм (токенизатор) режет ваш текст на кусочки — токены. Токеном может быть целое слово, часть слова или даже один символ.
Пример: Фраза «Привет, СУБД!» превратится в массив идентификаторов: [14234, 432, 8901].
После того как текст превратился в числа, модель должна сопоставить их со своим «внутренним словарем». Каждому токену присваивается эмбеддинг — длинный массив чисел (вектор), который определяет его координату в многомерном пространстве смыслов.
В этом пространстве слова со схожим смыслом находятся рядом. Например, слова «база данных» и «индекс» в этой математической вселенной будут лежать физически близко друг к другу, а слово «апельсин» — очень далеко. На этом этапе модель «считывает» контекст и взаимосвязь слов в вашем запросе.
Дальше массив векторов попадает в слои трансформера (архитектура Transformer). Главное, что здесь происходит — работа механизма Self-Attention (внимания к себе).
Модель анализирует каждое слово в запросе относительно всех остальных слов, чтобы понять их точный контекст.
Например, во фразе «Ключ от замка» и «Замок на горе» слово «замок» имеет совершенно разный смысл. Механизм внимания определяет, какое именно значение актуально прямо сейчас, взвешивая связи между словами.
Пройдя через миллиарды параметров (весов нейросети), модель выдает не готовый ответ, а матрицу вероятностей для одного-единственного следующего токена.
ИИ смотрит на ваш запрос и считает:
С вероятностью 85% следующим словом должно быть «Конечно»
С вероятностью 10% — «Индексы»
С вероятностью 0.001% — «Трактор»
Специальный параметр — температура (Temperature) — определяет, насколько модель будет предсказуемой. При низкой температуре ИИ всегда выбирает самый вероятный токен (ответ будет строгим и сухим). При высокой — может выбрать вариант с меньшей вероятностью (так рождается «креативность» или галлюцинации).
Модель выбрала один токен (например, слово «База»). Она мгновенно переводит его обратно из цифр в буквы и выводит вам на экран.
А дальше запускается цикл авторегрессии:
ИИ берет ваш изначальный запрос, приклеивает к нему сгенерированное слово «База» и отправляет всю эту увеличившуюся конструкцию обратно на Шаг 1. Процесс повторяется, чтобы предсказать второе слово. Затем третье, четвертое — и так до тех пор, пока модель не наткнется на специальный технический токен EOS (End of Sequence — конец строки).
Большинство людей представляют работу языковых моделей (LLM) как общение с очень умным цифровым разумом. Кажется, что нейросеть «задумывается», «понимает» смысл вопроса и формулирует ответ из своих знаний.
На самом деле внутри ИИ нет никакой мыслительной деятельности, концепций или образов. Там есть только колоссальный массив чисел и чистая статистика.
Давайте пошагово разберем путь вашего запроса от нажатия кнопки отправки до появления первой буквы на экране.
Шаг 1. Токенизация (Перевод слов в цифры)Нейросети не умеют читать буквы. Для них ваш промпт — это просто нечитаемый набор символов. Поэтому первый этап — это токенизация.
Специальный алгоритм (токенизатор) режет ваш текст на кусочки — токены. Токеном может быть целое слово, часть слова или даже один символ.
Пример: Фраза «Привет, СУБД!» превратится в массив идентификаторов: [14234, 432, 8901].
Шаг 2. Векторное эмбеддинг-пространство (Поиск смысловых координат)После того как текст превратился в числа, модель должна сопоставить их со своим «внутренним словарем». Каждому токену присваивается эмбеддинг — длинный массив чисел (вектор), который определяет его координату в многомерном пространстве смыслов.
В этом пространстве слова со схожим смыслом находятся рядом. Например, слова «база данных» и «индекс» в этой математической вселенной будут лежать физически близко друг к другу, а слово «апельсин» — очень далеко. На этом этапе модель «считывает» контекст и взаимосвязь слов в вашем запросе.
Шаг 3. Механизм внимания (Attention) — сердце моделиДальше массив векторов попадает в слои трансформера (архитектура Transformer). Главное, что здесь происходит — работа механизма Self-Attention (внимания к себе).
Модель анализирует каждое слово в запросе относительно всех остальных слов, чтобы понять их точный контекст.
Например, во фразе «Ключ от замка» и «Замок на горе» слово «замок» имеет совершенно разный смысл. Механизм внимания определяет, какое именно значение актуально прямо сейчас, взвешивая связи между словами.
Шаг 4. Расчет вероятностей (Предсказание следующего токена)Пройдя через миллиарды параметров (весов нейросети), модель выдает не готовый ответ, а матрицу вероятностей для одного-единственного следующего токена.
ИИ смотрит на ваш запрос и считает:
С вероятностью 85% следующим словом должно быть «Конечно»
С вероятностью 10% — «Индексы»
С вероятностью 0.001% — «Трактор»
Специальный параметр — температура (Temperature) — определяет, насколько модель будет предсказуемой. При низкой температуре ИИ всегда выбирает самый вероятный токен (ответ будет строгим и сухим). При высокой — может выбрать вариант с меньшей вероятностью (так рождается «креативность» или галлюцинации).
Шаг 5. Генерация ответа и авторегрессияМодель выбрала один токен (например, слово «База»). Она мгновенно переводит его обратно из цифр в буквы и выводит вам на экран.
А дальше запускается цикл авторегрессии:
ИИ берет ваш изначальный запрос, приклеивает к нему сгенерированное слово «База» и отправляет всю эту увеличившуюся конструкцию обратно на Шаг 1. Процесс повторяется, чтобы предсказать второе слово. Затем третье, четвертое — и так до тех пор, пока модель не наткнется на специальный технический токен EOS (End of Sequence — конец строки).
Резюме: Языковая модель — это не мыслящий субъект, а гигантский, невероятно сложный калькулятор. Она не знает истину, она просто с филигранной точностью вычисляет, какое слово чисто статистически должно идти следующим после вашего вопроса.
OpenAI выпустила GPT-6 Astra — и главное изменение не в том, что она «ещё лучше отвечает на вопросы»
Новая модель сильнее смещается от обычного чата к выполнению задачи целиком.
GPT-6 Astra умеет работать с браузером и интерфейсами программ, проводить исследования, писать и проверять код, анализировать данные, создавать документы, таблицы и презентации.
Сценарий работы выглядит теперь так:
→ поставил задачу
→ модель собрала информацию
→ поработала с нужными инструментами
→ подготовила результат
→ проверила часть выполненной работы
Отдельно OpenAI выделяет несколько улучшений.
→ Работа с компьютером
В тесте OSWorld 2.0 Astra получила 72,6% против 65,7% у GPT-5.6 Sol. При этом выполнение задачи в тестах занимало примерно на 47% меньше времени.
→ Программирование и технические задачи
Модель стала сильнее в работе с терминалом, кодовой базой, настройкой систем и многошаговыми инженерными задачами.
→ Большой контекст
В API доступно контекстное окно 1,05 млн токенов. Это позволяет работать с крупными документами, кодовыми базами и большими объёмами исходных данных в рамках одной задачи.
→ Более длинные рабочие процессы
Astra лучше удерживает исходную цель, когда по ходу работы появляются новые требования и уточнения. Это особенно полезно для задач, которые нельзя решить одним промптом.
→ Безопаснее работает с инструментами
OpenAI также заявляет об улучшенной устойчивости к prompt injection и меньшей вероятности выйти за разрешённые границы при работе с браузером и другими инструментами.
Главный вывод из релиза: развитие моделей идёт уже не только в сторону «умнее написать ответ».
Следующий этап — передать ИИ часть полноценного рабочего процесса: исследование, код, браузер, документы, анализ и проверку результата.
Источник: OpenAI.
Новая модель сильнее смещается от обычного чата к выполнению задачи целиком.
GPT-6 Astra умеет работать с браузером и интерфейсами программ, проводить исследования, писать и проверять код, анализировать данные, создавать документы, таблицы и презентации.
Сценарий работы выглядит теперь так:
→ поставил задачу
→ модель собрала информацию
→ поработала с нужными инструментами
→ подготовила результат
→ проверила часть выполненной работы
Отдельно OpenAI выделяет несколько улучшений.
→ Работа с компьютером
В тесте OSWorld 2.0 Astra получила 72,6% против 65,7% у GPT-5.6 Sol. При этом выполнение задачи в тестах занимало примерно на 47% меньше времени.
→ Программирование и технические задачи
Модель стала сильнее в работе с терминалом, кодовой базой, настройкой систем и многошаговыми инженерными задачами.
→ Большой контекст
В API доступно контекстное окно 1,05 млн токенов. Это позволяет работать с крупными документами, кодовыми базами и большими объёмами исходных данных в рамках одной задачи.
→ Более длинные рабочие процессы
Astra лучше удерживает исходную цель, когда по ходу работы появляются новые требования и уточнения. Это особенно полезно для задач, которые нельзя решить одним промптом.
→ Безопаснее работает с инструментами
OpenAI также заявляет об улучшенной устойчивости к prompt injection и меньшей вероятности выйти за разрешённые границы при работе с браузером и другими инструментами.
Главный вывод из релиза: развитие моделей идёт уже не только в сторону «умнее написать ответ».
Следующий этап — передать ИИ часть полноценного рабочего процесса: исследование, код, браузер, документы, анализ и проверку результата.
Источник: OpenAI.
Почему псевдоним из SELECT работает в ORDER BY, но не работает в WHERE?
Потому что части SQL-запроса обрабатываются не в том порядке, в котором мы их пишем.
Например:
SELECT price * quantity AS total
FROM orders
WHERE total > 1000;
Такой запрос в PostgreSQL не сработает: в момент обработки WHERE псевдонима total ещё нет.
Упрощённо порядок выглядит так:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
Сначала формируется набор строк из FROM, затем WHERE отбрасывает ненужные строки, и только после этого вычисляются выражения из SELECT и появляются их псевдонимы.
Поэтому в WHERE приходится писать само выражение:
SELECT price * quantity AS total
FROM orders
WHERE price * quantity > 1000;
А ORDER BY выполняется уже после SELECT, поэтому псевдоним к этому моменту известен:
SELECT price * quantity AS total
FROM orders
ORDER BY total DESC;
Отсюда правило:
→ WHERE не видит псевдонимы из SELECT
→ ORDER BY видит
Это не особенность alias и не ограничение PostgreSQL ради ограничения. Причина в логическом порядке обработки частей SQL-запроса.
Если помнить этот порядок, становятся понятнее и другие вопросы: почему агрегаты нельзя использовать в WHERE, зачем нужен HAVING и почему некоторые выражения приходится повторять.
Потому что части SQL-запроса обрабатываются не в том порядке, в котором мы их пишем.
Например:
SELECT price * quantity AS total
FROM orders
WHERE total > 1000;
Такой запрос в PostgreSQL не сработает: в момент обработки WHERE псевдонима total ещё нет.
Упрощённо порядок выглядит так:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
Сначала формируется набор строк из FROM, затем WHERE отбрасывает ненужные строки, и только после этого вычисляются выражения из SELECT и появляются их псевдонимы.
Поэтому в WHERE приходится писать само выражение:
SELECT price * quantity AS total
FROM orders
WHERE price * quantity > 1000;
А ORDER BY выполняется уже после SELECT, поэтому псевдоним к этому моменту известен:
SELECT price * quantity AS total
FROM orders
ORDER BY total DESC;
Отсюда правило:
→ WHERE не видит псевдонимы из SELECT
→ ORDER BY видит
Это не особенность alias и не ограничение PostgreSQL ради ограничения. Причина в логическом порядке обработки частей SQL-запроса.
Если помнить этот порядок, становятся понятнее и другие вопросы: почему агрегаты нельзя использовать в WHERE, зачем нужен HAVING и почему некоторые выражения приходится повторять.
🔥3
INTERSECT и EXCEPT — два оператора, которые иногда могут решить задачу проще, чем JOIN
Оба оператора сравнивают результаты двух SELECT и работают с наборами строк, часто еще говорят с множествами.
INTERSECT оставляет только то, что есть в обоих результатах.
Например, есть пользователи двух сервисов:
В результате останутся только user_id, которые встретились и в service_a, и в service_b.
EXCEPT работает наоборот: оставляет строки из первого SELECT, которых нет во втором.
Так мы получим пользователей service_a, которых нет в service_b.
Главное отличие:
→ INTERSECT = пересечение двух наборов
→ EXCEPT = первый набор минус второй
Для EXCEPT порядок запросов имеет значение:
A EXCEPT B — это не то же самое, что B EXCEPT A.
По умолчанию оба оператора удаляют дубликаты. Если повторяющиеся строки нужно учитывать, в PostgreSQL есть INTERSECT ALL и EXCEPT ALL.
Практический вывод: если задача звучит как «найти строки, которые есть в обоих результатах» — смотрим в сторону INTERSECT.
Если как «найти строки из первого результата, которых нет во втором» — EXCEPT.
Оба оператора сравнивают результаты двух SELECT и работают с наборами строк, часто еще говорят с множествами.
INTERSECT оставляет только то, что есть в обоих результатах.
Например, есть пользователи двух сервисов:
SELECT user_id FROM service_a
INTERSECT
SELECT user_id FROM service_b;
В результате останутся только user_id, которые встретились и в service_a, и в service_b.
EXCEPT работает наоборот: оставляет строки из первого SELECT, которых нет во втором.
SELECT user_id FROM service_a
EXCEPT
SELECT user_id FROM service_b;
Так мы получим пользователей service_a, которых нет в service_b.
Главное отличие:
→ INTERSECT = пересечение двух наборов
→ EXCEPT = первый набор минус второй
Для EXCEPT порядок запросов имеет значение:
A EXCEPT B — это не то же самое, что B EXCEPT A.
По умолчанию оба оператора удаляют дубликаты. Если повторяющиеся строки нужно учитывать, в PostgreSQL есть INTERSECT ALL и EXCEPT ALL.
Практический вывод: если задача звучит как «найти строки, которые есть в обоих результатах» — смотрим в сторону INTERSECT.
Если как «найти строки из первого результата, которых нет во втором» — EXCEPT.
🔥1