Ruby on rails 是否有Rails列类型的文档?

Ruby on rails 是否有Rails列类型的文档?,ruby-on-rails,Ruby On Rails,我想要的不仅仅是简单的类型列表: :主键,:字符串,:文本,:整数,:浮点,:十进制,:日期时间,:时间戳,:时间,:日期,:二进制,:布尔 但是否有任何文档真正定义了这些字段 具体而言: :string和:text之间有什么区别 介于:float和:decimal之间 :time、:timestamp和:datetime的区别特征是什么 这些类型的细微差别是否记录在任何地方 编辑:DB平台实现的要点与我想问的问题无关。如果,比如说,:datetime在Rails文档中没有定义的预期含义,那

我想要的不仅仅是简单的类型列表:

:主键,:字符串,:文本,:整数,:浮点,:十进制,:日期时间,:时间戳,:时间,:日期,:二进制,:布尔

但是否有任何文档真正定义了这些字段

具体而言:

  • :string
    :text
    之间有什么区别
  • 介于
    :float
    :decimal
    之间
  • :time
    :timestamp
    :datetime
    的区别特征是什么
这些类型的细微差别是否记录在任何地方


编辑:DB平台实现的要点与我想问的问题无关。如果,比如说,
:datetime
在Rails文档中没有定义的预期含义,那么DB适配器编写器在选择相应的列类型时依据什么?

根据个人经验构建的指南:

  • 字符串
    • 限制为255个字符(取决于DBMS)
    • 用于短文本字段(姓名、电子邮件等)
  • 文本
    • 无限长度(取决于DBMS)
    • 用于评论、博客文章等。一般经验法则:如果通过textarea捕获,则使用文本。对于使用文本字段的输入,请使用字符串
  • 整数
    • 整数
  • 浮动
    • 以浮点精度存储的十进制数
    • 精度是固定的,这对于某些计算可能会有问题;由于舍入不准确,通常不适用于数学运算
  • 十进制
    • 十进制数字的存储精度根据您的计算需要而变化;将这些用于需要精确的数学
    • 有关浮点数和小数之间差异的示例和深入解释,请参见post
  • 布尔值
    • 用于存储真/假属性(即只有两种状态的东西,如开/关)
  • 二进制文件:
    • 用于以原始原始格式将图像、电影和其他文件存储在称为blob的数据块中
  • :主键
    • 此数据类型是一个占位符,Rails可以将其转换为您选择的数据库所需的任何主键数据类型(即postgreSQL中的
      串行主键
      )。它的使用有点复杂,不推荐使用
    • 使用模型和迁移约束(如
      验证
      的唯一性,\u和
      使用
      :unique=>true
      选项添加索引
      ),而不是在您自己的一个字段上模拟主键功能
  • 日期
    • 仅存储日期(年、月、日)
  • 时间
    • 仅存储一个时间(小时、分钟、秒)
  • 日期时间
    • 存储日期和时间
  • 时间戳
    • 存储日期和时间
    • 注意:就Rails而言,Timestamp和DateTime都表示相同的内容(使用任一类型来存储日期和时间)。对于TL;请阅读下面一段,了解两者存在的原因
这些是经常存在混淆的类型;我希望这有帮助。我真的不知道为什么没有关于这些的官方文件。另外,我设想您提到的这些数据库适配器是由编写Rails的同一个人编写的,因此他们在编写适配器时可能不需要任何文档。希望这有帮助


注意:Rails包含了
:DateTime
:Timestamp
,我可以找到,这主要是为了与数据库系统兼容。例如,MySQL的
时间戳
数据类型存储为unix时间戳。它的有效范围是从1970年到2038年,时间存储为自上一次以来经过的秒数,这被认为是标准的,但实际上可能因系统而异。认识到相对时间在数据库中不是一件好事,MySQL后来引入了
DATETIME
datatype,它存储年、月、日、小时、分钟和秒中的每一个数字,代价是大小增加。保留
时间戳
数据类型是为了向后兼容。其他数据库系统也经历了类似的演变。Rails认识到存在多种标准,并为两者提供了接口。但是,Rails ActiveRecord将
:Timestamp
:DateTime
默认为存储在MySql的
DateTime
中的UTC日期,因此它对Rails程序员没有任何功能上的区别。它们的存在是为了让希望区分两者的用户能够做到这一点。(有关更深入的解释,请参见SO答案)。

