PostgreSQL : 텍스트와 varchar의 차이점 (문자 변경)


619

text데이터 형식과 character varying( varchar) 데이터 형식 의 차이점은 무엇입니까 ?

설명서 에 따르면

문자 지정이 길이 지정자없이 사용되는 경우 유형은 모든 크기의 문자열을 허용합니다. 후자는 PostgreSQL 확장입니다.

또한 PostgreSQL은 모든 길이의 문자열을 저장하는 텍스트 유형을 제공합니다. 유형 텍스트는 SQL 표준이 아니지만 다른 여러 SQL 데이터베이스 관리 시스템에도 있습니다.

차이점은 무엇입니까?

답변:


745

차이점은 없습니다. 두건 아래 모두입니다 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는 일반적으로 길이 제한에 대한 최선의 선택이라고 결론을 내립니다.


58
@axiopisty 그것은 훌륭한 기사입니다. 당신은 "아티클이 다운 될 경우를 대비하여 일부 발췌문을 끌어낼 수 있습니까?"라고 말할 수 있습니다. 기사의 내용 / 결론을 간단히 요약하려고했습니다. 이것이 귀하의 우려를 완화시키기에 충분하기를 바랍니다.
jpmc26

34
@axiopisty, 엄밀히 말하면, 초기 답변은 " 이건 모든 varlena입니다 " 라는 말이었습니다. 이 답변은 링크 전용 답변과 구별되는 유용한 정보입니다.
Bruno

24
무한한 끈으로 명심해야 할 한 가지는 남용의 가능성을 열어 준다는 것입니다. 사용자가 어떤 크기의 성을 갖도록 허용하면 성 필드에 많은 양의 정보를 저장하는 사람이있을 수 있습니다. 에서 기사 레딧의 개발에 대한, 그들은 "모든에 제한을 넣어"할 수있는 조언을 제공합니다.
Mark Hildreth

7
@MarkHildreth 그러나 요점은 일반적으로 UI에서 규칙 (및 위반 / 시도 시도)을 원활하게 처리 할 수 ​​있도록 응용 프로그램에서 일반적으로 적용되는 것입니다. 누군가가 데이터베이스에서 이런 종류의 작업을 계속하고 싶다면 제약 조건을 사용할 수 있습니다. "VARCHAR보다 유연성이 높은 필드를 작성하기 위해 TEXT 및 제한 조건을 사용하는 예"가 포함 된 blog.jonanin.com/2013/11/20/postgresql-char-varchar 를 참조하십시오 .
Ethan

4
@Ethan blog.jonanin.com/2013/11/20/postgresql-char-varchar-> 이것은 다운되었지만 여기서 archive.is/6xhA5에 있습니다.
MrR

115

"와 같은 문자 유형 의 문서 점에서"밖으로 varchar(n), char(n)그리고 text모두 같은 방식으로 저장됩니다. 유일한 차이점은 길이가 주어진 경우 길이를 확인하기 위해 추가 사이클이 필요하고 패딩이 필요한 경우 추가 공간과 시간이 필요하다는 것입니다 char(n).

그러나 단일 문자 만 저장해야하는 경우 특수 유형을 사용하면 약간의 성능 이점이 있습니다 "char"(큰 따옴표는 유형 이름의 일부 임). 필드에 더 빠르게 액세스 할 수 있으며 길이를 저장하는 오버 헤드가 없습니다.

방금 "char"소문자 알파벳에서 선택한 1,000,000 개의 무작위 테이블을 만들었습니다 . 주파수 분포 ( select count(*), field ... group by field) 를 얻는 쿼리 는 text필드를 사용하는 동일한 데이터에서 약 760 밀리 초가 걸리는 데 약 650 밀리 초가 걸립니다 .


18
기술적으로 따옴표는 유형 이름의 일부가 아닙니다. char 키워드와 구별하기 위해 필요합니다.
Jasen

31
기술적으로 당신은 @Jasen이 맞습니다 ... 물론 가장 좋은 종류입니다
JohannesH

데이터 유형 "char" 이 아닙니다 char?? 현재 PostgreSQL 11+에서 유효합니까? ... 예 : "유형 "char"(인용 부호 참고)은 1 바이트의 저장 공간 만 사용한다는 점에서 char (1)과 다릅니다. 시스템 카탈로그에서 단순한 열거 형 으로 내부적으로 사용됩니다 ." , guide / datatype-character .
피터 크라우스

63

2016 년 벤치 마크 업데이트 (pg9.5 이상)

