代码之家  ›  专栏  ›  技术社区  ›  Jonas

当整数列上的自动增量达到数据库中的最大值时会发生什么?

  •  60
  • Jonas  · 技术社区  · 15 年前

    我正在实现一个数据库应用程序,我将同时使用JavaDB和MySQL作为数据库。我的表中有一个id列,它的类型为integer,我使用databases auto_increment-function作为值。

    但当我得到超过20亿(或40亿)个帖子和整数还不够时会发生什么呢?整数是溢出并继续,还是抛出了我可以处理的异常?

    是的,我可以更改为long-as数据类型,但是在需要时如何检查?如果我将long as数据类型用于id列,那么获取最后一个插入的函数就有问题。

    6 回复  |  直到 7 年前
        1
  •  45
  •   outis    15 年前

    吉姆·马丁的评论来自 §3.6.9. "Using AUTO_INCREMENT" MySQL文档:

    为了避免出现任何问题,自动增量字段/不换行/。一旦达到字段大小的限制,插入将生成错误。(根据杰里米·科尔)

    使用MySQL5.1.45进行快速测试会导致以下错误:

    错误1467(hy000):无法从存储引擎读取自动增量值

    您可以在插入时测试该错误并采取适当的操作。

        2
  •  45
  •   Justin    14 年前

    为了安抚神经,考虑一下:

    假设您有一个数据库,每当用户在您的网站上执行某种事务时,它都会插入一个新值。

    如果使用64位整数作为ID,则这是溢出的条件: 世界人口有60亿,如果地球上的每个人每天和每年(没有休息)每秒执行一次交易,你的身份证就需要80多年才能完成。

    也就是说,只有谷歌需要在咖啡休息时偶尔模糊地考虑这个问题。

        3
  •  9
  •   Matti Virkkunen    15 年前

    通过查看最大的ID,您将知道它何时会溢出。您应该在任何异常接近被抛出之前对其进行很好的更改。

    事实上,您应该从足够大的数据类型开始设计。即使从一开始就使用64位ID,您的数据库性能也不会受到影响。

        4
  •  6
  •   CSTobey    7 年前

    这里的答案说明了发生了什么,但是只有一个答案说明了如何检测问题(然后只有在错误发生之后)。通常,在这些问题成为生产问题之前能够检测到它们是很有帮助的,因此我编写了一个查询来检测何时将发生溢出:

    SELECT
      c.TABLE_CATALOG,
      c.TABLE_SCHEMA,
      c.TABLE_NAME,
      c.COLUMN_NAME
    FROM information_schema.COLUMNS AS c
    JOIN information_schema.TABLES AS t USING (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME)
    WHERE c.EXTRA LIKE '%auto_increment%'
      AND t.AUTO_INCREMENT / CASE c.DATA_TYPE
          WHEN 'TINYINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 255, 127)
          WHEN 'SMALLINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 65535, 32767)
          WHEN 'MEDIUMINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 16777215, 8388607)
          WHEN 'INT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', 4294967295, 2147483647)
          WHEN 'BIGINT' THEN IF(c.COLUMN_TYPE LIKE '% UNSIGNED', '18446744073709551615', 9223372036854775807) # need to quote because column type defaults to unsigned.
          ELSE 0
        END > .9; # 10% buffer
    

    希望这能帮助别人。

        5
  •  0
  •   Jingguo Yao    9 年前

    对于MySQL5.6, 3.6.9 Using AUTO_INCREMENT 在says中:

    对自动增量列使用最小的整数数据类型,该列足够大,可以容纳所需的最大序列值。当列达到数据类型的上限时,下次尝试生成序列号失败。

        6
  •  -1
  •   Samuel Casimiro    9 年前

    我想分享一下我刚刚经历过的一次个人经历。使用nagios+检查\u mk+ndoutils。ndoutils将所有检查存储在一个名为nagios_servicechecks的表中。主键是有符号的自动增量int。在这个限制范围内,MySQL会发生什么?在我的例子中,MySQL删除了除最后一个记录以外的所有记录。桌子现在几乎空了。每次插入新记录时,都会删除旧记录。不知道为什么会这样,但事实是我失去了所有的记录。idoutils与icinga(而不是nagios)一起使用,通过bigint修复了这个问题。它没有产生错误。