Alterando a coluna de identidade de INT para BIGINT

9

Eu tenho uma tabela com uma coluna de identidade que também é uma chave primária. Atualmente, possui 50 milhões de linhas, com o valor mais alto da coluna de identidade em 148.921.803. A tabela possui muitos DELETEs e é INSERTSexecutada nela, daí o alto valor.

Queremos alterar o tipo de dados de INTpara BIGINTpara preparar a adição de mais linhas. Observe que, não há referências à coluna PK.

Qual é a melhor maneira de fazer isso, com tempo de inatividade mínimo? Eu tenho duas opções

  1. Solte o PK e altere a coluna; ou
  2. O método copy-drop-rename, conforme descrito aqui :
Felix Pamittan
fonte

Respostas:

7

Como existe uma chave primária definida na coluna de identidade, você não poderá alterar diretamente essa coluna.

As duas abordagens que você mencionou na sua pergunta podem ser usadas e o tempo de inatividade depende do desempenho do servidor e do número de linhas nessa tabela.

  1. Solte o PK e altere a coluna; ou

Primeiro solte o PK

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

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

Alterar coluna

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

Adicionar chave primária

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

Essa abordagem geralmente não leva muito tempo. No meu ambiente, são necessários segundos em grandes mesas com mais de 5 milhões de linhas.

  1. O método copy-drop-rename, conforme descrito

Você pode usar essa abordagem também. No entanto, para essa abordagem, você precisa de mais tempo de inatividade do que a abordagem 1, pois precisa sincronizar as tabelas.

Shashank Tiwari
fonte
6

Aaron Bertrand tem uma série de 4 partes sobre esse tópico, começando com:

Minimizando o impacto do alargamento de uma coluna IDENTITY - parte 1

Se você absolutamente precisa mudar bigint, deve minimizar o tempo de inatividade e ter bastante tempo para planejar, a abordagem que ele documenta na parte 4 é:

Em um nível muito alto, a abordagem é criar um conjunto de tabelas de sombra, onde todas as inserções são direcionadas para uma nova cópia da tabela (com o tipo de dados maior), e a existência dos dois conjuntos de tabelas é tão transparente possível para o aplicativo e seus usuários.

Mais detalhadamente, Aaron diz:

  1. Crie cópias de sombra das tabelas, com os tipos de dados corretos.
  2. Altere os procedimentos armazenados (ou código ad hoc) para usar bigint para parâmetros. (Isso pode exigir modificações além da lista de parâmetros, como variáveis ​​locais, tabelas temporárias, etc., mas não é o caso aqui.)
  3. Renomeie as tabelas antigas e crie visualizações com os nomes que unem as tabelas antigas e novas.
    • Essas visualizações terão, em vez de gatilhos, para direcionar adequadamente as operações DML para a (s) tabela (s) apropriada (s), para que os dados ainda possam ser modificados durante a migração.
    • Isso também requer que SCHEMABINDING seja eliminado de qualquer visualização indexada, as visualizações existentes tenham uniões entre tabelas novas e antigas e os procedimentos que dependem de SCOPE_IDENTITY () sejam modificados.
  4. Migrar os dados antigos para as novas tabelas em pedaços.
  5. Limpeza, consistindo em:
    • Descartar as visualizações temporárias (que eliminarão os gatilhos INSTEAD OF).
    • Renomeando as novas tabelas de volta aos nomes originais.
    • Corrigindo os procedimentos armazenados para reverter para SCOPE_IDENTITY ().
    • Largando as velhas mesas agora vazias.
    • Colocando SCHEMABINDING novamente nas visualizações indexadas e recriando índices clusterizados.
Paul White 9
fonte