Cambiar la columna de identidad de INT a BIGINT

9

Tengo una tabla con una columna de identidad que también es una clave principal. Actualmente, tiene 50 millones de filas, con el valor más alto de la columna de identidad en 148,921,803. La tabla tiene muchos DELETEsy se INSERTSejecuta en ella, de ahí el alto valor.

Queremos cambiar el tipo de datos de INTa BIGINTpara prepararnos para agregar más filas. Tenga en cuenta que no hay referencias a la columna PK.

¿Cuál es la mejor manera de hacer esto, con un tiempo de inactividad mínimo? Tengo dos opciones

  1. Suelta el PK y altera la columna; o
  2. El método copy-drop-rename, como se describe aquí :
Felix Pamittan
fuente

Respuestas:

7

Como hay una clave principal definida en la columna de identidad, no podrá modificarla directamente.

Se pueden utilizar los enfoques que ha mencionado en su pregunta y el tiempo de inactividad depende del rendimiento de su servidor y del número de filas que residen en esa tabla.

  1. Suelta el PK y altera la columna; o

Primero suelte la PK

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

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

Alterar columna

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

Agregar clave primaria

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

Este enfoque generalmente no lleva mucho tiempo. En mi entorno, se necesitan segundos de yegua en tablas grandes que tienen más de 5 millones de filas.

  1. El método copy-drop-rename, como se describe

Puedes usar este enfoque también. Sin embargo, para este enfoque necesita más tiempo de inactividad que el Enfoque uno, ya que debe sincronizar las tablas.

Shashank Tiwari
fuente
6

Aaron Bertrand tiene una serie de 4 partes sobre este tema, comenzando con:

Minimizar el impacto de ampliar una columna IDENTIDAD - parte 1

Si absolutamente necesita mudarse bigint, debe minimizar el tiempo de inactividad y tener suficiente tiempo para planificar, el enfoque que documenta en la parte 4 es:

En un nivel muy alto, el enfoque es crear un conjunto de tablas de sombra, donde todas las inserciones se dirigen a una nueva copia de la tabla (con el tipo de datos más grande), y la existencia de los dos conjuntos de tablas es tan transparente como sea posible para la aplicación y sus usuarios.

Con más detalle, Aaron dice:

  1. Cree instantáneas de las tablas, con los tipos de datos correctos.
  2. Modifique los procedimientos almacenados (o el código ad hoc) para usar bigint para los parámetros. (Esto puede requerir modificaciones más allá de la lista de parámetros, como variables locales, tablas temporales, etc., pero este no es el caso aquí).
  3. Cambie el nombre de las tablas antiguas y cree vistas con esos nombres que unen las tablas antiguas y nuevas.
    • Esas vistas tendrán en lugar de disparadores para dirigir correctamente las operaciones DML a la (s) tabla (s) apropiada (s), de modo que los datos puedan modificarse durante la migración.
    • Esto también requiere que SCHEMABINDING se elimine de cualquier vista indizada, que las vistas existentes tengan uniones entre tablas nuevas y antiguas y que los procedimientos que dependen de SCOPE_IDENTITY () se modifiquen.
  4. Migre los datos antiguos a las nuevas tablas en fragmentos.
  5. Limpieza, que consiste en:
    • Descarte de las vistas temporales (que dejarán caer los desencadenantes INSTEAD OF)
    • Cambiar el nombre de las nuevas tablas a los nombres originales.
    • Arreglando los procedimientos almacenados para volver a SCOPE_IDENTITY ().
    • Dejar caer las viejas mesas ahora vacías.
    • Poner SCHEMABINDING nuevamente en vistas indexadas y volver a crear índices agrupados.
Paul White 9
fuente