Связи таблиц
Связь существует благодаря ключам и ограничениям БД, а не потому, что в Java есть ссылка.
Основные виды
| Вид | Физическое представление | Пример |
|---|---|---|
| один ко многим | внешний ключ в таблице «многие» | заказ → строки заказа |
| один к одному | внешний ключ с UNIQUE либо общий PK | пользователь → профиль |
| многие ко многим | таблица связи с двумя внешними ключами | пользователь ↔ роль |
| самоссылка | внешний ключ на ту же таблицу | категория → родитель |
Целостность
Внешний ключ гарантирует существование целевой строки, но не все бизнес-правила. Обычно дополнительно нужны:
NOT NULL, если связь обязательна;UNIQUE, если допускается только одна связанная строка;- индекс по внешнему ключу для соединений и удаления родителя;
- осознанное
ON DELETE:RESTRICT,CASCADE,SET NULL.
Каскад БД и cascade ORM решают разные задачи. Первый работает со строками независимо от приложения, второй распространяет операции по графу сущностей.
Направление
Реляционная связь не «двунаправленная»: таблицы соединяются запросом. Направление появляется в объектной модели. Двунаправленную JPA-связь нужно поддерживать с обеих сторон:
void addLine(OrderLine line) {
lines.add(line);
line.setOrder(this);
}Типичные сбои
- many-to-many скрывает атрибуты отношения;
- внешний ключ без индекса замедляет join и каскадное удаление;
- nullable-связь используется там, где бизнес-правило требует обязательность;
- удаление родителя внезапно удаляет большой граф;
- коллекция и обратная ссылка расходятся в памяти.
Вопросы для повторения
- Где хранится внешний ключ для one-to-many? В таблице стороны «многие».
- Как представить one-to-one? Внешним ключом с уникальным ограничением или общим первичным ключом.
- Когда нужна отдельная сущность связи? Когда у отношения есть поля, поведение или самостоятельный жизненный цикл.
- Зачем индексировать внешний ключ? Для join и проверки/выполнения операций над родителем.
- Чем cascade ORM отличается от
ON DELETE CASCADE? Первый выполняется логикой ORM, второй — самой БД.
Связано: Многотабличные запросы операция JOIN, JoinColumn JoinTable, Маппинг Hibernate.