在 Microsoft SQL Server 2008 R2 中重新使用自动生成的 ID

发布于 2024-12-11 05:34:31 字数 300 浏览 0 评论 0原文

我有一个程序,客户可以触发计算,用计算出的数据填充表格,以便在会话中进一步使用。但是,我们必须在他们每次登录时删除所有记录,然后使用 insert into .. select 再次填充表格。

我知道最好更新行,但是很多事情在一段时间后可能会改变/变得过时,所以我们决定删除并重新插入。

这工作正常,但我担心这样一个事实:在某个时间我们会达到自动生成的 RowId 整数的限制。

有没有一种好方法可以重用已删除的旧 RowId?或者有其他方法可以确保我们永远不会陷入麻烦吗?

谢谢你和我一起思考!

I have a procedure where customers trigger a calculation that fills a table with calculated data for further use in their session. But, we have to do this every time they login by deleting all their records and then filling the table again by using insert into .. select.

I know it's better to update rows, but there are way to many things that can change / become obsolete after a while, so we decided to delete and reinsert.

This works fine, but I'm worried about the fact that somewhere in time we will hit the limit of our autogenerated RowId integer.

Is there a nice way to reuse the old RowId's that have been deleted? Or is there another approach to make sure we never get into trouble?

Thanks for thinking with me!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

逆光下的微笑 2024-12-18 05:34:31

正如其他人指出的那样,您不太可能很快用完 ID 值。不过我会问另一个问题。您真的需要这个 ID 吗?如果计算特定于用户和会话,那么在我看来,您已经有一种方法来识别行。只需将用户 ID 和会话 ID 放入表中,如果需要,还可以添加日期/时间列,并且根本不需要自动生成的 ID。

As others have pointed out, you're unlikely to run out of ID values any time soon. I'd ask another question though. Do you really need this ID? If the calculations are specific to a user and session then it seems to me that you already have a way to identify rows. Just put the user id and session id in the table, maybe with a date/time column as well if needed and you don't need an autogenerated ID at all.

肥爪爪 2024-12-18 05:34:31

你所处的时间点可能是数百年后的未来。除非您编写的软件可以持续那么长时间,否则您不必担心。

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

收集一些指标并进行这样的计算,您可能会发现您的上限可能是几代人之后的。

Your somewhere-in-time is likely hundreds of years in the future. Unless you're writing software to last that long you shouldn't have to worry.

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

For example:

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

Collect some metrics and make a calculation like this and you will likely find that your upper bound is likely generations off.

夜血缘 2024-12-18 05:34:31

如果您指的是身份字段,那么在每个数据库中都有一种方法可以将数字重置为您想要的任何值。只需谷歌搜索您的数据库并重置身份即可获得正确的语法。

最好的方法是编写一个小脚本,您有时可以运行该脚本来更改所有以 1 开头的现有 ID,然后将标识设置为最大值 + 1。

例如:如果您当前的 ID 是 12331、12332、12333
该票据会将这些 id 更改为 1,2,3 并将身份字段重置为 4。
所以接下来输入的 id 将为 4。

If you mean the identity field, in every database there is a way to reset the number to whatever you want. Just google your db and reset identity to get the correct syntax.

Best way to do that is to write a little script that you can run sometimes to change all the existing IDs starting with 1 and then set identity to the max + 1.

For example: if your current ids are 12331, 12332, 12333
the scrip would change these ids to 1,2,3 and reset the identity field to 4.
So next entered id would be 4.

牵你手 2024-12-18 05:34:31

Oracle NUMBER 最多可容纳 38 位十进制数字。如果您每纳秒生成一个新 ID,那么您将在 3.16887646 * 10^21 年。

我们的宇宙大约有 14 * 10^9 岁。相信我,您很快就不会“花费”ID。

(其他数据库也有类似的“限制”。)

The Oracle NUMBER can hold up to 38 decimal digits. If you generated a new ID every nanosecond, you'd spend them all after 3.16887646 * 10^21 years.

Our universe is about 14 * 10^9 years old. Trust me, you won't "spend" IDs any time soon.

(Other databases have similar "limitations".)

断念 2024-12-18 05:34:31

您不会用完生成的 ID 值,但可以使用替换为命令。您可以在此处找到一个很好的参考。

You won't run out of generated ID values, but you can use the replace into command. You can find a good reference here.

枯寂 2024-12-18 05:34:31

对于 INT 类型,从 1 开始,您将获得超过 20 亿 可能的行 - 这对于绝大多数情况来说应该足够了。使用BIGINT,您大约会得到922万亿(922有15个零 - 922'000十亿) - 对您来说足够了吗?

如果您使用从 1 开始的 INT IDENTITY,并且每秒插入一行,则需要 66.5 才能达到 20 亿的限制......

如果您使用从 1 开始的 BIGINT IDENTITY,并且每秒插入一千行,您需要令人难以置信的2.92 亿年才能到达922千万级限制....

MSDN 在线图书

With a type INT, starting at 1, you get over 2 billion possible rows - that should be more than sufficient for the vast majority of cases. With BIGINT, you get roughly 922 quadrillion (922 with 15 zeros - 922'000 billions) - enough for you??

If you use an INT IDENTITY starting at 1, and you insert a row every second, you need 66.5 years before you hit the 2 billion limit ....

If you use a BIGINT IDENTITY starting at 1, and you insert one thousand rows every second, you need a mind-boggling 292 million years before you hit the 922 quadrillion limit ....

Read more about it (with all the options there are) in the MSDN Books Online.

早乙女 2024-12-18 05:34:31

这应该为您提供表的列表,并显示您距离填充每个表的标识列有多近(这应该适用于 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

This should give you a list of your tables, and show you how close you are to filling the identity columns of each (this should work SQL 2005+). Alternative versions (inc. a SQL 2000 version) are available here.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文