Sql 在Rails ActiveRecord中生成序列号

Sql 在Rails ActiveRecord中生成序列号,sql,ruby-on-rails,activerecord,Sql,Ruby On Rails,Activerecord,在Rails应用程序中,我需要一个唯一的、连续的(无间隙)整数源来用作序列号。它必须是持久的,并允许并发访问 数据库自动增量是不够的,因为大多数数据库不保证“无间隙”属性 在straight SQL中,我只需创建一个单行表,然后(在PostgreSQL中)说: update sequence set value = value + 1 returning value 这显然是SQL世界中的标准实践。参考文献存在 在ActiveRecord中,我轻松地创建了一个模型,并找到了.increment

在Rails应用程序中,我需要一个唯一的、连续的(无间隙)整数源来用作序列号。它必须是持久的,并允许并发访问

数据库自动增量是不够的,因为大多数数据库不保证“无间隙”属性

在straight SQL中,我只需创建一个单行表,然后(在PostgreSQL中)说:

update sequence set value = value + 1 returning value
这显然是SQL世界中的标准实践。参考文献存在


在ActiveRecord中,我轻松地创建了一个模型,并找到了
.increment
递增计数器
。但我不知道如何自动检索递增的值。锁和事务似乎没有帮助。

如果你想使用redis(也许你已经在使用Resque或Sidekiq),你可以在一个键上执行一个
INCR
,这是原子的并返回新值。

因为
更新。。。返回
就输出而言就像选择一样,事实证明,您可以使用
find_by_sql
在一次操作中同时更新和获取更新的值

class SequenceNumber < ActiveRecord::Base
  attr_accessible :tag, :value
  validates :tag, :uniqueness => true

  def self.get_next(tag)
    find_by_sql("update sequence_numbers 
                 set value = value + 1 
                 where tag = '#{tag}' 
                 returning value").first.value
  end
end
class SequenceNumbertrue
定义自我。获取下一个(标签)
通过sql查找(“更新序列号”)
设定值=值+1
其中tag='#{tag}'
返回值“).first.value
结束
结束

剩下的问题是,这是完全不可移植的,因为返回的
是pgsql扩展。也许ActiveRecord开发人员会注意到这一点。

谢谢!我想到了这一点,这将是我的备用解决方案。在redis中有没有办法确保每个这样的事务的持久性?我的理解是,它通常只定期将数据保存在RAM和快照中。我担心的是,redis服务器崩溃后,当它恢复时可能会产生重复的数字。这取决于配置。对于持久性,有一个AOF选项,它对系统故障具有弹性。我会给你支票,因为你的答案很好,而接受我自己的答案很奇怪。接受一个人的答案并不奇怪,这是有规则的(例如,在发布答案后等待24小时)。在任何情况下,正如你正确地说的,它是完全不可携带的,所以它和我的一样好…;)