Связи таблиц

Связь существует благодаря ключам и ограничениям БД, а не потому, что в 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-связь используется там, где бизнес-правило требует обязательность;
  • удаление родителя внезапно удаляет большой граф;
  • коллекция и обратная ссылка расходятся в памяти.

Вопросы для повторения

  1. Где хранится внешний ключ для one-to-many? В таблице стороны «многие».
  2. Как представить one-to-one? Внешним ключом с уникальным ограничением или общим первичным ключом.
  3. Когда нужна отдельная сущность связи? Когда у отношения есть поля, поведение или самостоятельный жизненный цикл.
  4. Зачем индексировать внешний ключ? Для join и проверки/выполнения операций над родителем.
  5. Чем cascade ORM отличается от ON DELETE CASCADE? Первый выполняется логикой ORM, второй — самой БД.

Связано: Многотабличные запросы операция JOIN, JoinColumn JoinTable, Маппинг Hibernate.