当表中的字段接近最大有符号或无符号32位整数时该怎么办?


14

在任何以唯一的自动增量字段形式保存用户记录的给定数据库中(为方便起见,示例中为用户间消息)...当时间到了并且接近最大有符号数或无符号数时该怎么办当前数据类型?(一个32位INT)?我猜数据库服务器在尝试将(2∧32)-1数字分配给下一个条目时将溢出,因此,如何避免这种情况发生(出于问题的原因,不更改数据类型)和继续添加记录?你会怎么做?

为什么我要使用INT,而不要使用VARCHARS?

自问了这个假设问题已经好几天了,我想知道专业人员会做什么。

Answers:


12

通常,您将使用整数而不是varchar,因为它们占用较少的空间,并且具有很好理解的排序模式可以快速建立索引等。整数是CPU的自然数据类型,因此性能通常是最佳的。通常,整数是4个字节,相当于(非Unicode)varchar中的4个字符。

如果您担心INT类型的空间不足,请尝试使用BIGINT,它会为您提供8字节的数字。这方面的限制是非常巨大的,并且在达到该记录限制之前,您可能会用完磁盘空间:-) BIGINT的性能也将非常好,尤其是现在许多服务器也是64位的。

关于在INT中用尽时会发生什么的问题的第一部分的答案并不简单,尤其是正如您所说的那样,没有将数据类型更改为BIGINT。基本上没有什么可以做的,并且您可能能够做的事情在很大程度上受到数据库中数据性质的限制。哪些记录是该数据的外键?您还需要该表和相关记录中的所有数据吗?假设您可以存档许多初始数据(及其相关数据),那么我唯一建议的就是将数据移出表(假设前1条到X百万条记录),然后将身份种子重置为1。尽管我不推荐这样做,但有各种各样的原因-例如,我看到很多代码都在执行诸如检查id​​字段的最大值,看看刚刚添加了什么,那是行不通的(不应该这样做)。同样,人们认为记录N是在N + 1之前创建的。我认为没有简单的答案。

最后,我不了解MySQL,但是如果达到极限,SQL Server会给出溢出错误。


1
我很高兴得到如此详尽的答复。感谢您对VARCHAR,INT和BIGINT交易的解释。由于问题是假设性的,我想知道如果也达到BIGINT限制会发生什么。我看到一篇关于使用INT并达到极限的facebook的帖子提出了这个问题,我认为这是完全可能的。归档将起作用,或者使用条件语句创建第二个表(如您所说,这也将需要更新脚本,这将非常复杂)。总体而言,很好的答案。我感谢您所花费的时间。
AeroCross 2011年

9

一个被忽视的观点是,许多人从1开始自动编号或身份,因此立即失去了可能范围的一半(对于带符号)

您只需将数字重新定义为从-1开始,在这种情况下以-1递增。

可以说,如果您曾经希望填写身份列,那么您应该在其中进行设计并在开始时使用更广泛的数据类型。

请参阅以下最新问题:SQL Server 2008:如果身份超过最大整数值会发生什么?


逻辑上我会使用更广泛的数据类型(对于一个表,该数据量将是多少),但是由于这是一个假设的问题,因此我需要一些见识。如果它是签名的,那可能行得通(但我会有点奇怪,因为主键带有负数,恕我直言),我认为这很聪明。这将使DBA有时间来存档肯定的数据并重新开始。如果未签名,那么...问题。
AeroCross 2011年

另一种方法是使用从-1开始的-1增量,从(-2147483648)开始并以1增量。但是,是的,在经过INT_MAX之后,您已经掌握了很多技巧,需要重新查看设计,并删除替换它的旧索引与一个新的更大的。如果您通过未签名的BIGINT,那么我想加入您的团队;)
jcolebrand

PostgreSQL使用序列生成ID号。CREATE SEQUENCE语句使您可以指定CYCLE,如果达到最大值,它将循环显示。(或者,最小值,如果您朝另一个方向前进。)CYCLE选项现在在SQL标准中。(至少从2003年开始。)
Mike Sherrill'Cat Recall'

4

溢出BIGINT?哈哈。首先弄清楚如何实现永生。INT UNSIGNED(40亿)很难达到。一年内每秒100 INSERT将接近INT溢出。BIGINT将花费数十亿年。

要修复:ALTER TABLE foo MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; 但这将花费数小时,因为它将复制整个表(有近40亿行,对吗?)并重建所有二级索引。未雨绸缪。

通常,当您尝试为字段存储太大的数字时(例如,在TINYINT UNSIGNED中为999),它将无提示地将其限制为该字段的最大值(在这种情况下为255)。可能会有“警告”,但是大多数人都不会去检查警告。如果它是UNIQUE字段,或者有FOREIGN KEYS,则可能会出现更严重的错误。

CHAR或VARCHAR被静默截断为可用空间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.