На самом деле нет никакой физической разницы между «реальным» внешним ключом и «логическим» внешним ключом. Они оба являются просто столбцами в таблице и не влияют на способ хранения таблицы на диске. Это на самом деле меня тоже удивило, когда я впервые узнал.
Единственное отличие состоит в том, что когда у вас есть "реальный" внешний ключ, всякий раз, когда в таблице запускается оператор удаления, обновления или вставки, сервер базы данных должен проверить, что значение обновляется до допустимого значения. Если вы посмотрите на план выполнения для оператора, который является обновлением, вставкой, удалением или слиянием, вы фактически увидите, что он должен сканировать или искать все таблицы, имеющие внешний ключ.
Это может сильно снизить производительность, если много внешних ключей или нет полезных индексов.
Представьте, что у вас есть таблица для компаний, а затем еще одна таблица для сотрудников. Ваша таблица сотрудников, скорее всего, будет иметь столбец с названием companyId.
При запуске:
delete from Companies where companyId = 123;
Сервер базы данных должен убедиться, что в этой компании нет сотрудников. То же самое относится и к бегу:
insert into Employees (companyId, name) values (123, 'John');
Сервер базы данных должен выполнить поиск в таблице компаний, чтобы убедиться, что companyId 123 существует.
Да быстрее иметь только «логические» внешние ключи. Однако это происходит за счет возможного повреждения данных и может потребовать больше времени для поиска ошибок и других источников повреждения данных. Стоит ли оно того, решать вам. Следует учитывать, что это не влияет на запросы только для чтения.
Редактировать Как указал Мартин Смит, и я ушел, есть некоторые случаи, когда внешний ключ будет быстрее. Если в таблице есть внутреннее соединение с внешним ключом, а вторая таблица не ссылается ни на какие столбцы, запрос не должен попадать во вторую таблицу, поскольку он может доверять внешнему ключу.