Спецификация идентичности - PullRequest
0 голосов
/ 15 мая 2019

У меня проблема со спецификацией идентификации, когда я создаю таблицу в SQL Server 2016.

  • В столбце Id для Identity Increment и Identity Seed равны 1.
  • Далее Iдобавить новую запись в новую таблицу.
  • В столбце Id отображается значение 2.Зачем?Почему бы не 1 значение?
  • Далее отбросьте первую запись и добавьте новую.В столбце Id отображаются 3 значения.Зачем?Почему бы не 1 значение.
  • Далее я использую команду «обновить nametable set id = 1» и получить ответ не может обновить идентификатор столбца идентификации.Почему?

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Это, вероятно, легче объяснить с помощью некоторого кода:

CREATE TABLE YourTable (ID int IDENTITY(1,1),
                        SomeCol varchar(5));

INSERT INTO dbo.YourTable (SomeCol)
VALUES('abc'); --Will get ID 1

INSERT INTO dbo.YourTable (SomeCol)
VALUES('def'),('ghi'); --Will get 2 and 3.

SELECT *
FROM dbo.YourTable;

DELETE FROM dbo.YourTable;

INSERT INTO dbo.YourTable (SomeCol)
VALUES('abc'); --Will get ID 4, because 1-3 have been used. Deleting doesn't let you reuse values.

SELECT *
FROM dbo.YourTable;

DELETE FROM dbo.YourTable;

DBCC CHECKIDENT ('dbo.YourTable', RESEED, 1);

INSERT INTO dbo.YourTable (SomeCol)
VALUES('abc'); --Will get ID 2, as you seeded back to 1; so the NEXT ID is used.

SELECT *
FROM dbo.YourTable; 

TRUNCATE TABLE dbo.YourTable;

INSERT INTO dbo.YourTable (SomeCol)
VALUES('abc'); --Will get ID 4, because 1-3 have been used.

SELECT *
FROM dbo.YourTable; --Will get ID 1, as the column was reseed with the TRUNCATE


DROP TABLE dbo.YourTable;

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

Поскольку в таблице есть существующие строки, следующая вставленная строка будет использовать 11 в качестве значения - новое текущее значение идентификатора, определенное для столбца плюс 1 (значение приращения столбца).

Единственный способ определить таблицу, не имеющую существующих строк, - это TRUNCATE it, что я и сделаю позже в приведенном выше пакете (и почему 1 используется повторно).

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

Если важно иметь последовательные значения, то вам нужно использовать SEQUENCE, а не свойство IDENTITY. Последний не гарантирует уникальности или последовательных значений сам по себе (поскольку они могут быть пропущены из-за удалений, неудачных вставок, неожиданного выключения и т. Д.), Но он гарантирует, что не будет повторно использовать значения, если они были (без RESEED): IDENTITY (Transact-SQL) - Примечания . SEQUENCE может использоваться, чтобы гарантировать, что значения действительно последовательны (кроме как из-за DELETE).

1 голос
/ 15 мая 2019

Добро пожаловать на форум:)

Если вы создали таблицу, используя

Id INT IDENTITY(1,1)

Тогда первая вставленная запись будет иметь Id = 1, однако в случае сбоя оператора вставки или отката транзакции использованный идентификатор помечается как использованный (или потерянный), а следующий оператор вставки будет исходить из Id = 2.

Посмотрите документацию Microsoft по этой теме: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property?view=sql-server-2017

0 голосов
/ 15 мая 2019

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

Пробелы в значениях идентификатора также НЕ заполняются, когда более старые записи удаляются из таблицы и новые записи вставляются в таблицу.

Этокак работает личность.Это простой и безопасный механизм.

Если вы (иногда!) Хотите сбросить значение идентификатора, вы можете взглянуть на DBCC CHECKIDENT.Лично я склонен использовать это так:

DBCC CHECKIDENT (MyTable, RESEED, 0) WITH NO_INFOMSGS;
DBCC CHECKIDENT (MyTable, RESEED) WITH NO_INFOMSGS;

(я выполняю обе строки в указанном порядке.)

Однако я бы советовал не использовать эту практику в производственных средах.

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