Изменение первичного ключа. Изменение внешнего ключа. - PullRequest
0 голосов
/ 04 января 2011

У меня проблема, я работаю с существующей базой данных SQL Server 2008: мне нужно иногда изменять значение первичного ключа для некоторых существующих записей в таблице. К сожалению, существует около 30 других таблиц с ссылками на внешние ключи к этой таблице.

Какой самый элегантный способ изменить первичный ключ и связанные внешние ключи?

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

Спасибо!

Ответы [ 3 ]

7 голосов
/ 04 января 2011

Когда вы говорите: «Я не в ситуации, когда могу изменить существующую структуру ключей», вы можете добавить опцию ON UPDATE CASCADE к внешним ключам?Это самый простой способ справиться с этой ситуацией - программирование не требуется.

2 голосов
/ 04 января 2011

Как сказал Ларри, при обновлении Cascade будет работать, однако это может вызвать серьезные проблемы в рабочей базе данных, и большинство dbas не слишком рады тому, что вы можете использовать его. Например, предположим, что у вас есть клиент, который меняет название своей компании (и это PK), и в разных таблицах есть два миллиона связанных записей. При UPDATE Cascade выполнит все обновления в одной транзакции, которые могут заблокировать ваши основные таблицы на несколько часов. Это одна из причин, почему очень плохая идея иметь PK, который нужно будет заменить. Триггер был бы таким же плохим, и если его неправильно написать, он мог бы быть намного хуже.

Если вы вносите изменения в сохраненный процесс, вы можете поместить каждую часть в отдельную транзакцию, так что, по крайней мере, вы не блокируете все. Вы также можете обновлять записи в пакетах, так что если у вас есть миллион записей для обновления в таблице, вы можете делать их небольшими партиями, которые будут работать быстрее и иметь меньше блокировок. Лучший способ сделать это - создать новую запись в первичной таблице с новым PK, а затем переместить старые записи в новую в пакетном режиме, а затем удалить старую запись после перемещения всех связанных записей. Если вы делаете такие вещи, лучше всего иметь таблицы аудита, чтобы вы могли легко восстановить данные, если возникнет проблема, поскольку вы захотите сделать это в нескольких транзакциях, чтобы избежать блокировки всей базы данных. Теперь это сложнее поддерживать, вы должны помнить, чтобы добавить в процесс, когда вы добавляете FK (но вы также должны помнить, что нужно делать и с UPDATE CASCADE). С другой стороны, если он выходит из строя из-за проблемы с новым FK, это легко исправить, вы точно знаете, в чем проблема, и можете легко внести изменения в продукт относительно быстро.

Нет простых решений этой проблемы, потому что основная проблема - плохой дизайн. Вам нужно будет просмотреть все «за» и «против» всех решений (я бы отбросил идею триггера, так как Cascade Update будет работать лучше и будет меньше подвержен ошибкам), и решу, что работает лучше всего в вашем случае. Помните, что целостность данных и производительность имеют решающее значение для корпоративных баз данных и могут быть важнее, чем удобство обслуживания (я знаю, это ересь).

1 голос
/ 04 января 2011

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

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

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

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