После декомпозиции отношения на две таблицы соединение возвращает лишние комбинации: какой критерий показывает, что декомпозиция была без потерь?
Декомпозиция отношения на два отношения является без потерь, если их естественное соединение всегда восстанавливает исходное отношение без добавления ложных кортежей и без потери исходных кортежей. Для декомпозиции на схемы R1 и R2 общий набор атрибутов должен функционально определять все атрибуты хотя бы одной из частей — это проверяется относительно заданных функциональных зависимостей.
Декомпозиция возникла как средство нормализации реляционной схемы. Разделение одной таблицы уменьшает дублирование данных и риск аномалий вставки, обновления и удаления.
Однако простого разбиения недостаточно: после него нужно уметь восстановить исходные факты. Поэтому в теории реляционных баз данных отдельно проверяют свойство сохранения без потерь соединения.
Пусть отношение содержит атрибуты A, B и C, а его разбиение создаёт отношения R1(A, B) и R2(A, C). Если одно значение A связано с несколькими значениями B и несколькими значениями C независимо, соединение R1 и R2 образует все комбинации этих значений.
В результате появляются строки, которых в исходном отношении не было. Такая ошибка особенно опасна, если результат соединения используется для отчётов, расчёта показателей или формирования зависимых записей.
Для двух отношений R1 и R2 с пересечением X декомпозиция гарантированно является без потерь, если функциональные зависимости подразумевают хотя бы одно из условий:
Иными словами, общий ключ должен однозначно определять одну из частей декомпозиции. Если это условие не выполняется, соединение может породить ложные комбинации.
Например, исходные факты могут выглядеть так: для A=1 существуют пары B=x, C=p и B=y, C=q. После разбиения в R1 останутся пары (1,x) и (1,y), а в R2 — (1,p) и (1,q). Соединение по A дополнительно создаст (1,x,q) и (1,y,p).
Минимальная иллюстрация:
Запрос вернёт четыре комбинации, хотя в исходном отношении было только две. Причина не в ошибке оператора соединения, а в том, что атрибут A не определяет ни B, ни C.
На практике критерий проверяют по функциональным зависимостям, ключам и ограничениям схемы. При сложных зависимостях применяют алгоритм преследования, или chase. Важно отличать сохранение без потерь от сохранения зависимостей: первое говорит о восстановлении данных соединением, второе — о возможности проверять исходные зависимости после декомпозиции без объединения таблиц.
Слишком агрессивная нормализация может увеличить число соединений и усложнить запросы. Денормализация иногда оправдана ради производительности, но тогда необходимо отдельно контролировать согласованность дублируемых данных.
В системе курсов была таблица с атрибутами Курс, Преподаватель и Аудитория. Её разделили на связи «курс—преподаватель» и «курс—аудитория», предполагая, что курс однозначно определяет оба значения.
Первый вариант оставлял разбиение как есть. Он был простым, но неверным: если у курса несколько преподавателей и аудиторий, соединение создавало пары каждого преподавателя с каждой аудиторией.
Второй вариант добавлял в ключ конкретного занятия: Курс, Дата и Время. Это устраняло неоднозначность, но требовало изменить модель и мигрировать данные.
Выбран был второй вариант, потому что именно занятие, а не курс, определяло фактическую пару преподавателя и аудитории. После декомпозиции соединение по полному идентификатору занятия стало без потерь, а отчёты перестали показывать ложные расписания.
Да, если этот общий атрибут действительно является ключом одной из декомпозированных таблиц и ограничения гарантируют соответствующую функциональную зависимость. Например, если общий атрибут X — первичный ключ R1, то X функционально определяет все атрибуты R1, что обеспечивает условие без потерь для этой части.
Но одного совпадения имён или предполагаемой уникальности недостаточно. Свойство должно следовать из модели и ограничений, а не только из текущих данных.
Да. В текущем экземпляре отношения значения могут случайно не порождать ложных комбинаций. Например, у каждого значения общего атрибута может встретиться только одна комбинация, даже если схема не запрещает несколько комбинаций в будущем.
Для гарантии на уровне схемы этого недостаточно: при появлении новых данных соединение может стать lossy. Поэтому проверяют зависимости, действующие для всех допустимых экземпляров отношения.
Внешний ключ гарантирует существование соответствующей строки в другой таблице, но не утверждает, что общий атрибут однозначно определяет остальные атрибуты одной из частей. Он обеспечивает ссылочную целостность, а не нужную функциональную зависимость.
Например, несколько строк дочерней таблицы могут ссылаться на одного родителя. Соединение при этом корректно связывает строки, но при неверно выбранной декомпозиции всё равно может породить лишние комбинации между независимыми дочерними фактами.