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
?
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?
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
iadd_index
z opcją:unique => true
) zamiast tego, aby symulować podstawową funkcjonalność klucza na jednym z własnych pola.
- ten typ danych jest elementem zastępczym, który Rails przekłada na dowolny klucz podstawowy typ danych, jakiego wymaga twoja baza danych (np.
-
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).
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:
#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
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