text
데이터 형식과 character varying
( varchar
) 데이터 형식 의 차이점은 무엇입니까 ?
설명서 에 따르면
문자 지정이 길이 지정자없이 사용되는 경우 유형은 모든 크기의 문자열을 허용합니다. 후자는 PostgreSQL 확장입니다.
과
또한 PostgreSQL은 모든 길이의 문자열을 저장하는 텍스트 유형을 제공합니다. 유형 텍스트는 SQL 표준이 아니지만 다른 여러 SQL 데이터베이스 관리 시스템에도 있습니다.
차이점은 무엇입니까?
답변
차이점은 없습니다. 두건 아래 모두입니다 varlena
( 가변 길이 배열 ).
Depesz에서이 기사를 확인하십시오 : http://www.depesz.com/index.php/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/
몇 가지 주요 사항 :
요약하면 다음과 같습니다.
- char (n) –보다 짧은 값을 처리 할 때 공간을 너무 많이 차지하고
n
( 값을 채움n
) 후행 공백을 추가하여 미묘한 오류가 발생할 수 있으며 한계를 변경하는 데 문제가 있습니다- varchar (n) – 실제 환경에서 제한을 변경하는 데 문제가 있습니다 (테이블을 변경하는 동안 독점 잠금이 필요함)
- varchar – 텍스트처럼
- text – 나에게는 승자 – 문제가 없기 때문에 n 개 이상의 데이터 유형, 그리고 varchar – 별개의 이름이 있기 때문에
이 기사에서는 4 가지 데이터 유형 모두에 대한 인서트 및 선택의 성능이 유사하다는 것을 보여주기 위해 자세한 테스트를 수행합니다. 또한 필요할 때 길이를 제한하는 다른 방법을 자세히 살펴 봅니다. 함수 기반 제약 조건 또는 도메인은 길이 제약 조건을 즉시 증가시킬 수있는 이점을 제공하며 문자열 길이 제약 조건을 줄이는 것이 드물다는 점을 고려할 때 depesz는 일반적으로 길이 제한에 대한 최선의 선택이라고 결론을 내립니다.
답변
“와 같은 문자 유형 의 문서 점에서”밖으로 varchar(n)
, char(n)
그리고 text
모두 같은 방식으로 저장됩니다. 유일한 차이점은 길이가 주어진 경우 길이를 확인하기 위해 추가 사이클이 필요하고 패딩이 필요한 경우 추가 공간과 시간이 필요하다는 것입니다 char(n)
.
그러나 단일 문자 만 저장해야하는 경우 특수 유형을 사용하면 약간의 성능 이점이 있습니다 "char"
(큰 따옴표는 유형 이름의 일부 임). 필드에 더 빠르게 액세스 할 수 있으며 길이를 저장하는 오버 헤드가 없습니다.
방금 "char"
소문자 알파벳에서 선택한 1,000,000 개의 무작위 테이블을 만들었습니다 . 주파수 분포 ( select count(*), field ... group by field
) 를 얻는 쿼리 는 text
필드를 사용하는 동일한 데이터에서 약 760 밀리 초가 걸리는 데 약 650 밀리 초가 걸립니다 .
답변
2016 년 벤치 마크 업데이트 (pg9.5 이상)
“Pure SQL”벤치 마크 사용 (외부 스크립트없이)
-
UTF8과 함께 string_generator를 사용하십시오.
-
주요 벤치 마크 :
2.1. 끼워 넣다
2.2. 비교 및 계산 선택
CREATE FUNCTION string_generator(int DEFAULT 20,int DEFAULT 10) RETURNS text AS $f$
SELECT array_to_string( array_agg(
substring(md5(random()::text),1,$1)||chr( 9824 + (random()*10)::int )
), ' ' ) as s
FROM generate_series(1, $2) i(x);
$f$ LANGUAGE SQL IMMUTABLE;
특정 시험 준비 (예)
DROP TABLE IF EXISTS test;
-- CREATE TABLE test ( f varchar(500));
-- CREATE TABLE test ( f text);
CREATE TABLE test ( f text CHECK(char_length(f)<=500) );
기본 테스트를 수행하십시오.
INSERT INTO test
SELECT string_generator(20+(random()*(i%11))::int)
FROM generate_series(1, 99000) t(i);
그리고 다른 테스트들
CREATE INDEX q on test (f);
SELECT count(*) FROM (
SELECT substring(f,1,1) || f FROM test WHERE f<'a0' ORDER BY 1 LIMIT 80000
) t;
… 그리고 사용하십시오 EXPLAIN ANALYZE
.
다시 업데이트 2018 (pg10)
2018 년 결과를 추가하고 권장 사항을 강화하기 위해 약간의 편집.
2016 년 및 2018 년 결과
평균적으로 많은 기계와 많은 테스트에서 내 결과는 모두 동일합니다
(통계적으로 적은 표준 편차).
추천
-
사용
text
, 데이터 유형을
세 않도록varchar(x)
때때로 표준, 예를 들어 있지 않기 때문에CREATE FUNCTION
절varchar(x)
≠varchar(y)
. -
(같은과 한계를 표현
varchar
성능!)에 의해CHECK
에 절CREATE TABLE
예를CHECK(char_length(x)<=10)
.
당신은 또한 할 수있는 제어 범위와 문자열 구조에 INSERT / UPDATE의 성능을 무시할 손실
예CHECK(char_length(x)>5 AND char_length(x)<=20 AND x LIKE 'Hello%')
답변
PostgreSQL 매뉴얼
공백으로 채워진 유형을 사용할 때 스토리지 공간이 증가하고 길이가 제한된 컬럼에 저장할 때 길이를 확인하는 몇 가지 추가 CPU주기 외에는이 세 가지 유형간에 성능 차이가 없습니다. character (n)은 일부 다른 데이터베이스 시스템에서 성능 이점이 있지만 PostgreSQL에서는 그러한 이점이 없습니다. 실제로 character (n)은 추가 스토리지 비용으로 인해 일반적으로 3 개 중 가장 느립니다. 대부분의 상황에서 텍스트 나 문자를 다르게 사용해야합니다.
나는 보통 텍스트를 사용한다
참조 : http://www.postgresql.org/docs/current/static/datatype-character.html
답변
제 생각 varchar(n)
에는 자체 장점이 있습니다. 예, 그들은 모두 동일한 기본 유형을 사용합니다. 그러나 PostgreSQL의 인덱스 는 행 당 2712 바이트 의 크기 제한이 있음을 지적해야합니다 .
TL; DR : 제약 조건없이text
유형
을 사용 하고 이러한 열에 색인이있는 경우 일부 열에 대해이 한계에 도달하고 데이터를 삽입하려고 할 때 오류가 발생하지만을 사용 하면이를 방지 할 수 있습니다.varchar(n)
자세한 내용 은 여기에서 문제는 PostgreSQL이 text
유형에 대한 인덱스를 만들 때 또는 2712보다 큰 varchar(n)
위치에 대한 예외를 제공하지 않는다는 n
것입니다. 그러나 압축 크기가 2712보다 큰 레코드를 삽입하려고하면 오류가 발생합니다. 이는 2712 이하로 압축되기 때문에 반복 문자로 쉽게 구성된 100.000 문자의 문자열을 삽입 할 수 있지만 압축 된 크기가 2712 바이트보다 커서 4000 문자로 일부 문자열을 삽입하지 못할 수 있습니다. 사용하는 varchar(n)
곳 n
없는 너무 많은 2,712 이상, 당신은 이러한 오류로부터 안전 해요.
답변
text와 varchar는 암시 적 유형 변환이 다릅니다. 내가 주목 한 가장 큰 영향은 후행 공백을 처리하는 것입니다. 예를 들어 …
select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text
예상대로 반환 true, false, true
하지 않습니다 true, true, true
.
답변
다소 OT : Rails를 사용하는 경우 웹 페이지의 표준 형식이 다를 수 있습니다. 데이터 입력 양식의 경우 text
상자를 스크롤 할 수 있지만 character varying
(레일 string
) 상자는 한 줄입니다. 보기 조회수는 필요한 시간입니다.
