代码之家  ›  专栏  ›  技术社区  ›  Jared Harley

SQLite DBs中的标识列最大值

  •  11
  • Jared Harley  · 技术社区  · 17 年前

    我有一个关于SQLite数据库的纯学术性问题。

    我正在使用SQLite.net在我的WinForm项目中使用一个数据库,在设置一个新表时,我开始考虑ID列的最大值。

    IDENTITY 为了我的 [ID] SQLite.net DataType Mappings DbType.Int64 . 我通常从零开始ID列(将该行作为测试记录),并使数据库自动递增。

    Int64.MaxValue )电话号码是9223372036854775807。就我的目的而言,当达到最大值时,我甚至不会触及表面,但在达到最大值的数据库中会发生什么呢?当我试着阅读这篇文章时,我发现DB2显然将值“包装”为负值(-9223372036854775807),并从中递增,直到数据库无法插入行,因为ID列必须是唯一的。

    在SQLite和/或其他数据库引擎中会发生这种情况吗?

    4 回复  |  直到 14 年前
        1
  •  24
  •   Alex Martelli    17 年前

    我怀疑是否有人确切知道,因为如果每秒插入一百万行,将需要大约292471年才能达到环绕风险点——而数据库在这段时间内只存在了一小部分时间(实际上,智人也是如此)。

        2
  •  7
  •   Matthew Flaschen    17 年前

    在SQLite中,标识实际上不是自动递增的正确方法。这将需要您在应用程序层中执行增量操作。在SQLite shell中,尝试:

    create table bar (id IDENTITY, name VARCHAR);
    insert into bar (name) values ("John");
    select * from bar;
    

    您将看到id只是空的。SQLite没有赋予标识任何特殊意义,因此它基本上是一个普通(非类型化)列。

    create table baz (id INTEGER PRIMARY KEY, name VARCHAR);
    insert into baz (name) values ("John");
    select * from baz;
    

    正如我想你所期望的那样,它将是1。

    注意 there is also 整数主键自动递增。基本区别在于,自动增量可确保从不重用关键点。因此,如果删除John,1将永远不会被重用为id。无论哪种方式,如果使用主键(可选的自动增量)并耗尽id,SQLite都应该在SQLite_FULL而不是wrap-around的情况下失败。

    通过使用IDENTITY,您确实打开了您的 应用程序 如果数据库已满,将错误地环绕。这是完全可能的,因为SQLite中的标识列可以包含任何值(包括负整数)。再次尝试:

    insert into bar VALUES ("What the hell", "Bill");
    insert into bar VALUES (-9, "Mary");
    

    这两种观点都是完全正确的。它们也适用于baz。 使用baz,您可以避免手动指定id。这样,您的id列中就不会有垃圾。

        3
  •  3
  •   Martin Carpella    16 年前

    文档位于 http://www.sqlite.org/autoinc.html 表示 ROWID 一旦达到最大值,将尝试通过随机化查找未使用的值。

    对于 AUTOINCREMENT 它将以失败告终 SQLITE_FULL 在所有插入此表的尝试中,一旦表中存在最大值,则:

    这是必要的,因为 自动增量 保证ID是单调递增的。

        4
  •  1
  •   Adam Robinson    17 年前

    我不能谈论任何特定的DB2实现逻辑,但您描述的“环绕”行为是通过实现签名的数字的标准 two's complement .

    至于实际会发生什么,数据库将如何处理它完全是个未知数。问题出现在实际创建对字段来说太大的id时,因为引擎内部不太可能使用超过64位的数据类型。在这一点上,这是任何人的猜测…用于开发引擎的内部语言可能会抛出,数字可能会自动环绕,只会导致主键冲突(假设存在冲突的ID),世界可能会因为您的溢出而结束,等等。

    但实际上,亚历克斯是正确的。这里涉及的行数的理论限制(假设每行只有一个id,而不是任何形式的骗子身份插入骗局)基本上会使情况变得毫无意义,因为当你可以想象以惊人的插入率输入那么多行时,我们无论如何都会死,所以这没关系:)

    推荐文章