Изменение столбца идентификации с INT на BIGINT

9

У меня есть таблица со столбцом идентификации, который также является первичным ключом. В настоящее время в нем 50 миллионов строк, а наибольшее значение столбца идентификаторов составляет 148 921 803. Таблица имеет много DELETEs и INSERTSвыполняется на нем, отсюда и высокое значение.

Мы хотим изменить тип данных с INTна, BIGINTчтобы подготовиться к добавлению большего количества строк. Обратите внимание, что нет ссылок на столбец PK.

Каков наилучший способ сделать это с минимальным временем простоя? У меня есть два варианта.

  1. Бросьте PK и измените колонку; или
  2. Метод copy-drop-rename, как описано здесь :
Феликс Памиттан
источник

Ответы:

7

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

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

  1. Бросьте PK и измените колонку; или

Первая капля ПК

/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/

ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO

Изменить столбец

ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT

Добавить первичный ключ

/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD  CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

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

  1. Метод copy-drop-rename, как описано

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

Шашанк Тивари
источник
6

Аарон Бертран имеет серию из четырех частей на эту тему, начиная с:

Минимизация влияния расширения столбца IDENTITY - часть 1

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

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

Более подробно Аарон говорит:

  1. Создайте теневые копии таблиц с правильными типами данных.
  2. Измените хранимые процедуры (или специальный код), чтобы использовать bigint для параметров. (Это может потребовать изменения за пределами списка параметров, таких как локальные переменные, временные таблицы и т. Д., Но здесь это не так.)
  3. Переименуйте старые таблицы и создайте представления с теми именами, которые объединяют старые и новые таблицы.
    • Эти представления вместо триггеров будут правильно направлять операции DML в соответствующие таблицы, так что данные все еще могут быть изменены во время миграции.
    • Это также требует удаления SCHEMABINDING из любых индексированных представлений, существующих представлений, чтобы иметь объединения между новыми и старыми таблицами, и процедур, основанных на SCOPE_IDENTITY (), которые должны быть изменены.
  4. Перенесите старые данные в новые таблицы порциями.
  5. Очистка, состоящая из:
    • Отбрасывание временных представлений (которые будут сбрасывать триггеры INSTEAD OF).
    • Переименование новых таблиц обратно в исходные имена.
    • Исправление хранимых процедур для возврата к SCOPE_IDENTITY ().
    • Отбрасывание старых, теперь пустых таблиц.
    • Возврат SCHEMABINDING обратно на индексированные представления и повторное создание кластеризованных индексов.
Пол Уайт 9
источник