Je recherche plus que la simple liste de types qui se trouve sur cette page :
: primary_key,: string,: text,: integer,: float,: decimal,: datetime,: timestamp,: time,: date,: binary,: boolean
Mais existe-t-il une documentation qui définit réellement ces champs?
Plus précisément:
- Quelle est la différence entre
:string
et:text
? - Entre
:float
et:decimal
? - Quelles sont les caractéristiques distinctives de
:time
,:timestamp
et:datetime
?
Les nuances de ces types sont-elles documentées quelque part?
EDIT: Les points des implémentations de la plate-forme DB ne sont pas pertinents pour la question que j'essaie de poser. Si, par exemple, :datetime
n'a pas de signification définie dans la documentation de Rails, que se passe-t-il par db-adapter-writers lors du choix d'un type de colonne correspondant?
ruby-on-rails
Grant Birchmeier
la source
la source
:string
et:text
et je ne pouvais pas trouver autre chose que cela. Donc, je me demandais juste pour référence future.Réponses:
Lignes directrices fondées sur l'expérience personnelle:
serial primary key
à- dire dans PostgreSQL). Son utilisation est quelque peu compliquée et déconseillée.validates_uniqueness_of
etadd_index
avec l':unique => true
option) pour simuler la fonctionnalité de clé primaire sur l'un de vos propres champs.Ce sont les types au sujet desquels la confusion existe souvent; J'espère que ça aide. Je ne sais vraiment pas pourquoi il n'y a pas de documentation officielle à ce sujet. De plus, j'imagine que ces adaptateurs de base de données auxquels vous avez fait allusion ont été écrits par les mêmes personnes qui ont écrit Rails, donc ils n'avaient probablement pas besoin de documentation lorsqu'ils écrivaient les adaptateurs. J'espère que cela t'aides!
Remarque: la présence des deux
:DateTime
et:Timestamp
, d'après ce que je peux trouver, est incluse par Rails principalement pour la compatibilité avec les systèmes de base de données. Par exemple, le type de données de MySQL a été conservé pour une compatibilité ascendante. D'autres systèmes de bases de données ont connu des évolutions similaires. Rails a reconnu l'existence de plusieurs normes et a fourni des interfaces pour les deux. Cependant, Rails ActiveRecord utilise par défaut les deux et les dates UTC stockées dans MySql's , donc cela ne fait aucune différence fonctionnelle pour les programmeurs Rails. Celles-ci existent pour que les utilisateurs qui souhaitent différencier les deux puissent le faire. (Pour une explication plus approfondie, voir cette réponse SO).TIMESTAMP
type données est stocké sous la forme d'un horodatage unix. Sa plage valide va de 1970 à 2038, et le temps est stocké comme le nombre de secondes qui se sont écoulées depuis la dernière époque , ce qui est censé être standard, mais en pratique peut différer d'un système à l'autre. Reconnaissant que le temps relatif n'était pas une bonne chose à avoir dans les bases de données, MySQL a ensuite introduit leDATETIME
type de données, qui stocke chaque chiffre de l'année, du mois, du jour, de l'heure, de la minute et de la seconde, au prix d'une augmentation de taille. leTIMESTAMP
:Timestamp
:DateTime
DATETIME
la source
À partir du code source de la branche principale de Rails, j'ai trouvé:
résumé 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
la méthode
super
intype_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
la source