How to create columns like "bigint" or "longtext" in Rails migrations

Rails understands a :limit options when you create columns in a migration. Its meaning depends on the column type, and sometimes the supplied value.

The documentation states that :limit sets the column length to the number of characters for string and text columns, and to the number of bytes for binary and integer columns.

Using it

This is nice since you may want a bigint column to store really long numbers in it. You can just create it by saying integer, :limit => 8 and you'll be able to store 8 bytes of data. Similarly, you can use it to get a mediumtext or longtext column by applying the proper limits (65535 bytes would be a text, up to 16777215 a mediumtext, and up to 4294967295 a longtext).

Or if you know that you'll never store more than a certain value, you might want to choose smaller column sizes for performance (it won't matter until your project becomes big, so don't worry about it for now).

Integer column lengths, mediumintbigint, and all that other stuff

Mind that some values have a special meaning for integer:

 
 
create_table 'example' do |t| t.integer :int # int (4 bytes, max 2,147,483,647) t.integer :int1, :limit => 1 # tinyint (1 byte, -128 to 127) t.integer :int2, :limit => 2 # smallint (2 bytes, max 32,767) t.integer :int3, :limit => 3 # mediumint (3 bytes, max 8,388,607) t.integer :int4, :limit => 4 # int (4 bytes) t.integer :int5, :limit => 5 # bigint (8 bytes, max 9,223,372,036,854,775,807) t.integer :int8, :limit => 8 # bigint (8 bytes) t.integer :int11, :limit => 11 # int (4 bytes) end

The first case is probably not surprising, it's just the default: when you say integer :my_column, you just get an int, or int(11) since its maximum value has 11 digits. You'll get the same when saying :limit => 4 just because an int holds up to 4 bytes of data.

However, mind that while you might think saying :limit => 11 gives you something like a superbigint or at least an exception, it will in fact create an int column, which is smaller than a bigint.


These are values for MySQL. I don't know what happens on other database adapters

--------------------------------------------------------------------------------------------------------

Using BIGINT columns in rails migrations

Sometimes, you need to use BIGINT columns in your databases, e.g. when working with Twitter whose IDs are over 32 bits long now, and will be 64 bits long soon.

After some googling which didn’t bring up any good results, a quick look into the adapter code helps us:


# activerecord-3.0.0/lib/active_record/connection_adapters/mysql_adapter.rb
# Maps logical Rails types to MySQL-specific data types.
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  return super unless type.to_s == 'integer'

  case limit
  when 1; 'tinyint'
  when 2; 'smallint'
  when 3; 'mediumint'
  when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
  when 5..8; 'bigint'
  else raise(ActiveRecordError, "No integer type has byte size #{limit}")
  end
end

So, use integer with :limit => 8 to get a bigint column. If you need a primary key of type bigint, you need to pass :id => false to your create_table call, then define the id column manually:


class CreateDemo < ActiveRecord::Migration
  def self.up
    create_table :demo, :id => false do |t|
      t.integer :id, :limit => 8
    end
  end
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值