Реляционные базы данных и SQL: как устроены таблицы, связи и JOIN-запросы
Многие думают, что «реляционные» базы — это про «отношения» между таблицами. Это верно, но лишь отчасти. На самом деле, термин происходит от математической теории отношений (relation), и именно эта основа — ключ к пониманию их строгой структуры.
Реляционные базы — движок бесчисленного количества приложений. SQL — язык, который позволяет ему работать. По данным Stack Overflow Developer Survey 2024, SQL стабильно входит в топ-3 самых популярных технологий. Это показатель его фундаментальной важности.
Почему «реляционные»? От математики к таблицам
В основе лежит не просто таблица-сетка. С точки зрения теории, таблица — это отношение (relation). Это строгий набор строк (кортежей), где каждый столбец (атрибут) имеет уникальное имя и тип.
Главное следствие — порядок строк не имеет значения, а сами строки должны быть уникальны. Это сразу решает проблему дубликатов. Как писал К. Дж. Дейт, именно эта модель отличает СУБД от простых коллекций файлов.
Ключи таблиц: первичные и внешние
Чтобы строки можно было однозначно идентифицировать, нужен первичный ключ (PRIMARY KEY). Это столбец или комбинация столбцов с уникальными значениями. Пример — student_id в таблице Студенты.
Но сила баз раскрывается, когда таблицы ссылаются друг на друга. Для этого существует внешний ключ (FOREIGN KEY). Это столбец в одной таблице, который указывает на первичный ключ в другой.
Пример: таблица Студенты с ключом id и таблица Зачетки, где student_id — внешний ключ, ссылающийся на id в Студентах. Так рождается связь.
Три типа связей между таблицами
1. Один к одному (1:1). Например, человек и его паспорт. На практике такие таблицы часто объединяют в одну.
2. Один ко многим (1:M). Самая распространенная связь. Один студент может иметь много записей об оценках. Реализуется через внешний ключ в таблице «многих».
3. Многие ко многим (M:M). Студенты и Курсы. Нужна третья, связующая таблица, которая содержит внешние ключи на обе исходные.
Как писать простые JOIN: пример на основе связей
SQL-запрос JOIN позволяет «склеить» связанные таблицы. Самый частый тип — INNER JOIN. Он возвращает только те строки, для которых есть связь в обеих таблицах.
Вернемся к Студентам и Зачеткам. Хотим получить отчет: имя студента и все его оценки.
SELECT
Студенты.имя,
Зачетки.предмет,
Зачетки.оценка
FROM
Студенты
INNER JOIN
Зачетки ON Студенты.id = Зачетки.student_id;
Давайте разберем запрос по шагам:
В результате получим сводную таблицу, где каждая оценка будет стоять рядом с именем соответствующего студента:
Какой тип связи (1:1, 1:M, M:M) вызывает у вас больше всего вопросов при проектировании схемы?