Pergunta

Nosso banco de dados é o SQL Server 2008 R2.Temos algumas tabelas que possuem algumas colunas varchar(500) que desejo mudar para datetime2 ou bigint.Posso garantir que todos os dados nas colunas a serem trocadas são válidos para o tipo adequado.As alterações nas colunas afetam os índices, mas não as chaves.

Ao discutir com colegas, chegamos a duas maneiras de abordar o problema.Ambos seriam feitos por meio de scripts T-Sql.

  1. Crie uma tabela temporária via select into, elimine a tabela antiga e recrie a tabela com os tipos de dados apropriados.Recrie os índices.
  2. Altere os tipos de tabela/dados atuais viaALTER TABLE x ALTER COLUMN Y datetime2 e, em seguida, reconstrua ou recrie os índices.

Como estou confiante de que os dados serão convertidos de forma limpa, estou inclinado para o número 2.Meu colega e um amigo DBA preferem o número 1, mas meu colega não se lembra por que o treinaram dessa maneira.O amigo DBA está de férias, então não perguntei por quê.

Alguém pode fornecer informações sobre qual opção considera melhor e por quê?Em última análise, a decisão é minha e estou me perguntando por que o número 1 seria preferido ao número 2?

Foi útil?

Solução

Recentemente fiz isso em minha organização, onde queríamos lidar com uma tabela com mais de um bilhão de linhas.

Todo o crédito pela ideia vai para Aaron Bertrand e vem de sua postagem no blog Tiros de truque:Esquema Switch-A-Roo

Teste o processo abaixo em uma pequena mesa e fique confortável antes de fazê-lo no PROD.

  1. crie 2 esquemas fake e shadow com autorização dbo.
  2. Crie uma tabela com as colunas e tipos de dados que você deseja shadow esquema, por exemplo create table shadow.Correct_Table ...
  3. Insira os dados e crie todos os índices que a tabela original possui no shadow tabela de esquema.
  4. Desta forma você tem cópias idênticas da tabela com dados e índices, mas eles estão em esquemas diferentes (separados logicamente).
  5. Uma vez feito isso, atualize as estatísticas na mesa com shadow esquema.
  6. Troque os esquemas (esta é uma operação de metadados e é extremamente rápida)

    --- ALTER SCHEMA TargetSchema TRANSFER SourceSchema.TableName; 
    
    BEGIN TRANSACTION;
    
      ALTER SCHEMA fake TRANSFER     dbo.original_table;
      ALTER SCHEMA dbo  TRANSFER  shadow.Correct_Table;
    
    COMMIT TRANSACTION;
    
    ALTER SCHEMA shadow TRANSFER fake.Lookup;
    
  7. Faça uma verificação final para ver se tudo correu conforme planejado.Você deveria fazer um select count(1) from dbo.Correct_table

  8. Assim que a etapa 7 for confirmada e você estiver satisfeito, solte o shadow.table, shadow esquema e fake esquema como limpeza.

Outras dicas

Aqui está a maneira como eu vejo isso.

Prós para #1

  • Como você está usando uma tabela separada, sua tabela de produção permanece em uso até você terminar.Não há bloqueios (além daqueles necessários para ler os dados).
  • Isso também corresponde ao que @AaronBertrand disse:você pode fazer isso aos poucos, testar etc.
  • Você pode alterar a ordem das colunas conforme necessário

Prós para #2

  • É uma operação de tudo ou nada.Não há chance de você perder dados que foram inseridos/modificados na tabela original enquanto você não estava olhando.
  • Quaisquer permissões atribuídas especificamente ao objeto serão mantidas.Se você usar o nº 1, certifique-se de criar o script e aplicá-lo.

Dito isso, normalmente usarei o número 2 para tabelas pequenas ou quando houver uma interrupção (sempre faça um backup antes) e o número 1 se não conseguir uma interrupção tão grande ou tiver que reorganizar a ordem das colunas etc.Se for fazer o número 1, normalmente gerarei o script por meio da GUI e o revisarei cuidadosamente antes de executá-lo.

Tenha cuidado com a opção soltar e recriar:isso pode deixar sys.depends em um estado estranho e causar problemas para planos em cache onde a ordem ou o tipo de colunas está mudando.

Você também precisará tomar medidas para manter quaisquer permissões em nível de objeto, pois elas serão perdidas no DROP e não recriado automaticamente com o subsequente CREATE.

ALTER TABLE é a opção mais limpa, IMO, mas certifique-se de testar completamente antes de fazê-lo na produção, tanto para ter certeza de que tudo está bem depois quanto para saber quanto tempo as operações levarão (em uma tabela com muitas linhas, isso pode levar um bom tempo ).

Meu colega acabou encontrando um artigo sobre o que ele estava se referindo: http://www.nigelrivett.net/SQLAdmin/AlterTableProblems.html.Depois de ler isso e perceber que nosso relatório de final de ano estava chegando, decidimos não fazer alterações nos tipos de colunas e revisitaremos isso nos próximos meses.Acho que depois de ler o artigo, posso simplesmente optar pelo método Drop/Create.

Obrigado a todos por seus comentários sobre isso.Muitas abordagens interessantes a serem consideradas quando decidimos seguir em frente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a dba.stackexchange
scroll top