Какие проблемы возникают при отсутствии внешнего ключа между таблицами ученик и школа?
Что проверяют
Понимаете ли вы, что внешний ключ это ограничение целостности, которое держит база, а не код. Следом часто спрашивают, почему бы не проверять существование школы в сервисе и бывают ли случаи, когда ключи сознательно не ставят.
Как отвечать
- сироты: в
student.school_idможно записать id несуществующей школы или оставить ссылку после её удаления.INNER JOINмолча теряет таких учеников, отчёты расходятся с реальностью; - нет правил удаления: без ключа база не знает, что делать с учениками при удалении школы. С ключом это задаётся явно: запрет (
NO ACTIONпо умолчанию илиRESTRICT),CASCADEилиSET NULL; - гонка при проверке в коде: сервис убедился, что школа есть, а между проверкой и
INSERTдругая транзакция её удалила. Без блокировок такую проверку корректно не сделать, а ключ закрывает её атомарно; - сюрпризы в Hibernate:
@ManyToOneна отсутствующую запись при ленивой загрузке падает сEntityNotFoundException, и ошибка всплывает далеко от места, где испортили данные; - другие клиенты базы: ручные скрипты, импорт и соседний сервис вашу валидацию не проходят.
Про производительность скажите честно: ключ запросы почти не ускоряет и добавляет проверку на каждую вставку. Зато при удалении школы база ищет ссылающихся учеников, и без индекса по school_id это полный скан. PostgreSQL такой индекс сам не создаёт, MySQL InnoDB создаёт.
Ключи не ставят, когда школа живёт в другом сервисе или базе, при шардировании, иногда на массовых загрузках. Тогда целостность компенсируют: проверка при записи, событие об удалении школы, периодический поиск сирот через LEFT JOIN school s ... WHERE s.id IS NULL.
Где спотыкаются
Приписывают внешнему ключу защиту от дублей. От повторов защищает уникальное ограничение, ключ проверяет только существование ссылки.
Считают, что ddl-auto в Hibernate решает вопрос. На проде схема живёт в миграциях Flyway или Liquibase, и ключ там нужно объявить явно.
Ставят CASCADE на всё подряд. Одно удаление школы молча уносит сотни учеников вместе с оценками, хотя обычно нужен запрет или мягкое удаление.