![La columna de identidad de Bigint salta de 17 a 1004. ¿Por qué?](https://rvso.com/image/1595517/La%20columna%20de%20identidad%20de%20Bigint%20salta%20de%2017%20a%201004.%20%C2%BFPor%20qu%C3%A9%3F.png)
Estoy usando columnas de identidad bigint en varias tablas y noto que siguen saltando de números bajos a altos. En este caso, de 17 a 1004, pero en otras tablas hasta los 10000. Si este comportamiento continúa, estaré en la extensión de bigint dentro de unos pocos miles de registros. ¿Por qué sucede esto y cómo puedo solucionarlo?
Captura de pantalla aquí:
Respuesta1
Bigint oscila entre -9.223.372.036.854.775.808 y 9.223.372.036.854.775.807. Creo que tienes un tiempo antes de alcanzar los límites superiores; incluso si estás saltando 100.000 registros a la vez, podrías tener mil millones de saltos y aún así no alcanzar los límites superiores. Si todavía estás preocupado, reinicia tu identidad para comenzar en el rango negativo y todos estaremos muertos antes de que tengas que preocuparte por las cosas.
¿Por qué un valor de identidad tiene lagunas?
Una aplicación intenta insertar un registro en su tabla y se elimina un número del grupo. Por razones de integridad referencial, la inserción falla o el programa que realiza la llamada deshace (revierte) la inserción realizada; de cualquier manera, el valor de identidad ya no está en el grupo de candidatos. Sí, incluso si la transacción se revierte, el número se agotó y no se revierte.
Prueba por ti mismo
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#Demo') IS NOT NULL
BEGIN
DROP TABLE #Demo;
END
CREATE TABLE #Demo
(
demoid int IDENTITY(1,1) NOT NULL
, CantBeNull varchar(50) NOT NULL
);
-- add a record and look at our identity
INSERT INTO #Demo
(CantBeNull)
VALUES
('First Entry');
SELECT SCOPE_IDENTITY() AS GeneratedId;
-- GO forces the batch to commit (assuming default implicit transaction model)
GO
-- Violate RI
INSERT INTO #Demo
(CantBeNull)
VALUES
(NULL);
SELECT SCOPE_IDENTITY() AS RIViolationGeneratedId;
GO
-- add a record and look at our identity
INSERT INTO #Demo
(CantBeNull)
VALUES
('Third Entry');
SELECT SCOPE_IDENTITY() AS ThirdGeneratedId;
GO
-- Transaction consumes
BEGIN TRAN
INSERT INTO #Demo
(CantBeNull)
VALUES
('Fourth Entry');
SELECT SCOPE_IDENTITY() AS FourthGeneratedId;
ROLLBACK;
INSERT INTO #Demo
(CantBeNull)
VALUES
('Fifth Entry');
SELECT SCOPE_IDENTITY() AS FifthGeneratedId;
GO
SELECT D.* FROM #Demo AS D;
En la pestaña de resultados, verá 1, 1, 3, 4 y 5, ya que esos eran los números que se estaban utilizando, pero como revertimos 4, se verán los resultados confirmados de la tabla #Demo.
demoid CantBeNull
1 First Entry
3 Third Entry
5 Fifth Entry
no me gusta este comportamiento
Así es como funciona la propiedad de identidad: no hay forma de cambiarla. Lo mismo ocurre si cambia al objeto Secuencia (nuevo en 2012).
Si las brechas son una preocupación, buscaría identificar qué proceso las está consumiendo. Si se trata de violaciones de integridad referencial (RI), ajuste la validación antes de intentar guardar. Si la causa principal son las transacciones que se revierten, conviértalo en una confirmación de dos fases o algo así: Guardar en Stage.MyTable. Si el agotamiento de la identidad es un problema, cambie a un objeto SECUENCIA y active el ciclo. Periódicamente, sondee esta tabla para detectar transacciones confirmadas y luego insértela en dbo.MyTable desde allí. Eso debería reducir la posibilidad de que existan lagunas en su clave sustituta.
Kendra pequeñaUn bonito póster sobre el nivel de aislamiento me ayuda a recordar qué nivel de aislamiento necesitaría para comprobar lo que está realmente comprometido.