Есть ли какой-то недостаток, если таблица имеет много (более 20) ограничений внешнего ключа?
Допустим, у меня есть таблица, в которой есть много полей, связанных со значениями из других "таблиц значений". Естественно, я объявляю ограничения внешнего ключа для каждого и уклоняюсь от них для обеспечения целостности.
Что если я наконец получу количество таких полей в диапазоне 20-30? Будет ли это как-то "медленные" операции с таблицами или нет?
ДОБАВЛЕНО: Ожидается, что в таблицах значений будет только несколько записей, обычно 5-10 или что-то в этом роде. База данных SQL Server 2008.
6 ответов
Когда вы вставляете строку в вашу дочернюю таблицу, механизм БД будет искать, существуют ли соответствующие значения в родительских таблицах - это потребует некоторого количества ресурсов ЦП и некоторых логических операций чтения. Если ваши родительские таблицы маленькие, они, скорее всего, будут в кеше, так что вы не ожидаете много медленных физических чтений, как только ваша трость нагреется.
Что меня больше всего беспокоит, так это то, что вы когда-нибудь собираетесь удалять из родительских таблиц: если у вас нет соответствующего индекса в дочерней таблице, вся дочерняя таблица будет заблокирована и отсканирована. С другой стороны, если у вас есть соответствующие индексы для всех ваших внешних ключей, то вы можете получить до 20-30 дополнительных индексов в вашей дочерней таблице, что является значительным замедлением.
Возможно, вы захотите запустить свои собственные тесты и убедиться сами.
Да, при вставке и обновлении существует некоторое снижение производительности, поскольку проверяются все соответствующие ограничения, но вряд ли это вызовет какие-либо проблемы, если вы не пытаетесь вставить данные с высокой скоростью. Как правило, более важно, чтобы данные поддерживались правильно, а не быстро, поэтому штраф стоит того.
Если вы выполняете ОБНОВЛЕНИЕ нескольких столбцов, необходимо проверить только ограничения на эти столбцы, и большинство СУБД будут проверять только эти ограничения.
Конечно, операторы SELECT не будут замедляться вообще, а в некоторых (возможно, редких) случаях может быть даже полезно, если оптимизатор будет осведомлен о взаимосвязи внешнего ключа между двумя объединяемыми таблицами.
Наличие одного внешнего ключа замедляет операции вставки / обновления по сравнению с нулевым внешним ключом - просто потому, что база данных должна проверить, что значение внешнего ключа действительно существует. Наличие 30 внешних ключей будет медленнее, чем отсутствие.
Тем не менее, насколько медленнее это будет, зависит от многих вещей, в том числе от размера таблиц значений / движка базы данных, который вы используете / indexes / etc... и может быть практически незначительным в лучшем случае.
Сколько из 20-30 полей редко привыкаешь? Может быть, какой-то другой стол может быть построен. Это усложняет необходимость обновления двух таблиц с точки зрения кодирования, но ускорит процесс, если большую часть времени вы не будете обновлять вторую таблицу.
Я имею дело со сторонним приложением, у которого есть основные таблицы с соответствующими "пользовательскими" таблицами, где мы можем настроить свои собственные поля. К сожалению, мы постоянно используем "настраиваемые" поля и редко можем справиться с работой только с основной таблицей.
Я думаю, что это будет зависеть от того, используют ли ваши запросы какие-либо из ограничений. Если ваш запрос будет нуждаться в проверке другой таблицы из-за ограничений, то вы увидите снижение производительности. Если ваш запрос не ссылается ни на какие столбцы в ограничениях, снижение производительности, вероятно, будет незначительным.
Как и все, что связано с дизайном базы данных, это "зависит". Если ваше приложение выполняет интенсивную вставку, обновление и удаление, вы столкнетесь с проблемами производительности. Это может быть тот случай, когда можно было бы оправдать денормализацию, особенно если таблицы "значений" не меняются.