Rails 3 迁移:添加无符号整型列

11

我想生成一个迁移来向数据类型为unsigned int的表中添加一列。 我希望像这篇文章 中所述的那样使用它来存储IP地址。

我看到了这个问题 ,但这会使迁移数据库依赖,有更好的方法吗?


我认为你应该评估下面Mohsen Alizadeh的答案 - 它正是你想要的。我无法确认数据库互操作性,但我正在使用MySQL,所以它非常适合我。PostgreSQL在Rails中有自己的:ip_address类型支持 - 所以我认为这涵盖了你所有的基础。他确实值得获得"正确答案"勾选。 - Ash
对于那些可以接受验证的懒人 :) validates :cost, numericality: { greater_than: 0 } - Dorian
4个回答

16

这里展示了一种可行的解决方案,可以在Rails迁移中更加原生地实现: 在Ruby on Rails迁移中创建无符号整数字段?

为了长期考虑,答案是在选项中添加自定义规范以创建无类型列:

t.column :population, 'integer unsigned'

我认为使用“integer unsigned”在数据库中是相对独立的,但可能不是100%。如果您愿意将自己锁定到特定的数据库,也可以使用类似“BIGINT unsigned”的东西。

此外,我对Geoff的回答有些失望,因为他似乎完全忽视了一个无符号整数尽管使用相同的存储空间,但保存了不同的数据集这一事实。如果您知道不需要负数并且有兴趣优化数据存储需求,则无符号整数很有价值。有关mysql指南,请参见:http://dev.mysql.com/doc/refman/5.5/en/integer-types.html

需要指出JellicleCat下面的说明非常重要,即模式文件将无法跟踪此更改,因此在加载模式时将丢失列的签名方面。


2
这个答案的问题在于Rails的schema.rb文件永远不会反映出特殊的“unsigned”属性。因此,当您在新环境上设置应用程序并使用模式文件创建数据库时,您的应用程序将为population字段设置有符号位。 - JellicleCat
很好的发现,我实际上没有注意到。假设宝石能够捕捉到这一点,似乎这是更好的选择。Rails让你传递自定义配置然后却丢失了它,这似乎有些奇怪。无论如何,这是一个很好的提示,我会编辑答案以确保它突出显示。 - whoughton

9

第一步:

将activerecord-mysql-unsigned添加到GemFile中。

# add unsigned integer support to mysql2 adapter
gem "activerecord-mysql-unsigned", "~> 0.0.1"

步骤2:安装Gems

bundle install

步骤三:

在您喜欢的字段中使用“unsigned: true”。

t.integer :cost, unsigned: true

参考文献: http://rubydoc.info/gems/activerecord-mysql-unsigned/0.0.1/frames 该文档是ActiveRecord的MySQL无符号整数扩展库,提供通过Active Record在MySQL中使用无符号整数的支持。其中包括数据类型、验证器和查询构造器等方面的详细说明。

1
这正是我想要做的,将IPv4地址存储为无符号整数 - 并且不需要我的数据库中所有PK字段都带有符号(因为ID永远不会是负数),非常完美。 - Ash

1

你可以通过执行SQL查询来完成,

如果是MySQL查询,则为

添加新列

ALTER TABLE table_name ADD column_name INT unsigned;

删除列

ALTER TABLE table_name DROP column_name;

迁移:

class MyMigration < ActiveRecord::Migration
  def self.up
    execute "ALTER TABLE table_name ADD column_name INT unsigned;"
  end

  def self.down
     execute "ALTER TABLE table_name DROP column_name;"
  end
end

它将使其依赖于数据库。 - Shobhit
1
由于Rails不支持unsigned int,因此@shobhit想要的类型无法实现。因此,我建议执行SQL查询。 - Raghvendra Parashar
@user806495 具体来说,我需要3次。此外,我正在教一群人Rails,出于学术原因想要了解它。 - Shobhit

-7

抱歉。Unsigned 不是支持的 Rails 数据类型之一。

请参阅下面指南的第 1.4 节。

http://guides.rubyonrails.org/migrations.html

我不确定你为什么认为你需要无符号。整数和无符号都占用相同数量的位,有符号只是表示您想将其中一个位解释为有符号位的约定。如果您分配一个带有有符号位的值,数据库将认为它是负数,但您会更明白,您可以意识到自己比机器更聪明,因此可以微笑。

希望这可以帮助到您。


2
MySQL的新版本(5.6.x)在您尝试将大型IP放入带有消息的signed int-11中时会失败,例如“Data truncation: Out of range value for column 'ip'”。 - Jason
3
在自增主键列中使用无符号整数将使您拥有两倍的可能主键 - 例如,无符号整数可达到40亿,而有符号整数只能达到20亿。 - Jonathan Swartz
2
"...数据库会认为它是一个负数,但你会更清楚。只要你是处理该列的唯一人员,生活将很美好。然而,如果你在现实世界中工作,那么拥有只有你知道的秘密是一件不好的事情。" - Richard Haven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接