Повторно использовать автоматически сгенерированный идентификатор в Microsoft SQL Server 2008 R2 - PullRequest
1 голос
/ 20 октября 2011

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

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

Это прекрасно работает, но меня беспокоит тот факт, что где-то во времени мы достигнем предела нашего автоматически сгенерированного целого числа RowId.

Есть ли хороший способ повторно использовать старые RowId, которые были удалены? Или есть другой способ убедиться, что у нас никогда не будет проблем?

Спасибо, что подумали со мной!

Ответы [ 7 ]

0 голосов
/ 21 октября 2011

С типом INT, начиная с 1, вы получаете более 2 миллиардов возможных строк - этого должно быть более чем достаточно для подавляющего большинства случаев. С BIGINT вы получите примерно 922 квадриллиона (922 с 15 нулями - 922 000 миллиардов) - вам достаточно ??

Если вы используете INT IDENTITY, начинающийся с 1, и вставляете строку каждую секунду, вам нужно 66,5 лет , прежде чем вы достигнете предела в 2 миллиарда ....

Если вы используете BIGINT IDENTITY, начинающийся с 1, и вставляете тысячу строк каждую секунду , вам нужно ошеломить 292 миллиона лет , прежде чем вы достигнете 922 квадриллиона предел ....

Подробнее об этом (со всеми имеющимися опциями) читайте в Электронной документации MSDN .

0 голосов
/ 21 февраля 2012

Это должно дать вам список ваших таблиц и показать, насколько вы близки к заполнению столбцов идентификации каждого (это должно работать в SQL 2005+).Альтернативные версии (включая версию SQL 2000) доступны здесь .

SELECT  QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' +  QUOTENAME(t.name) AS TableName, 
    c.name AS ColumnName,
    CASE c.system_type_id
        WHEN 127 THEN 'bigint'
        WHEN 56 THEN 'int'
        WHEN 52 THEN 'smallint'
        WHEN 48 THEN 'tinyint'
    END AS 'DataType',
    IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) AS CurrentIdentityValue,
    CASE c.system_type_id
        WHEN 127 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 9223372036854775807
        WHEN 56 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 2147483647
        WHEN 52 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 32767
        WHEN 48 THEN (IDENT_CURRENT(SCHEMA_NAME(t.schema_id)  + '.' + t.name) * 100.) / 255
    END AS 'PercentageUsed' 
FROM    sys.columns AS c 
    INNER JOIN
    sys.tables AS t 
    ON t.[object_id] = c.[object_id]
WHERE   c.is_identity = 1
ORDER BY PercentageUsed DESC
0 голосов
/ 20 октября 2011

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

0 голосов
/ 20 октября 2011

Вы не исчерпаете сгенерированные значения идентификатора, но вы можете использовать команду replace into .Вы можете найти хороший справочник здесь .

0 голосов
/ 20 октября 2011

Oracle NUMBER может содержать до 38 десятичных цифр. Если вы генерируете новый идентификатор каждую наносекунду , вы потратите их все через 3.16887646 * 10^21 лет.

Нашей вселенной около 14 * 10^9 лет. Поверьте мне, вы не будете тратить идентификаторы в ближайшее время.

(Другие базы данных имеют аналогичные «ограничения».)

0 голосов
/ 20 октября 2011

Ваше где-то во времени, вероятно, через сотни лет в будущем. Если вы не пишете программное обеспечение для , которое долго, вам не о чем беспокоиться.

count_of_users * count_of_sessions * count_of_days < (much less than) MAX(int)

Например:

1000 * 100 * 1000 (~3 years) = 100 million = an order of magnitude less than 1 billion

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

0 голосов
/ 20 октября 2011

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

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

Например: если ваши текущие идентификаторы 12331, 12332, 12333, скрипт изменит эти идентификаторы на 1,2,3 и сбросит поле идентификатора до 4. Таким образом, следующий введенный идентификатор будет 4.

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