ruby-on-rails - software - ruby on rails tutorial
¿Hay documentación para los tipos de columna Rails? (2)
Del código fuente de la rama maestra de Rails encontré:
#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
el super
en el método 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
Estoy buscando algo más que la simple lista de tipos que se encuentra en esta página :
: primary_key,: string,: text,: integer,: float,: decimal,: datetime,: timestamp,: time,: date,: binary,: boolean
Pero, ¿hay alguna documentación que realmente defina estos campos?
Específicamente:
- ¿Cuál es la diferencia entre
:string
y:text
? - Entre
:float
y:decimal
? - ¿Cuáles son las características distintivas de
:time
:timestamp
y:datetime
?
¿Los matices de estos tipos están documentados en alguna parte?
EDITAR: los puntos de las implementaciones de la plataforma DB son irrelevantes para la pregunta que estoy tratando de hacer. Si, por ejemplo :datetime
no tiene un significado intencional definido en la documentación de Rails, ¿a qué se deben aplicar los db-adapter-writers al elegir el tipo de columna correspondiente?
Pautas construidas a partir de la experiencia personal:
- Cadena :
- Limitado a 255 caracteres (según DBMS)
- Usar para campos de texto cortos (nombres, correos electrónicos, etc.)
- Texto :
- Longitud ilimitada (según DBMS)
- Úselo para comentarios, publicaciones en blogs, etc. Regla general: si se captura a través de textarea, use Texto. Para ingresar usando campos de texto, use cadena.
- Entero :
- Números enteros
- Float :
- Números decimales almacenados con precisión de coma flotante
- La precisión es fija, lo que puede ser problemático para algunos cálculos; generalmente no es bueno para las operaciones de matemáticas debido a un redondeo inexacto.
- Decimal :
- Números decimales almacenados con precisión que varía de acuerdo con sus cálculos; utilizar estos para las matemáticas que debe ser precisa
- Consulte this publicación para ver ejemplos y una explicación detallada de las diferencias entre flotantes y decimales.
- Booleano :
- Úselo para almacenar atributos verdadero / falso (es decir, cosas que solo tienen dos estados, como encendido / apagado)
- Binario :
- Úselo para almacenar imágenes, películas y otros archivos en su formato original sin procesar en fragmentos de datos llamados blobs
- :Clave primaria
- Este tipo de datos es un marcador de posición que Rails traduce a cualquier tipo de datos de
serial primary key
requiera su base de datos de elección (es decirserial primary key
en postgreSQL). Su uso es algo complicado y no recomendado. - Use restricciones de modelo y migración (como
validates_uniqueness_of
yadd_index
con la opción:unique => true
) en su lugar para simular la funcionalidad de la clave principal en uno de sus propios campos.
- Este tipo de datos es un marcador de posición que Rails traduce a cualquier tipo de datos de
- Fecha :
- Almacena solo una fecha (año, mes, día)
- Tiempo :
- Almacena solo un tiempo (horas, minutos, segundos)
- DateTime :
- Almacena tanto la fecha como la hora
- Marca de tiempo
- Almacena tanto la fecha como la hora
- Nota: Para los propósitos de Rails, tanto Timestamp como DateTime significan lo mismo (use cualquier tipo para almacenar tanto la fecha como la hora). Para la descripción de TL; DR de por qué ambos existen, lea el párrafo inferior.
Estos son los tipos sobre los que a menudo existe confusión; Espero que esto ayude. Realmente no sé por qué no hay documentación oficial sobre esto. Además, me imagino que estos adaptadores de base de datos a los que se refiere fueron escritos por las mismas personas que escribieron Rails, por lo que probablemente no necesitaron ninguna documentación cuando escribieron los adaptadores. ¡Espero que esto ayude!
Nota: la presencia de ambos :DateTime
y :Timestamp
, de lo que puedo encontrar, está incluido por Rails sobre todo para la compatibilidad con los sistemas de bases de datos. Por ejemplo, el tipo de datos TIMESTAMP
de MySQL se almacena como una marca de tiempo Unix. Su rango válido va de 1970 a 2038, y el tiempo se almacena como el número de segundos transcurridos desde la última epoch , que supuestamente es estándar, pero en la práctica puede diferir de un sistema a otro. Reconociendo que el tiempo relativo no era algo bueno para tener en las bases de datos, MySQL introdujo más tarde el tipo de datos DATETIME
, que almacena cada dígito en el año, mes, día, hora, minuto y segundo, a costa de un aumento de tamaño. El tipo de datos TIMESTAMP
fue retenido por compatibilidad con versiones anteriores. Otros sistemas de bases de datos experimentaron evoluciones similares. Rails reconoció que existían estándares múltiples y proporcionó interfaces para ambos. Sin embargo, Rails ActiveRecord predetermina ambos :Timestamp
y :DateTime
a las fechas UTC almacenadas en DATETIME
de DATETIME
, por lo que no establece ninguna diferencia funcional para los programadores de Rails. Existen para que los usuarios que deseen diferenciar entre los dos puedan hacerlo. (Para una explicación más detallada, vea this respuesta SO).