Có tài liệu cho các loại cột Rails?


181

Tôi đang tìm kiếm nhiều hơn danh sách loại đơn giản được tìm thấy trên trang này :

: primary_key ,: string ,: text ,: số nguyên ,: float ,: binary ,: datetime ,: dấu thời gian ,: time ,: date ,: binary ,: boolean

Nhưng có tài liệu nào thực sự định nghĩa các lĩnh vực này không?

Đặc biệt:

  • Sự khác biệt giữa :stringvà là :textgì?
  • Giữa :float:decimal?
  • Các tính năng phân biệt của là gì :time, :timestamp:datetime?

Các sắc thái của các loại này được ghi nhận ở bất cứ đâu?

EDIT: Điểm của việc triển khai nền tảng DB không liên quan đến câu hỏi tôi đang cố gắng hỏi. Nếu, giả sử, :datetimekhông có ý nghĩa dự định được xác định trong tài liệu Rails, thì các trình soạn thảo db-adapter sẽ làm gì khi chọn một loại cột tương ứng?


1
Những loại đó, xin lỗi sự lựa chọn của tôi về từ, sự vật , được gọi là gì? Giống như, chúng là các trường hoặc thuộc tính hoặc những gì. Tôi đã tìm kiếm khác điều khác hơn :string:textvà tôi không thể tìm thấy bất kỳ khác hơn thế này. Vì vậy, tôi chỉ tự hỏi để tham khảo trong tương lai.
l1zZY

2
@ l1zZY, ​​thuật ngữ bạn có thể đang tìm kiếm là "loại dữ liệu".
đó là

Câu trả lời:


397

Nguyên tắc được xây dựng từ kinh nghiệm cá nhân:

  • Chuỗi :
    • Giới hạn ở 255 ký tự (tùy thuộc vào DBMS)
    • Sử dụng cho các trường văn bản ngắn (tên, email, v.v.)
  • Văn bản :
    • Độ dài không giới hạn (tùy thuộc vào DBMS)
    • Sử dụng cho các bình luận, bài đăng trên blog, v.v ... Quy tắc chung: nếu nó được ghi lại qua textarea, hãy sử dụng Văn bản. Đối với đầu vào sử dụng trường văn bản, sử dụng chuỗi.
  • Số nguyên :
    • Số nguyên
  • Phao :
    • Số thập phân được lưu trữ với độ chính xác dấu phẩy động
    • Độ chính xác là cố định, có thể có vấn đề đối với một số tính toán; nói chung là không tốt cho các hoạt động toán học do làm tròn không chính xác.
  • Số thập phân :
    • Số thập phân được lưu trữ với độ chính xác thay đổi tùy theo những gì cần thiết cho tính toán của bạn; sử dụng chúng cho toán học cần phải chính xác
    • Xem bài đăng này để biết ví dụ và giải thích sâu về sự khác biệt giữa số float và số thập phân.
  • Boolean :
    • Sử dụng để lưu trữ các thuộc tính đúng / sai (nghĩa là những thứ chỉ có hai trạng thái, như bật / tắt)
  • Nhị phân :
    • Sử dụng để lưu trữ hình ảnh, phim và các tệp khác ở định dạng ban đầu, thô trong khối dữ liệu được gọi là blobs
  • :khóa chính
    • Kiểu dữ liệu này là một trình giữ chỗ mà Rails chuyển thành bất kỳ kiểu dữ liệu khóa chính nào mà cơ sở dữ liệu bạn chọn yêu cầu (ví dụ như serial primary keytrong postgreQuery). Việc sử dụng của nó là hơi phức tạp và không được khuyến khích.
    • Thay vào đó, hãy sử dụng các ràng buộc mô hình và di chuyển (như validates_uniqueness_ofadd_indexvới :unique => truetùy chọn) để mô phỏng chức năng khóa chính trên một trong các trường của riêng bạn.
  • Ngày :
    • Cửa hàng chỉ một ngày (năm, tháng, ngày)
  • Thời gian :
    • Chỉ lưu trữ một thời gian (giờ, phút, giây)
  • Ngày giờ :
    • Lưu trữ cả ngày và giờ
  • Dấu thời gian
    • Lưu trữ cả ngày và giờ
    • Lưu ý: Đối với mục đích của Rails, cả Dấu thời gian và Ngày giờ đều có nghĩa giống nhau (sử dụng một trong hai loại để lưu trữ cả ngày và giờ). Đối với mô tả TL; DR về lý do cả hai tồn tại, hãy đọc đoạn dưới cùng.

