Czy istnieje dokumentacja dla typów kolumn Rails?

Szukam czegoś więcej niż prosty typ listy , który znajduje się na tej stronie :

: primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary,: boolean

Ale czy jest jakaś dokumentacja, która faktycznie definiuje te pola?

Konkretnie:

  • Jaka jest różnica między :string a :text?
  • między :float a :decimal?
  • jakie są cechy wyróżniające :time, :timestamp, i :datetime?
Czy niuanse tego typu są gdzieś udokumentowane?

EDIT: punkty implementacji DB-platform nie mają znaczenia dla pytania, które próbuję zadać. jeśli, powiedzmy, :datetime nie ma zdefiniowanego zamierzonego znaczenia w dokumentacji Rails, to czym kierują się pisarze db-adapter przy wyborze odpowiedniego typu kolumny?

Author: Grant Birchmeier, 2012-08-09

2 answers

Wytyczne zbudowane z osobistego doświadczenia:

  • String :
    • ograniczone do 255 znaków (w zależności od DBMS)
    • Użyj dla krótkich pól tekstowych (nazwy, e-maile, itp.)
  • tekst :
    • Nieograniczona długość (w zależności od DBMS)
    • używaj do komentarzy, wpisów na blogu itp. Ogólna zasada: jeśli jest przechwycony przez textarea, użyj tekstu. Do wprowadzania za pomocą pól tekstowych, użyj sznurek.
  • liczba całkowita :
    • liczby całkowite
  • Float :
    • liczby dziesiętne przechowywane z precyzją zmiennoprzecinkową
    • precyzja jest stała, co może być problematyczne dla niektórych obliczeń; generalnie nie nadaje się do operacji matematycznych z powodu niedokładnego zaokrąglania.
  • dziesiętny :
    • liczby dziesiętne przechowywane z dokładnością, która różni się w zależności od tego, co jest potrzebne przez obliczenia; użyj ich do matematyki, która musi być dokładna
    • Zobacz ten post , aby uzyskać przykłady i szczegółowe wyjaśnienie różnic między pływakami i dziesiętnikami.
  • Boolean :
    • używaj do przechowywania prawdziwych / fałszywych atrybutów (tj. rzeczy, które mają tylko dwa stany, takie jak on/off)
  • binarny :
    • służy do przechowywania obrazów, filmów i innych plików w oryginalnym, surowym formacie w kawałkach danych zwanych blobs
  • :primary_key
    • ten typ danych jest elementem zastępczym, który Rails przekłada na dowolny klucz podstawowy typ danych, jakiego wymaga twoja baza danych (np. serial primary key w postgreSQL). Jego stosowanie jest nieco skomplikowane i nie zaleca się.
    • użyj ograniczeń modelu i migracji (takich jak validates_uniqueness_of i add_index z opcją :unique => true) zamiast tego, aby symulować podstawową funkcjonalność klucza na jednym z własnych pola.
  • Data :
    • przechowuje tylko datę (Rok, Miesiąc, Dzień)
  • CZAS :
    • przechowuje tylko czas (Godziny, Minuty, Sekundy)
  • DateTime :
    • przechowuje zarówno datę, jak i czas
  • Timestamp
    • przechowuje zarówno datę, jak i czas
    • uwaga: dla potrzeb Rails, zarówno znacznik czasu, jak i DateTime oznaczają to samo (użyj dowolnego typu do przechowywania zarówno daty, jak i czasu). Dla TL; DR opis dlaczego oba istnieją, przeczytaj dolny akapit.

Są to typy, o których często istnieje zamieszanie; mam nadzieję, że to pomoże. Naprawdę Nie wiem, dlaczego nie ma oficjalnej dokumentacji na ten temat. Wyobrażam sobie również, że te adaptery baz danych, o których wspomniałeś, zostały napisane przez tych samych ludzi, którzy napisali Rails, więc prawdopodobnie nie potrzebowali żadnej dokumentacji, aby przejść obok, gdy pisali Adaptery. Hope this pomaga!

Uwaga: obecność zarówno :DateTime jak i :Timestamp, z tego co mogę znaleźć, jest uwzględniana przez Rails głównie dla kompatybilności z systemami bazodanowymi. Na przykład typ danych MySQL TIMESTAMP jest przechowywany jako znacznik czasu w systemie unix. Jego poprawny zakres sięga od 1970 do 2038, a czas jest zapisywany jako liczba sekund, które upłynęły od ostatniej epoki , co jest podobno standardem, ale w praktyce może się różnić w zależności od systemu. Uznając, że czas względny nie był dobrą rzeczą dla w bazach danych MySQL wprowadził później typ danych DATETIME, który przechowuje każdą cyfrę w roku, miesiącu, dniu, godzinie, minucie i sekundzie, kosztem zwiększenia rozmiaru. Typ danych TIMESTAMP został zachowany dla zgodności wstecznej. Inne systemy baz danych przeszły podobną ewolucję. Rails uznał, że istnieje wiele standardów i dostarczył interfejsy do obu. Jednak Rails ActiveRecord domyślnie ustawia :Timestamp i :DateTime Na daty UTC przechowywane w DATETIME MySql, więc nie działa różnica w stosunku do programistów Rails. Istnieją one po to, aby użytkownicy, którzy[78]}chcą {79]} rozróżnić te dwa mogą to zrobić. (Aby uzyskać bardziej szczegółowe wyjaśnienie, zobacz to więc odpowiedz).

 383
Author: aguazales,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:58

Z kodu rails master branch souce znalazłem:

Abstract 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

Metoda super w 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
 7
Author: fangxing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-04 00:16:32