Столбец идентификатора Bigint подскакивает с 17 до 1004. Почему?

Столбец идентификатора Bigint подскакивает с 17 до 1004. Почему?

Я использую столбцы bigint identity в нескольких таблицах и замечаю, что они продолжают прыгать от низких чисел к высоким. В этом случае от 17 до 1004, но в других таблицах до 10000. Если это поведение продолжится, я буду в пределах bigint в пределах нескольких тысяч записей! Почему это происходит и как это исправить?

Скриншот здесь:

решение1

Bigint варьируется от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807. Я думаю, у вас есть время, прежде чем вы достигнете верхних границ - даже если вы прыгаете на 100 тыс. записей за раз, вы можете сделать миллиард прыжков и все равно не достичь верхних границ. Если вы все еще обеспокоены, пересейте свою личность, чтобы начать с отрицательного диапазона, и мы все умрем прежде, чем вам придется беспокоиться о вещах.

Почему в значении идентичности есть пробелы?

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

Проверьте сами

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;

На вкладке результатов вы увидите 1, 1, 3, 4 и 5, поскольку именно эти числа использовались, но поскольку мы откатываемся на 4, зафиксированные результаты таблицы #Demo будут выглядеть

demoid  CantBeNull
1       First Entry
3       Third Entry
5       Fifth Entry

Мне не нравится такое поведение.

Вот как работает свойство identity — нет способа его изменить. То же самое справедливо, если вы переключитесь на объект Sequence (новый в 2012 году).

Если пробелы вызывают беспокойство, я бы посмотрел на определение того, какой процесс их потребляет. Если это нарушения ссылочной целостности (RI), ужесточите проверку перед попыткой сохранения. Если первопричина в откате транзакций, то сделайте это двухфазным подтверждением или чем-то вроде этого — сохраните в Stage.MyTable. Если проблема в исчерпании идентификаторов, переключитесь на объект SEQUENCE и включите цикличность. Периодически опрашивайте эту таблицу на предмет подтвержденных транзакций, а затем вставляйте в dbo.MyTable оттуда. Это должно уменьшить вероятность существования пробелов в вашем суррогатном ключе.

Кендра Литтлпрекрасный плакат с уровнем изоляции помогает мне помнить, какой уровень изоляции мне нужен для проверки того, что действительно, действительно выполнено.

введите описание изображения здесь

Связанный контент