Đây là những loại mà sự nhầm lẫn thường tồn tại; Tôi hi vọng cái này giúp được. Tôi thực sự không biết tại sao không có tài liệu chính thức về những điều này. Ngoài ra, tôi tưởng tượng các bộ điều hợp cơ sở dữ liệu mà bạn đề cập đến được viết bởi cùng những người đã viết Rails, vì vậy họ có thể không cần bất kỳ tài liệu nào để đi khi họ đang viết bộ điều hợp. Hi vọng điêu nay co ich!

Lưu ý: sự hiện diện của cả hai :DateTime:Timestamp, từ những gì tôi có thể tìm thấy, được Rails đưa vào chủ yếu để tương thích với các hệ thống cơ sở dữ liệu. Ví dụ, TIMESTAMPkiểu dữ liệu của MySQL được lưu trữ dưới dạng dấu thời gian unix. Phạm vi hợp lệ của nó đi từ 1970 đến 2038 và thời gian được lưu trữ dưới dạng số giây đã trôi qua kể từ khi epoch cuối cùng , được cho là tiêu chuẩn, nhưng trên thực tế có thể khác với hệ thống. Nhận thấy rằng thời gian tương đối không phải là một điều tốt trong cơ sở dữ liệu, MySQL sau đó đã giới thiệu DATETIMEkiểu dữ liệu, lưu trữ mọi chữ số trong năm, tháng, ngày, giờ, phút và giây, với chi phí tăng kích thước. CácTIMESTAMPkiểu dữ liệu được giữ lại để tương thích ngược. Các hệ thống cơ sở dữ liệu khác đã trải qua các diễn biến tương tự. Rails nhận ra rằng có nhiều tiêu chuẩn tồn tại và cung cấp giao diện cho cả hai. Tuy nhiên, Rails ActiveRecord mặc định cả hai :Timestamp:DateTimeđến ngày UTC được lưu trữ trong MySql DATETIME, do đó, nó không có sự khác biệt về chức năng đối với các lập trình viên Rails. Chúng tồn tại để người dùng muốnđể phân biệt giữa hai có thể làm như vậy. (Để được giải thích sâu hơn, hãy xem câu trả lời SO này ).


21
Đó là một bài viết tuyệt vời, @aguazales. Có vẻ như một sự giám sát quá lớn rằng tài liệu Rails không có cái gì đó như thế này.
Grant Birchmeier

Cảm ơn :) Và tôi hoàn toàn đồng ý, ActiveRecord và các kiểu dữ liệu của nó rất quan trọng đối với Rails, idk tại sao đây không phải là tài liệu chuẩn.
aguazales

2
Văn bản không phải lúc nào cũng không giới hạn - trong MySQL, nó bị giới hạn ở khoảng 16kb. Có các loại cơ sở dữ liệu MEDIUMTEXT và LONGTEXT nếu bạn cần nhiều hơn 16kb.
Haegin

3
Đây cũng là một loại dữ liệu di chuyển Rails nguồn tốt - MySql - Postgresql - SQLite . Tôi biết cơ sở dữ liệu cụ thể nhưng biết việc triển khai thực tế vẫn hữu ích khi hiểu các loại cơ sở dữ liệu đường ray.
Nate

1
Tôi không thể chắc chắn 100%, nhưng tôi nghĩ tài nguyên của Nate đã được đăng lại ở đây .
aguazales

10

Từ mã nguồn chi nhánh Rails tôi tìm thấy:

trừu tượng mysql_ad CHƯƠNG

#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

những supertrong type_to_sqlphương pháp

#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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.