Почему существуют пробелы в значениях столбца IDENTITY?

У меня проблема.

My ID Primary (IDENTITY) настроен на автоматическое увеличение (тип: int). Но, когда я вставляю новую строку, этот новый идентификатор не является последовательным. Что происходит? Любые решения?

Редакция:

[...]
[id]int] IDENTITY(1,1) NOT NULL,
[...]
CONTRAINT [PK_Medida] PRIMARY KEY CLUSTERED
(
[id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Ответ 1

Не ожидайте, что идентификаторы будут последовательными. Существует много сценариев, которые могут оставлять пробелы. Рассмотрим тождество как абстрактное число и не придавайте ему никакого делового значения.

Ответ 2

Свойство идентификации в столбце не гарантирует следующее:

Уникальность значения. Единственность должна быть принудительно применена с использованием ограничения PRIMARY KEY или UNIQUE или UNIQUE.

Последовательные значения внутри транзакции. Транзакция, вставляющая несколько строк, не гарантирует получение последовательных значений для строк, поскольку в таблице могут появляться другие параллельные вставки. Если значения должны быть последовательными, то транзакция должна использовать исключительную блокировку в таблице или использовать уровень изоляции SERIALIZABLE.

Последовательные значения после перезагрузки сервера или других сбоев. Сервер SQL Server может кэшировать значения идентификаторов по соображениям производительности, а некоторые из назначенных значений могут быть потеряны во время сбоя базы данных или перезагрузки сервера. Это может привести к разрыву в значении идентификации при вставке. Если промежутки неприемлемы, приложение должно использовать генератор последовательности с опцией NOCACHE или использовать собственный механизм для генерации значений ключа.

Повторное использование значений. Для заданного свойства идентификации с конкретным семенем/приращением значения идентификатора не будут повторно использоваться движком. Если какой-либо конкретный оператор вставки терпит неудачу или если оператор вставки откат, то потребляемые значения идентичности теряются и не будут генерироваться снова. Это может привести к разрыву, когда генерируются последующие идентификационные значения.

Кроме того,

Если столбец идентификатора существует для таблицы с частыми удалениями, между значениями идентичности могут возникать пробелы. Если это вызывает беспокойство, не используйте свойство IDENTITY. Тем не менее, , чтобы убедиться, что пробелы не были созданы или заполнить существующий пробел, оцените существующие значения идентификатора перед явным вводом его с помощью SET IDENTITY_INSERT ON.

Кроме того, проверьте свойства столбца Identity и проверьте значение Identity Increment. Его значение должно быть 1.

enter image description here

Ответ 3

Пробелы возникают, когда:

  • записи удаляются.
  • Ошибка при попытке вставить новая запись (например, ошибка с ненулевым ограничением). Значение идентичности равно беспомощно пропущен.
  • кто-то вставил/обновил его с помощью явного значение (например, параметр identity_insert).
  • инкрементное значение больше 1.

Ответ 4

Вы можете избежать этой ошибки либо , оценив ожидаемую ошибку, прежде чем выполнять инструкцию increment, или , используя транзакцию, чтобы оператор никогда не выполнялся и откатывался, если есть любая ошибка. Надеюсь, что это поможет.

Ответ 5

Автоматический идентификатор удаляемой строки больше не используется новой вставленной строкой. Я не могу дать вам решение, но это поведение.

Wouter

Ответ 6

Если столбец задан как первичный, и если значение auto increment равно true, это произойдет, потому что вы могли бы удалить несколько строк между ними. Если вы хотите, чтобы он был последовательным, вы не должны использовать автоматическое приращение.

Ответ 7

У меня есть таблица с несколькими ограничениями, которые, как я ожидаю, вызовут массивное число операторов вставки. Это вызывало огромные пробелы в моем индексе, который обрабатывается Identity (1,1).

Решением, которое я разработал, было создание промежуточной таблицы без столбца ID, но все остальные столбцы таблицы. Затем я указываю триггер для запуска в таблице промежуточной таблицы, который после успешной вставки записывается в фактическую таблицу с индексом. В этом случае резервирование идентификатора выполняется в другое время и позволяет группировать все значения для идентификатора.

Я знаю, что это кажется немного неэффективным, но для меня это очень хорошо работало.