Можно ли выполнить операцию JOIN, если между таблицами в базе данных не настроены связи (FOREIGN KEY)?

«Можно ли выполнить операцию JOIN, если между таблицами в базе данных не настроены связи (FOREIGN KEY)?» — вопрос из категории Базы данных, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, абсолютно. JOIN — это операция языка SQL, выполняемая во время выполнения запроса. Она не требует наличия предварительно объявленных ограничений внешнего ключа (FOREIGN KEY) в схеме базы данных. Для JOIN достаточно указать условие соединения в предложении ON или WHERE.

Пример запроса без FOREIGN KEY:

SELECT 
    e.employee_id,
    e.name,
    d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;

Этот запрос выполнится, даже если между employees.department_id и departments.department_id нет объявленной связи.

Роль FOREIGN KEY:

  1. Целостность данных: Гарантирует, что значение в столбце ссылается на существующую запись в другой таблице. Без FOREIGN KEY в department_id может оказаться любое число.
  2. Производительность: Часто автоматически создаётся индекс, который может ускорить выполнение JOIN.
  3. Каскадные операции: Позволяет автоматически удалять или обновлять связанные записи (ON DELETE CASCADE).

Работа с JOIN в C++ (на примере SQLite):

#include <sqlite3.h>
#include <iostream>

// ... инициализация БД ...

std::string sql = R"(
    SELECT users.name, orders.total_amount
    FROM users
    INNER JOIN orders ON users.id = orders.user_id
    WHERE orders.date > '2024-01-01'
)";

sqlite3_stmt* stmt;
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) == SQLITE_OK) {
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
        double amount = sqlite3_column_double(stmt, 1);
        std::cout << name << ": " << amount << std::endl;
    }
    sqlite3_finalize(stmt);
}

Таким образом, JOIN работает на уровне запроса, а FOREIGN KEY — на уровне целостности схемы данных.