Использование внешних ключей имеет мало общего с производительностью. На самом деле, это может добавить немного накладных расходов, потому что любая вставка или обновление вашей таблицы должно проверять наличие значения в ссылочной таблице. Но на практике это не намного дороже, чем обновление индекса.
Причиной использования внешних ключей является не производительность, а обеспечение целостности данных. Без внешнего ключа любое обновление вашей базы данных может удалить родительскую строку в users
, даже если в name
есть строки, ссылающиеся на нее. Без ограничения внешнего ключа, только ваши привычки кодирования сохраняют данные нетронутыми. С ограничением внешнего ключа удаление строки в users
вернет ошибку, если есть другие строки, зависящие от него.
Может показаться, что это хорошая идея, но существуют разные мнения. Ограничение может ограничить некоторую работу, которую вам нужно сделать. Я разговаривал с разработчиками, которые считают, что ограничения мешают им, например, когда им нужно очистить искаженные данные. Также верно, что поведение блокировки может вас удивить: например, если вы обновите зависимую строку в name
, то создадите блокировку для строки, на которую она ссылается в users
.
/* this also implicitly puts a shared lock on `users` where id = 1234 */
UPDATE name SET ... WHERE user = 1234;
К сожалению, механизм хранения MySQL InnoDB не поддерживает показанный вами синтаксис, где вы объявляете предложение REFERENCES
в каждом определении столбца. Несмотря на то, что это стандартный SQL, он не распознается в MySQL.
Вы обнаружите, что определение внешних ключей таким способом принимается без ошибок, но оно игнорирует запрос в молчании и не реализует ограничение.
InnoDB поддерживает только синтаксис для внешних ключей уровня таблицы:
CREATE TABLE `name` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user` INT(11) UNSIGNED NOT NULL,
`user2` INT(11) UNSIGNED NOT NULL,
`data` datetime NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`user`) REFERENCES users (`id`),
FOREIGN KEY (`user2`) REFERENCES users (`id`)
) ENGINE=InnoDB;
Конечный результат одинаков в отношении способа хранения данных и влияния на производительность. Единственная разница заключается в синтаксисе, используемом для определения ограничений внешнего ключа.