Устранение несоответствий БД - поля идентификаторов - PullRequest
3 голосов
/ 15 января 2009

Я унаследовал (Microsoft?) Базу данных SQL, которая в исходном состоянии была не очень чистой. В нем все еще есть некоторые очень странные вещи, которые я пытаюсь исправить - одна из них - непоследовательные записи идентификаторов.

В таблице счетов каждая запись имеет номер, называемый accountID, на который есть ссылки в нескольких других таблицах (заметки, оборудование и т. Д.). Проблема заключается в том, что числа (по какой-то случайной причине) варьируются от -100000 до +2000000, когда записей всего около 7000.

Есть ли какой-нибудь хороший способ перенумеровать их при изменении соответствующих номеров в других таблицах? В моем распоряжении также есть ColdFusion, поэтому все, что работает с SQL и / или что я приму.

Ответы [ 6 ]

4 голосов
/ 15 января 2009

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

2 голосов
/ 15 января 2009

В данном случае это звучит как «почему» - это лучший вопрос, чем «как». ОП отмечает, что есть странная проблема, которую нужно исправить, но не говорит, почему это проблема. Это вызывает проблемы? Какое положительное влияние окажет изменение этих цифр? Если вы изначально не запрограммировали систему и точно не понимаете, почему номер находится в его текущем состоянии, вы делаете довольно рискованные изменения, подобные этим.

1 голос
/ 15 января 2009

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

0 голосов
/ 15 января 2009

Создайте новый столбец в таблице счетов для нового идентификатора и новый столбец в каждой из связанных таблиц для ссылки на новый столбец идентификатора.

ALTER TABLE accounts
ADD new_accountID int IDENTITY

ALTER TABLE notes
ADD new_accountID int

ALTER TABLE equipment
ADD new_accountID int

Затем вы можете сопоставить столбец new_accountID в каждой из ваших ссылочных таблиц с таблицей счетов.

UPDATE notes
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN notes ON (notes.accountID = accounts.accountID)

UPDATE equipment
SET new_accountID = accounts.new_accountID
FROM accounts
INNER JOIN equipment ON (equipment.accountID = accounts.accountID)

На данный момент каждая таблица имеет и accountID со старыми ключами, и new_accountID с новыми ключами. Отсюда все должно быть довольно просто.

  1. Сломать все внешние ключи на accountID.
  2. В каждой таблице UPDATE [таблица] SET accountID = new_accountID.
  3. Повторно добавить внешние ключи для accountID.
  4. Удалите new_accountID из всех таблиц, так как он больше не нужен.
0 голосов
/ 15 января 2009

С ColdFusion это не должно быть геркулесовой задачей, но это будет грязно, и вам нужно быть осторожным. Один из методов, который вы могли бы использовать, - это сценарий базы данных, а затем сгенерировать совершенно новую, пустую схему таблицы. Установите accountID в качестве поля идентификации в новой базе данных.

Затем, используя ColdFusion, напишите запрос, который будет извлекать все старые данные учетной записи и вставлять их в новую базу данных один за другим. Для каждой строки пусть новая база данных назначит новый идентификатор. После каждой вставки извлекайте новый идентификатор (используя @@ IDENTITY или MAX (accountID)) и сохраняйте новый идентификатор и старый идентификатор вместе во временной таблице, чтобы вы знали, какие старые идентификаторы принадлежат каким новым идентификаторам.

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

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

0 голосов
/ 15 января 2009

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

Проверьте сценарий здесь: http://vyaskn.tripod.com/sql_server_search_and_replace.htm

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

Стоит, однако, спросить, почему эти значения оказываются не в порядке. В этой базе данных постоянно добавляются и удаляются значения? Являются ли значения первичного ключа действительно произвольными или они только кажутся, но они действительно имеют значение? Хотя я все за консолидацию, вы должны убедиться, что эти значения не имеют смысла.

...