Отношения, кортежи, атрибуты и домены

Под привычной «таблицей» скрывается строгий математический объект — отношение. Разберём его по косточкам и поймём, что из этого следует на практике.

Отношение — это множество кортежей, заданных над одной схемой (набором атрибутов с доменами). Проще говоря, отношение — это таблица, но с важными математическими свойствами, которые из обычной «таблицы как в Excel» не следуют.

Зачем нам точные термины

Может показаться, что разница между «таблицей» и «отношением», между «строкой» и «кортежем» — занудство. Но именно она отделяет инженера, понимающего базу, от того, кто заучил синтаксис. Строгие термины дают язык для рассуждения о корректности. Когда дальше мы скажем «проекция удаляет дубликаты» (раздел про алгебру) или «функциональная зависимость — это утверждение об отношении, а не о текущей таблице» (раздел про нормализацию), за этими словами будет стоять точный смысл, а не интуиция. Так что усилие на освоение терминов сейчас окупится во всех следующих разделах.

Зачем нам строгость

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

Откуда взялось слово «отношение»

Название «отношение» (relation) часто сбивает с толку: кажется, что речь о связи между таблицами. На самом деле термин пришёл из математики. В теории множеств отношение — это подмножество декартова произведения множеств (доменов). Если домен имён — это все возможные имена, а домен годов — все годы, то их декартово произведение — все мыслимые пары «(имя, год)». Конкретное отношение «книги» — это подмножество таких пар: только те комбинации, которые реально существуют. Отсюда и слово: отношение «соотносит» значения разных доменов друг с другом. Понимать это математическое происхождение полезно: оно объясняет, почему отношение — множество (а значит, без дубликатов и без порядка) и почему к нему применимы операции над множествами, которым посвящён отдельный раздел курса.

Базовые понятия

Рассмотрим таблицу книг в библиотеке.

idtitleauthoryear
1Война и мирТолстой1869
2Преступление и наказаниеДостоевский1866
  • Атрибут — именованный столбец: id, title, author, year. У атрибута есть имя и домен.
  • Домен — множество допустимых значений атрибута. Домен year — целые числа (скажем, от 1 до текущего года); домен title — строки. Домен — это «тип плюс смысл»: оба атрибута могут быть целыми числами, но складывать id книги с year бессмысленно — это разные домены.
  • Кортеж — одна строка: набор значений по одному из каждого домена, например (1, 'Война и мир', 'Толстой', 1869).
  • Схема отношения — имя отношения и список его атрибутов с доменами: Books(id, title, author, year). Это «заголовок».
  • Экземпляр отношения (тело) — конкретное множество кортежей в данный момент.
  • Степень отношения — число атрибутов (здесь 4). Кардинальность — число кортежей (здесь 2).

Ключевые свойства отношения

Раз отношение — это множество кортежей, из определения множества следуют свойства, которые отличают отношение от вольной «таблицы».

  • Нет повторяющихся кортежей. Множество не содержит дубликатов: двух полностью одинаковых строк в отношении быть не может. (SQL-таблицы это правило ослабляют — об этом ниже.)
  • Порядок кортежей не важен. Множество неупорядочено: переставить строки — то же самое отношение. Поэтому без ORDER BY порядок строк в SQL не гарантирован.
  • Порядок атрибутов не важен (в теории). К значениям обращаются по имени атрибута, а не по позиции. На практике SQL хранит порядок столбцов, но опираться на него в запросах — плохая привычка.
  • Атомарность значений (1NF). В каждой ячейке — одно неделимое значение из домена, а не список и не вложенная таблица. Это требование первой нормальной формы, к которой мы вернёмся в разделе про нормализацию.

Атомарность на примере

Требование атомарности (1NF) на практике встречается сплошь и рядом в нарушенном виде, и его стоит прочувствовать. Допустим, начинающий проектировщик решил хранить теги книги в одном поле строкой «фантастика, классика, приключения». Формально это «одно значение», но семантически — список. Проблемы всплывают мгновенно: как найти все книги с тегом «классика»? Через поиск подстроки, который сломается на «неоклассика». Как добавить тег, не затронув остальные? Только переписав всю строку. Как посчитать книги по каждому тегу? Почти невозможно. Атомарность требует: один тег — одно значение в отдельной строке (обычно в связанной таблице тегов). Тогда поиск, подсчёт и изменение становятся обычными операциями. Запомните: если внутри ячейки прячется список — это сигнал, что модель данных нарушена, и расплата придёт на первом же нетривиальном запросе.

Отношение против таблицы SQL: важная оговорка

SQL-таблица — это инженерная реализация отношения, и она в двух местах отступает от чистой теории. Во-первых, таблица без ограничений может содержать дубликаты строк (а отношение — множество, дубликатов в нём нет). Во-вторых, в SQL результат запроса по умолчанию — это мультимножество (bag), а не множество: SELECT сохраняет повторы, пока вы явно не напишете DISTINCT. Понимать этот зазор полезно: многие «странности» SQL объясняются тем, что он работает с мультимножествами, а теория — с множествами.

