Почему значения идентификаторов моего SQL Server используются повторно? - PullRequest
1 голос
/ 19 июля 2011

У меня есть таблица, которую я использую для постановки в очередь информации перед ее отправкой в ​​другую систему (Dynamics CRM). Я записываю информацию в эту очередь, и другой сервис приходит и записывает данные в CRM.

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

Однако похоже, что SQL Server повторно использует ключи в поле идентификации. Многие идентификаторы используются только один раз, но многие используются дважды, и довольно много использовались три раза. Очевидно, что это делает поиск истории по этому идентификатору бесполезным. Я делаю что-то неправильно? Я думал, что значения идентичности должны быть уникальными, и таблица не должна использовать их повторно.

Вот свойства столбца, если это поможет.

Column Properties

Дополнительные свойства свойства первичного ключа:

enter image description here

Ответы [ 5 ]

2 голосов
/ 19 июля 2011

Значения идентичности будут уникальными в таблице в тот момент, когда это необходимо.

Механизм SQL не знает старых значений идентификаторов, если вы усекаете таблицу.

Если вы хотите, чтобы значение, которое когда-либо использовалось только один раз за время существования таблицы, вы должны учитывать GUID или создать уникальный ключ на основе identity + datetime.

2 голосов
/ 19 июля 2011

IDENTITY само по себе не означает УНИКАЛЬНО - это просто означает автоинкремент от текущего начального значения на величину приращения. Это не волнует, если уже есть такая ценность. Если вы также объявите столбец как уникальный (в таких ситуациях, как ваша, это обычно означает пометку его как первичного ключа), вы не получите ни одного из этих дубликатов, и вам следует довольно быстро выяснить, кто виноват, потому что приложение или пользователь получит ошибки нарушения ограничений.

Кроме TRUNCATE TABLE , существуют другие способы, которыми значения IDENTITY могут быть аналогичным образом нарушены:

DBCC CHECKIDENT () может использоваться, чтобы вручную установить текущее начальное значение на то, что хочет пользователь.

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

Вы можете запустить трассировку на стороне сервера, которая бы захватила эти события, чтобы выяснить, вызывается ли какое-либо из них.

Всегда полезно указать, какую версию SQL Server вы используете, или, по крайней мере, пометить вопрос минимальной версией, которую вам нужно поддерживать, поскольку решение и поведение для SQL Server 2000, например, часто могут быть довольно отличается от SQL Server 2008 R2. Просто полезный совет для будущего вопроса.

2 голосов
/ 19 июля 2011

Не знаю, как вы извлекаете личность (@@ identity и т. Д.), Но есть некоторые ограничения, связанные с областью действия, с различными подходами к этому.

Вот (ограниченная, но справедливая) статья о 3 способах получения личности: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

1 голос
/ 19 июля 2011

A TRUNCATE TABLE оператор очистит значения идентичности.Значения идентичности также можно вставлять, задав для параметра IDENTITY_INSERT значение ON.

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

Однако, как указано выше, если вы используете TRUNCATE TABLE и просто выставляете эти столбцы идентификаторов в другом месте (сохраняя ихв какой-то другой таблице, например), это ожидаемое поведение.

Если вы удаляете все строки из таблицы и хотите не допустить повторного заполнения идентификатора, вам вместо этого нужно использовать команду DELETE.См MSDN

0 голосов
/ 19 июля 2011

Если у вас есть связанные таблицы, самое первое, что я хотел бы сделать, это убедиться, что вы на самом деле настроили отношения PK / FK. Многие разработчики просто предполагают, что приложение справится с этим, и возникнут проблемы, когда что-то подобное произойдет. Вы не можете усечь таблицу, если у нее есть внешние ключи, которые предотвратят повторное использование идентификаторов.

Если существует несколько вариантов использования идентификатора в одной и той же таблице в одно и то же время, идентификатор по определению не может быть PK, если он не является частью множественного поля PK. Если у вас действительно есть этот случай, я советую вам лучше проконсультироваться с Microsoft, так как произошел какой-то совершенно неоправданный случай. Если люди копируют старые и используют их повторно, это совсем другая история.

Очевидно, что какой-то процесс или человек сбрасывали значения в прошлом по неизвестной причине. Вы можете использовать триггеры DDL для записи, если кто-то изменяет PK, удаляет ограничения внешнего ключа и т. Д. По крайней мере, таким образом вы можете узнать, какой процесс это делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...