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


따라서 텍스트 대신 모든 열을 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.