"Pure SQL"벤치 마크 사용 (외부 스크립트없이)

  1. UTF8과 함께 string_generator를 사용하십시오.

  2. 주요 벤치 마크 :

    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 FUNCTIONvarchar(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%')


따라서 텍스트 대신 모든 열을 varchar로 만든 것보다 중요하지 않습니다. 일부는 4-5 자이고 확실히 255 자 임에도 불구하고 길이를 지정하지 않았습니다.
트렌치

1
@trench 예, 중요하지 않습니다
FuriousFolder

1
쿨, 나는 그것을 안전하기 위해 다시 작성하고 어쨌든 모든 텍스트를 만들었습니다. 그것은 잘 작동했으며 어쨌든 수백만 건의 기록을 빠르게 추가하는 것이 매우 쉬웠습니다.
트렌치

@trench and reader : 유일한 예외는 더 빠른 데이터 유형 입니다. 요즘 PostgreSQL 11 이상에서도 "char"그렇지 않습니다 char. 는 AS 가이드 / 데이터 형 문자가 말한다 "유형 "char"(인용 부호에주의)에만 저장 1 바이트를 사용하는의 문자 (1)과 다르다. 그것은 내부적으로 시스템 카탈로그에 사용되는 단순한 열거 형 ." .
피터 크라우스

3
텍스트> VARCHAR (N)> text_check> 문자 (N) : 2,019에서 PG11과 여전히 유효
올리비에 Refalo

37

PostgreSQL 매뉴얼

공백으로 채워진 유형을 사용할 때 스토리지 공간이 증가하고 길이가 제한된 컬럼에 저장할 때 길이를 확인하는 몇 가지 추가 CPU주기 외에는이 세 가지 유형간에 성능 차이가 없습니다. character (n)은 일부 다른 데이터베이스 시스템에서 성능 이점이 있지만 PostgreSQL에서는 그러한 이점이 없습니다. 실제로 character (n)은 추가 스토리지 비용으로 인해 일반적으로 3 개 중 가장 느립니다. 대부분의 상황에서 텍스트 나 문자를 다르게 사용해야합니다.

나는 보통 텍스트를 사용한다

참조 : http://www.postgresql.org/docs/current/static/datatype-character.html


23

제 생각 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 이상, 당신은 이러한 오류로부터 안전 해요.


나중에 텍스트에 대한 색인 생성을 시도하는 postgres 오류는 varchar ((n)이없는 버전)에서만 작동합니다. 그러나 내장 된 postgres로만 테스트되었습니다.
arntg

2
참조 : PostgreSQL Wiki에 대한 링크가있는 stackoverflow.com/questions/39965834/… : wiki.postgresql.org/wiki/… 최대 행 크기는 400GB로, 행당 명시된 2712 바이트 제한이 잘못된 것 같습니다. . 데이터베이스의 최대 크기? 무제한 (32TB 데이터베이스가 존재 함) 테이블의 최대 크기? 32TB 행의 최대 크기? 400GB 필드의 최대 크기? 1GB 테이블의 최대 행 수? 무제한
Bill Worthington

@BillWorthington 게시 한 숫자는 색인을 넣는 것을 고려하지 않습니다. 2712 바이트는 btree의 최대 한계에 관한 것으로, 문서에서 찾을 수 없도록 구현 세부 사항입니다. 그러나 쉽게 테스트 할 수 있습니다. 예를 들어 "postgresql 인덱스 행 크기가 최대 인덱스 2712를 초과합니다"를 검색하여 Google에서 쉽게 검색 할 수 있습니다.
sotn

저는 PostgeSQL을 처음 사용하므로 전문가가 아닙니다. 뉴스 기사를 테이블의 열에 저장하려는 프로젝트를 진행 중입니다. 텍스트 열 유형이 내가 사용할 것 같습니다. 2712 바이트의 총 행 크기는 Oracle과 같은 수준에 가까운 데이터베이스에 비해 너무 작게 들립니다. 큰 텍스트 필드의 색인을 생성한다는 것을 올바르게 이해하고 있습니까? 당신에게 도전하거나 논쟁하려고하지 않고, 실제 한계를 이해하려고 노력하십시오. 관련된 인덱스가 없다면 위키에서와 같이 행 제한이 400GB입니까? 빠른 답변 감사합니다.
Bill Worthington

1
@BillWorthington 전체 텍스트 검색에 대해 조사해야합니다. 확인 이 링크의
sotn

18

text와 varchar는 암시 적 유형 변환이 다릅니다. 내가 주목 한 가장 큰 영향은 후행 공백을 처리하는 것입니다. 예를 들어 ...

select ' '::char = ' '::varchar, ' '::char = ' '::text, ' '::varchar = ' '::text

예상대로 반환 true, false, true하지 않습니다 true, true, true.


이것이 어떻게 가능한지? a = b이고 a = c이면 b = c입니다.
Lucas Silva

4

다소 OT : Rails를 사용하는 경우 웹 페이지의 표준 형식이 다를 수 있습니다. 데이터 입력 양식의 경우 text상자를 스크롤 할 수 있지만 character varying(레일 string) 상자는 한 줄입니다. 보기 조회수는 필요한 시간입니다.


2

http://www.sqlines.com/postgresql/datatypes/text 에서 좋은 설명 :

TEXT와 VARCHAR (n)의 유일한 차이점은 VARCHAR 열의 최대 길이를 제한 할 수 있다는 것입니다. 예를 들어 VARCHAR (255)는 255자를 초과하는 문자열을 삽입 할 수 없습니다.

TEXT와 VARCHAR은 모두 1Gb의 상한을 가지며 PostgreSQL 설명서에 따라 성능 차이가 없습니다.


-1

character varying(n), varchar(n)-(모두 동일). 오류가 발생하지 않고 값이 n 자로 잘립니다.

character(n), char(n)-(모두 동일). 고정 길이이며 길이가 끝날 때까지 공백으로 채 웁니다.

text-무제한 길이.

예:

Table test:
   a character(7)
   b varchar(7)

insert "ok    " to a
insert "ok    " to b

결과를 얻습니다.

a        | (a)char_length | b     | (b)char_length
----------+----------------+-------+----------------
"ok     "| 7              | "ok"  | 2

5
값이 열 크기를 초과하면 MySQL이 자동으로 데이터를 자르지 만 PostgreSQL은 "type character varying (n)"오류에 대해 너무 긴 값을 발생시키지 않습니다.
gsiems
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.