добавить ссылки или нет во всех моих таблицах? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть много таких таблиц:

CREATE TABLE `name` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `user` INT(11) UNSIGNED NOT NULL REFERENCES users (`id`),
  `user2` INT(11) UNSIGNED NOT NULL REFERENCES users (`id`),
  `data` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

Я хотел бы знать, является ли этот references users хорошим выбором, я должен оставить это поле пустым для повышения производительности и улучшения?

1 Ответ

0 голосов
/ 04 мая 2018

Использование внешних ключей имеет мало общего с производительностью. На самом деле, это может добавить немного накладных расходов, потому что любая вставка или обновление вашей таблицы должно проверять наличие значения в ссылочной таблице. Но на практике это не намного дороже, чем обновление индекса.

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

Конечный результат одинаков в отношении способа хранения данных и влияния на производительность. Единственная разница заключается в синтаксисе, используемом для определения ограничений внешнего ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...