Чи є документація для типів стовпців Rails?


181

Я шукаю більше, ніж простий перелік типів, який можна знайти на цій сторінці :

: basic_key,: string,: text,: integer,: float,: decimal,: datetime,: timetamp,: time,: date,: binary,: boolean

Але чи є документація, яка фактично визначає ці поля?

Конкретно:

  • Яка різниця між :stringі :text?
  • Між :floatі :decimal?
  • Які відмінні риси :time, :timestampі :datetime?

Чи документовані нюанси цих типів де-небудь?

EDIT: Точки реалізації платформи DB не стосуються питання, яке я намагаюся задати. Якщо, скажімо, :datetimeв документації на Rails немає визначеного значення, яке значення має бути в документації Rails, то що робити db-адаптери-записувачі, вибираючи відповідний тип стовпця?


1
Що це за типи, вибачте за вибір моїх слів, речей ? Мовляв, це поля чи атрибути чи що. Я шукав інші речі , крім :stringі :textя не міг знайти, крім цього. Отже, я просто цікавився для подальшого використання.
l1zZY

2
@ l1zZY, ​​термін, який ви можете шукати, - це "типи даних".
малює слона

Відповіді:


397

Настанови, побудовані з особистого досвіду:

  • Рядок :
    • Обмежено до 255 символів (залежно від СУБД)
    • Використовувати для коротких текстових полів (імена, електронні листи тощо)
  • Текст :
    • Необмежена довжина (залежно від СУБД)
    • Використовуйте для коментарів, публікацій блогу тощо. Загальне правило: якщо це зроблено через textarea, використовуйте Text. Для введення тексту за допомогою текстових полів використовуйте рядок.
  • Ціле число :
    • Цілі числа
  • Поплавок :
    • Десяткові числа, що зберігаються з точністю з плаваючою комою
    • Точність фіксована, що може бути проблематичним для деяких розрахунків; як правило, не добре для математичних операцій через неточне округлення.
  • Десяткові :
    • Десяткові числа, що зберігаються з точністю, яка змінюється відповідно до того, що потрібно для ваших розрахунків; використовувати їх для математики, яка повинна бути точною
    • Дивіться цей пост для прикладу і пояснення поглиблених про відмінності між поплавками і знаками після коми.
  • Булева :
    • Використовуйте для зберігання істинних / хибних атрибутів (тобто речей, які мають лише два стани, наприклад увімкнення / вимкнення)
  • Двійковий :
    • Використовуйте для зберігання зображень, фільмів та інших файлів у їх оригінальному, необробленому форматі в шматках даних, що називаються краплями
  • : Primary_key
    • Цей тип даних є заповнювачем місця, який Rails переводить у будь-який тип даних первинного ключа, який вимагає ваша база даних (тобто serial primary keyв postgreSQL). Його використання дещо складне і не рекомендується.
    • Використовуйте модельні та міграційні обмеження (як-от validates_uniqueness_ofі add_indexз :unique => trueопцією) замість цього, щоб імітувати функціональність первинного ключа в одному з ваших власних полів.
  • Дата :
    • Зберігає лише дату (рік, місяць, день)
  • Час :
    • Зберігає лише час (години, хвилини, секунди)
  • DateTime :
    • Зберігає дату та час
  • Відмітка часу
    • Зберігає дату та час
    • Примітка. Для цілей Rails і Timetamp, і DateTime означають одне і те ж (використовуйте будь-який тип, щоб зберігати дату і час). Для опису TL; DR, чому обидва існують, читайте нижній абзац.

Це типи, щодо яких часто виникає плутанина; Я сподіваюся, що це допомагає. Я справді не знаю, чому немає офіційної документації про них. Крім того, я думаю, що ці адаптери бази даних, про які ви згадували, були написані тими ж людьми, що писали Rails, тому їм, ймовірно, не потрібна документація, коли вони писали адаптери. Сподіваюся, це допомагає!

Примітка: наявність обох, :DateTimeі :Timestamp, як я можу знайти, включена в Rails здебільшого для сумісності з системами баз даних. Наприклад, TIMESTAMPтип даних MySQL зберігається як часова мітка Unix. Дійсний діапазон становить від 1970 до 2038 року, а час зберігається як кількість секунд, що минули з часу останньої епохи , що нібито є стандартним, але на практиці може відрізнятися від системи до системи. Визнаючи, що відносний час у базах даних було не надто реальним, MySQL пізніше представив DATETIMEтип даних, який зберігає кожну цифру за рік, місяць, день, годину, хвилину та секунду, ціною збільшення розміру. TheTIMESTAMPтип даних збережено для зворотної сумісності. Інші системи баз даних пройшли подібну еволюцію. Рейки визнали, що існує кілька стандартів, і забезпечили інтерфейс для обох. Однак для Rails ActiveRecord за замовчуванням застосовуються як дати, так :Timestampі :DateTimeдати UTC, що зберігаються в MySql DATETIME, тому це не має функціональної різниці для програмістів Rails. Вони існують, щоб користувачі, які бажають розмежуватись між ними, могли це зробити. (Для більш поглибленого пояснення дивіться цю відповідь ТА).


21
Це дивовижний запис, @aguazales. Це здається величезним наглядом, що документація Rails не має подібного.
Грант Бірхмайер

Дякую :) І я повністю згоден, ActiveRecord та його типи даних настільки важливі для Rails, idk, чому це не стандартна документація.
aguazales

2
Текст не завжди необмеженої довжини - в MySQL він обмежений приблизно 16 кбіт. Існують типи баз даних MEDIUMTEXT та LONGTEXT, якщо вам потрібно більше 16 кбіт.
Хаегін

3
Це також непоганий джерело типів даних міграції Rails - MySql - Postgresql - SQLite . Я знаю, що це специфічна база даних, але знати фактичну реалізацію все ще корисно при розумінні типів баз рейок.
Нейт

1
Я не можу бути на 100% впевнений, але я думаю, що ресурс Нейт був репонований тут .
aguazales

10

З вихідного коду головного відділення Rails я знайшов:

абстрактний mysql_adapter

#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

superв type_to_sqlметоді

#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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.