【问题标题】:What happens when the ActiveRecord ID overflows?ActiveRecord ID 溢出时会发生什么?
【发布时间】:2014-04-22 15:00:47
【问题描述】:

我知道这种情况是一种极端情况,因为 2,147,483,647 是一个非常大的数字,但我想知道当 ID 值溢出时 ActiveRecord 是否会做任何特别的事情。 ID 值似乎通常被定义为一个整数,所以我想如果很快创建新对象会出现某种问题。这可能不是一个直接的问题,但如果一个系统每天或每小时创建数千次条目,它可能会在多年后成为一个问题。

我有一些示例代码来说明我在说什么。

require "active_record"
require "pg"

ActiveRecord::Base.establish_connection(
  adapter: "postgresql",
  ...
)

ActiveRecord::Migration.suppress_messages do
  ActiveRecord::Schema.define do
    create_table :garbages
  end
end

class Garbage < ActiveRecord::Base; end
loop do
  Garbage.create
end

如果我继续让它运行会发生什么?避免这种事情的最佳解决方案是什么?

编辑:将示例切换到使用 32 位整数的 postgresql。

【问题讨论】:

  • 我认为 sqlite 整数主键是 64 位的,首先,例如,sqlite.org/lang_createtable.html#rowid。假设删除为零,则为 9,223,372,036,854,775,807 个条目。无论如何,如果您使用的系统将创建 20 亿个条目,您可能会在它翻转之前遇到性能问题,如果您预计这是一个问题,您可能不会使用整数 ID,不是吗?
  • 我在我的例子中使用了 sqlite3,但我更多地考虑使用 32 位条目的 postgresql。
  • 我投票决定关闭它,理由是它是假设的。与大多数假设性问题一样,这个问题不太可能真正帮助任何人。
  • @JonathanSternberg 见bigserial
  • 好的,第一步是将主键字段切换为允许更大范围的唯一值的数据类型:正如@DaveNewton 所说,即使切换到 64 位数字也会给你大约 10 ^18 个值。在此之前,尽管您会重新设计以将数据拆分到不同的数据库中,从而完全绕过问题,但在其他方面使您的系统更加复杂。此外,尽可能快地将垃圾值发送到您的数据库中不会模拟任何事情,除了您在胡闹。完成一些适当的工作:)

标签: ruby-on-rails database activerecord


【解决方案1】:

这根本不是假设,但它不会经常发生。

当您的 int ID 达到 Int32 的限制时,您需要转到 Int64。在 SQL Server 上,这称为 BIG_INT。在 Postgres 上它的 bigint。我不得不使用它们两次。如果你能溢出那......

不过,如果调整大小表明将来某个时间可能会溢出 int32,那么从一开始就使用 bigint 会更容易。如果你从不需要它,没问题。如果你这样做了,你就被排序了,并且不必转换 210 亿行......

【讨论】:

    猜你喜欢
    • 2017-09-04
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    相关资源
    最近更新 更多