我从Rails主分支源代码中找到:


“这是一篇很棒的文章,”阿加扎莱斯说。Rails文档没有这样的内容,这似乎是一个巨大的疏忽。谢谢:)我完全同意,ActiveRecord及其数据类型对Rails非常重要,idk为什么这不是标准文档。文本并不总是无限长的——在MySQL中,它被限制在16kb左右。如果需要16kb以上的数据库,可以使用MEDIUMTEXT和LONGTEXT数据库类型。这也是一个很好的源代码。我知道它是特定于数据库的,但了解实际的实现对于理解rails数据库类型仍然很有帮助。我不能100%肯定,但我认为Nate的资源是重新发布的。请原谅,这些类型是什么?比如,它们是字段或属性还是什么。我正在搜索除
:string
:text
之外的其他内容,除了这个,我找不到其他内容。所以
#activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

  NATIVE_DATABASE_TYPES = {
    primary_key: "bigint auto_increment PRIMARY KEY",
    string:      { name: "varchar", limit: 255 },
    text:        { name: "text", limit: 65535 },
    integer:     { name: "int", limit: 4 },
    float:       { name: "float" },
    decimal:     { name: "decimal" },
    datetime:    { name: "datetime" },
    timestamp:   { name: "timestamp" },
    time:        { name: "time" },
    date:        { name: "date" },
    binary:      { name: "blob", limit: 65535 },
    boolean:     { name: "tinyint", limit: 1 },
    json:        { name: "json" },
  }

  # Maps logical Rails types to MySQL-specific data types.
  def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil)
    sql = case type.to_s
    when 'integer'
      integer_to_sql(limit)
    when 'text'
      text_to_sql(limit)
    when 'blob'
      binary_to_sql(limit)
    when 'binary'
      if (0..0xfff) === limit
        "varbinary(#{limit})"
      else
        binary_to_sql(limit)
      end
    else
      super(type, limit, precision, scale)
    end

    sql << ' unsigned' if unsigned && type != :primary_key
    sql
  end    

# and integer ...

  def integer_to_sql(limit) # :nodoc:
    case limit
    when 1; 'tinyint'
    when 2; 'smallint'
    when 3; 'mediumint'
    when nil, 4; 'int'
    when 5..8; 'bigint'
    else raise(ActiveRecordError, "No integer type has byte size #{limit}")
    end
  end

 # and text ..

  def text_to_sql(limit) # :nodoc:
    case limit
    when 0..0xff;               'tinytext'
    when nil, 0x100..0xffff;    'text'
    when 0x10000..0xffffff;     'mediumtext'
    when 0x1000000..0xffffffff; 'longtext'
    else raise(ActiveRecordError, "No text type has byte length #{limit}")
    end
  end

# and binary ...

    def binary_to_sql(limit) # :nodoc:
      case limit
      when 0..0xff;               "tinyblob"
      when nil, 0x100..0xffff;    "blob"
      when 0x10000..0xffffff;     "mediumblob"
      when 0x1000000..0xffffffff; "longblob"
      else raise(ActiveRecordError, "No binary type has byte length #{limit}")
      end
    end
#activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
  def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
    type = type.to_sym if type
    if native = native_database_types[type]
      column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup

      if type == :decimal # ignore limit, use precision and scale
        scale ||= native[:scale]

        if precision ||= native[:precision]
          if scale
            column_type_sql << "(#{precision},#{scale})"
          else
            column_type_sql << "(#{precision})"
          end
        elsif scale
          raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
        end

      elsif [:datetime, :time].include?(type) && precision ||= native[:precision]
        if (0..6) === precision
          column_type_sql << "(#{precision})"
        else
          raise(ActiveRecordError, "No #{native[:name]} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
        end
      elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
        column_type_sql << "(#{limit})"
      end

      column_type_sql
    else
      type.to_s
    end
  end