Максимум для автоинкрементного int первичного ключа в SqlServer - PullRequest
8 голосов
/ 19 февраля 2010

Есть ли максимум? Начнет ли SQL Server генерировать исключения SqlException при достижении максимума? Как вы это решаете? (Архивирование?)

Из ресурсов SQL Server видно, что максимум составляет 2 147 483 647. Я далек от этого, но мне было просто любопытно.

Ответы [ 5 ]

9 голосов
/ 19 февраля 2010

Максимальное значение для int действительно составляет 2 147 483 647.

Если вы попытаетесь превысить максимальный размер, вы получите эту ошибку:

Msg 8115, Level 16, State 1, Line 2 
Arithmetic overflow error converting IDENTITY to data type int. 
Arithmetic overflow occurred.

Если она невеликадостаточно, используйте bigint (9,223,372,036,854,775,807)

6 голосов
/ 19 февраля 2010

вы можете увидеть ошибку, используя этот небольшой пример

use tempdb;

if OBJECT_ID('dbo.test', 'U') is not null drop table dbo.test

create table test
( id int identity not null,
  dummy int not null )
go

SET IDENTITY_INSERT dbo.test ON

insert into test(id, dummy) values(2147483647, 1)

SET IDENTITY_INSERT dbo.test OFF

insert into test(dummy) values(1)

ошибка:

(1 row(s) affected)
Msg 8115, Level 16, State 1, Line 8
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.
5 голосов
/ 19 февраля 2010

Максимум определяется типом данных, а не модификатором IDENTITY. Для столбца INT вы уже вычислили максимум. Если вам нужен тип данных с большим диапазоном, BIGINT является очевидным выбором, и его вполне можно пометить IDENTITY.

  • TINYINT: от 0 до 255
  • SMALLINT: от -32768 до 32767
  • INT: от -2147483648 до 2147483647
  • BIGINT: от -9223372036854775808 до 9223372036854775807

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

Хотя, безусловно, можно было бы заархивировать строки в какое-то другое хранилище данных и начать повторное использование идентификаторов (DBCC CHECKIDENT (jobs, RESEED, 0) сбросит счетчик), SQL Server не предлагает готовые решения. Вы должны будете реализовать логику для этого самостоятельно, и, кроме того, вам нужно будет подумать, какие проблемы могут возникнуть при повторном использовании идентификаторов в вашем приложении. Например, для веб-приложения старые URL-адреса внезапно будут указывать на новые документы или возвращать 404 ошибки?

1 голос
/ 24 ноября 2016

Если вы настаиваете на использовании, например, типа данных INT для вашего первичного ключа, и вы достигли конца емкости этого типа данных, вы должны сделать следующее:

  1. Удалить старые данные. Например, удалите из TABLENAME, где pk <1000000 Конечно, если ваши данные важны, перед удалением вы должны переместить их в архивную таблицу. Таким образом, диапазон от 1 до 1000000 станет свободным, и вы можете использовать его. Предположим, что ваш первичный ключ вставлен динамически. Таким образом, вы должны СБРОСИТЬ свой первичный ключ. </li>
  2. Запустите этот запрос к вашей таблице:

    DBCC CHECKIDENT (TableName, RESEED, 0)

Таким образом, ваша запись будет вставлена ​​по первичному ключу от 1.

Но учтите, что если ваш pk достигнет 1000001, вы столкнетесь с ошибкой, поскольку этот первичный ключ существует в вашей таблице. Другими словами, вы всегда должны учитывать свой первичный ключ.

1 голос
/ 07 марта 2014

Обратите внимание: если вы усекаете таблицу, вы по существу сбрасываете идентификатор. Может быть полезно в тех случаях, когда вы не можете удалить и воссоздать таблицу.

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