[ruby-on-rails] Rails 열 유형에 대한 설명서가 있습니까?
이 페이지에 있는 간단한 유형 목록보다 더 많은 것을 찾고 있습니다 .
: primary_key, : string, : text, : integer, : float, : decimal, : datetime, : timestamp, : time, : date, : binary, : boolean
그러나 실제로 이러한 필드를 정의 하는 문서가 있습니까?
구체적으로 특별히:
- 차이 무엇
:string
과:text
? - 사이
:float
와:decimal
? - 의 구별 특징은 무엇입니까
:time
,:timestamp
그리고는:datetime
?
이러한 유형의 뉘앙스는 어디에나 문서화되어 있습니까?
편집 : DB 플랫폼 구현의 요점은 내가 묻고 자하는 질문과 관련이 없습니다. 예를 들어 :datetime
Rails 문서에 의도 된 의미가 없다면, 해당 컬럼 유형을 선택할 때 db-adapter-writer는 무엇을 수행합니까?
답변
개인적인 경험을 바탕으로 작성된 지침 :
- 문자열 :
- 255 자로 제한됨 (DBMS에 따라 다름)
- 짧은 텍스트 필드 (이름, 이메일 등)에 사용
- 텍스트 :
- 무제한 길이 (DBMS에 따라 다름)
- 댓글, 블로그 게시물 등에 사용합니다. 일반적인 경험 법칙 : 텍스트 영역을 통해 캡처 된 경우 텍스트를 사용하십시오. 텍스트 필드를 사용하여 입력하려면 문자열을 사용하십시오.
- 정수 :
- 정수
- 플로트 :
- 부동 소수점 정밀도로 저장된 10 진수
- 정밀도는 고정되어 일부 계산에 문제가 될 수 있습니다. 일반적으로 부정확 한 반올림으로 인해 수학 연산에 적합하지 않습니다.
- 십진법 :
- 계산에 필요한 것에 따라 달라지는 정밀도로 저장된 10 진수; 정확한 수학에 사용하십시오
- 부동 소수점과 소수의 차이점에 대한 예와 자세한 설명은 이 게시물을 참조하십시오 .
- 부울 :
- true / false 속성을 저장하는 데 사용합니다 (예 : on / off와 같이 두 가지 상태 만있는 것).
- 이진 :
- 이미지, 동영상 및 기타 파일을 원래의 원시 형식으로 Blob 이라는 데이터 덩어리에 저장하는 데 사용
- : primary_key
- 이 데이터 유형은 Rails가 선택한 데이터베이스에 필요한 기본 키 데이터 유형 (예 :
serial primary key
postgreSQL)으로 변환하는 자리 표시 자입니다 . 사용은 다소 복잡하므로 권장하지 않습니다. - 자신의 필드 중 하나에서 기본 키 기능을 시뮬레이션 하려면 모델 및 마이그레이션 제약 조건 (예 : 옵션
validates_uniqueness_of
과add_index
함께:unique => true
)을 사용하십시오.
- 이 데이터 유형은 Rails가 선택한 데이터베이스에 필요한 기본 키 데이터 유형 (예 :
- 날짜 :
- 날짜 만 저장 (년, 월, 일)
- 시간 :
- 시간 (시간, 분, 초) 만 저장
- 날짜 시간 :
- 날짜와 시간을 모두 저장
- 타임 스탬프
- 날짜와 시간을 모두 저장
- 참고 : Rails의 목적 상 Timestamp와 DateTime은 모두 같은 의미입니다 (날짜와 시간을 모두 저장하려면 두 유형 중 하나를 사용하십시오). 둘 다 존재하는 이유에 대한 TL; DR 설명은 맨 아래 단락을 읽으십시오.
이것들은 종종 혼란이 존재하는 유형입니다. 이게 도움이 되길 바란다. 나는 왜 이것들에 대한 공식적인 문서가 없는지 모른다. 또한 언급 한 데이터베이스 어댑터가 Rails를 작성한 사람과 동일한 사람들이 작성했다고 생각하므로 어댑터를 작성할 때 설명서가 필요하지 않을 것입니다. 도움이 되었기를 바랍니다!
참고 : :DateTime
및 :Timestamp
에서 찾을 수있는 것의 대부분은 데이터베이스 시스템과의 호환성을 위해 Rails에 포함되어 있습니다. 예를 들어, MySQL의 TIMESTAMP
데이터 유형은 유닉스 타임 스탬프로 저장됩니다. 유효 범위는 1970 년에서 2038 년 사이이며, 시간은 마지막 epoch 이후에 경과 한 시간 (초)으로 저장됩니다. 표준으로 가정되지만 실제로는 시스템마다 다를 수 있습니다. MySQL은 데이터베이스에서 상대적 시간이 좋지 않다는 것을 인식하고 나중에 DATETIME
데이터 유형을 도입했습니다.이 데이터 유형은 1 년, 월, 일,시, 분 및 초의 모든 숫자를 크기 증가 비용으로 저장합니다. 그만큼TIMESTAMP
이전 버전과의 호환성을 위해 데이터 유형이 유지되었습니다. 다른 데이터베이스 시스템도 비슷한 발전을 거쳤습니다. Rails는 여러 표준이 존재 함을 인식하고 두 인터페이스를 모두 제공했습니다. 그러나 Rails ActiveRecord 는 MySql ‘s에 저장된 UTC 날짜 :Timestamp
와 :DateTime
UTC 날짜를 기본값으로 사용 DATETIME
하므로 Rails 프로그래머와 기능적으로 차이가 없습니다. 이것들 은 두 가지를 구별 하려는 사용자가 그렇게 할 수 있도록 존재합니다 . (자세한 설명은 이 SO 답변을 참조하십시오 ).
답변
Rails 마스터 브랜치 소스 코드에서 다음을 발견했습니다.
#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