CREATE TABLE books (id INTEGER, author TEXT);
INSERT INTO books VALUES (1, 'Толстой'), (2, 'Толстой'), (3, 'Чехов');

-- SELECT по умолчанию возвращает мультимножество (с повторами)
SELECT author FROM books;

Вывод: три строки, где «Толстой» встречается дважды. Чтобы получить чистое множество авторов, как требует теория, нужен DISTINCT:

CREATE TABLE books (id INTEGER, author TEXT);
INSERT INTO books VALUES (1, 'Толстой'), (2, 'Толстой'), (3, 'Чехов');

SELECT DISTINCT author FROM books;

Степень, кардинальность и пустые отношения

Два числовых параметра отношения стоит закрепить, потому что ими описывают «размер» в теории. Степень (арность) — число атрибутов; это свойство схемы, оно стабильно. Кардинальность — число кортежей; это свойство состояния, оно меняется при каждой вставке. Отношение степени 0 (без атрибутов) и отношение кардинальности 0 (без кортежей) — допустимые крайние случаи. Пустое отношение (ноль кортежей) — совершенно нормальное состояние: таблица заказов нового магазина пуста, но схема у неё есть. Не путайте «пустое отношение» с «отсутствием отношения»: первое существует и имеет схему, просто пока без строк.

Почему домены важны на практике

Домены — не педантизм. Если СУБД (или проектировщик) следит за доменами, она не даст сравнить несравнимое и поймает класс ошибок. Положили возраст в домен «целые 0..150» — и значение 999 будет отвергнуто ограничением. На практике в SQL домены выражаются типами столбцов плюс ограничениями CHECK, а в некоторых СУБД (PostgreSQL) есть и явные пользовательские домены.

Глубокая идея домена — в сравнимости. Реляционная модель разрешает сравнивать значения только из одного домена. Атрибуты id_книги и год_издания оба целые, но принадлежат разным доменам, и запрос вроде «найди книги, у которых id равен году» — бессмыслица, которую строгая модель должна отвергать. На практике большинство SQL-СУБД этого не проверяют (они смотрят лишь на тип данных), поэтому ответственность за «доменную дисциплину» во многом ложится на проектировщика. Привычка мысленно держать домены раздельно спасает от целого класса логических ошибок в запросах.

Реляционная модель как основа: что мы получили

Зафиксируем, зачем нам эта строгость на входе в курс. Определив отношение как множество кортежей над схемой из доменов, мы получили объект с предсказуемыми свойствами, к которому применима математика. Дальше из этих свойств вырастет всё: операции реляционной алгебры (раз отношение — множество, к нему применимы операции над множествами), понятие ключа (раз дубликатов нет, кортежи можно идентифицировать), функциональные зависимости и нормализация. Каждое из этих понятий мы будем выводить, а не постулировать, — и возможность вывода и есть главная ценность строгого определения отношения.

Типичные заблуждения

  • «Отношение и таблица — полные синонимы». Почти, но отношение — множество (без дубликатов, неупорядочено), а SQL-таблица допускает повторы и хранит порядок столбцов.
  • «Порядок строк можно использовать». Нет: без ORDER BY порядок не определён, потому что тело отношения — множество.
  • «Домен — это просто тип данных». Домен — это тип плюс смысл; два целочисленных атрибута могут принадлежать разным доменам, и сравнивать их бессмысленно.

Итог

  • Отношение — это множество кортежей над схемой из атрибутов и доменов; «таблица» — его привычное имя.
  • Из определения множества следуют ключевые свойства: нет дубликатов, порядок строк и атрибутов не важен, значения атомарны.
  • SQL-таблица отступает от теории: допускает дубликаты, а запросы по умолчанию возвращают мультимножество — отсюда нужен DISTINCT.
  • Домен — это множество допустимых значений со смыслом, а не просто тип данных.
Проверьте себя
1. Почему без ORDER BY порядок строк в результате SQL-запроса не гарантирован?
AИз-за ошибки в стандарте SQL
BТело отношения — это множество, а множество неупорядочено
CПотому что строки хранятся случайно на диске
DПотому что СУБД экономит память
2. Чем отношение в теории отличается от обычной SQL-таблицы?
AОтношение может содержать дубликаты, а таблица нет
BОтношение — множество без дубликатов, а SQL-таблица допускает повторяющиеся строки
CОтношение хранится на диске, а таблица в памяти
DРазличий нет
3. Что такое домен атрибута?
AИмя столбца
BМножество допустимых значений атрибута (тип со смыслом)
CЧисло строк в таблице
DВнешний ключ
Поддержать проект