MySQL : 큰 VARCHAR 대 텍스트?


845

MySQL 사이에 사용자 간 메시지를 기록하는 메시지 테이블이 있습니다. 일반적인 ID 및 메시지 유형 (모든 정수 유형) 외에도 실제 메시지 텍스트를 VARCHAR 또는 TEXT로 저장해야합니다. 프런트 엔드 제한을 3000 자로 설정하여 메시지가이 길이보다 오래 db에 삽입되지 않음을 의미합니다.

VARCHAR (3000) 또는 TEXT와 관련하여 근거가 있습니까? VARCHAR (3000)을 작성하는 것에는 다소 반 직관적 인 느낌이 듭니다. Stack Overflow에서 다른 유사한 게시물을 겪었지만이 유형의 일반적인 메시지 저장과 관련된보기를 얻는 것이 좋습니다.


27
조금 낡았지만 여기에 대해 생각하게 만드는 문제가 생겨서 여기에 왔습니다. 필자의 경우 프론트 엔드 양식은 2,000 자로 제한되었지만 내 저장 방법에 암시적인 인코딩은 국제 문자를 여러 문자로 인코딩했습니다 (문자 당 3-12까지 가능). 그래서 내 2,000은 갑자기 최대 24,000이됩니다. 생각해 볼 점 ...
James S

3
많은 동시 삽입에서 텍스트가 훨씬 더 빠릅니다.
Ray S.

1
@JamesS : utf8mb4 ...>. <
불가분 한

10
@RickJames는 질문을 닫기보다는 업데이트 된 답변을 게시하는 것을 고려합니다
Yvette

3
@YvetteColomb-답변을 추가했습니다. 수락 된 답변 이 오래되어서 주로 제거하고 싶습니다 . 누군가가 잘못된 정보를 인용하여 "754 upvotes, 옳 아야합니다."라고 말하면서 Q & A에 왔습니다. 확인 응답도 편집했습니다. (그렇지만 부적절한 느낌입니다.)
Rick James

답변:


811
  • TEXT하고 BLOB 있다 하여 테이블은 단지 실제 저장 영역의 위치에 대한 포인터를 갖는 테이블 떨어져 저장된다. 저장되는 위치는 데이터 크기, 열 크기, row_format 및 MySQL 버전과 같은 많은 요소에 따라 다릅니다.

  • VARCHAR테이블과 함께 인라인으로 저장됩니다. VARCHAR크기가 합리적 일 때 더 빠르며, 그와의 상충 관계는 데이터와 하드웨어에 따라 다르므로 데이터와 실제 시나리오를 벤치마킹하고 싶을 것입니다.


148
+1 : VARCHAR (인라인으로 저장)은 데이터가 자주 검색되는 경우 (대부분의 쿼리에 포함됨) 더 빠릅니다. 그러나 일반적으로 검색되지 않는 (즉, 쿼리에서 참조하지 않는) 대량의 데이터의 경우 데이터를 인라인으로 저장하지 않는 것이 좋습니다. 인라인으로 저장된 데이터의 경우 행 크기에는 상한이 있습니다.
spencer7593

21
@Pacerier : "인라인"스토리지를 피함으로써 얻을 수있는 정확한 이점은 블록에 저장할 수있는 행 수가 증가한다는 것입니다. 즉, 테이블 행은 InnoDB 버퍼 캐시에서 더 적은 수의 블록을 차지하고 (더 작은 메모리 공간) 더 적은 수를 의미합니다 디스크와주고받을 블록 (감소 된 I / O). 그러나 "off row"로 저장된 열이 쿼리에서 대부분 참조되지 않는 경우에만 성능상의 이점입니다. 이러한 "행 외부"열이 대부분의 쿼리에서 참조되는 경우 큰 이점이 있습니다. 열이 최대 행 크기에 맞고 자주 참조되는 경우 인라인이 선호됩니다.
spencer7593

231
"크기가 적당하면 VARCHAR이 더 빠릅니다". "합리적인"문자 수는 100입니까? 1000? 100,000?
팀 피터슨

125
이 답변은 InnoDB에 맞지 않습니다. 주어진 행의 값이 페이지 크기에 맞는 경우 VARCHAR 및 BLOB / TEXT는 다른 열과 함께 인라인으로 저장됩니다 (16KB 및 각 페이지는 최소한 두 개의 행을 보유해야 함). 문자열이 너무 크면 추가 페이지로 넘칩니다. 자세한 설명 은 mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb 를 참조하십시오 .
Bill Karwin

14
@ BillKarwin ... 올바르게 이해한다면 작은 텍스트 항목에 대해 InnoDB varcharblob/ 사이에 성능 차이가 없어야 text합니까? 그래서 그럼 그냥 모든 있도록 현명 할 유형과 DB가 인라인 대 오버 플로우를 관리 할 수? varchartext
ryvantage

473

사용자 입력 시간을 예측할 수 있습니까?

바차 (X)

사례 : 사용자 이름, 이메일, 국가, 제목, 비밀번호


본문

사례 : 메시지, 이메일, 댓글, 형식이 지정된 텍스트, HTML, 코드, 이미지, 링크


중간 텍스트

사례 : 큰 JSON 본문, 중소형 도서, CSV 문자열


긴 텍스트

사례 : 교과서, 프로그램, 수년간의 로그 파일, 해리 포터 및 불의 잔, 과학 연구 로깅


7
예측 성은 실제로 부수적 인 항목입니다. 실제로 최대 예상 길이가 결정 요인이되어야합니다. 더 예측 가능하다고 언급 한 항목은 다른 항목 보다 짧기 때문에 그러한 방식 일뿐입니다 .
Andrew Barber

29
@ andrew-barber 그것은 내 요점입니다. 다른 모든 게시물은 차이점에 대해 잘 설명하지만 실제로 두 가지 중에서 선택해야 할 상황에 대해서는 설명하지 않습니다. varchar를 사용하여 짧게 예측하는 것이 좋으며 텍스트를 임의로 길게 사용하는 것이 좋습니다.
마이클 J. 칼 킨스

1
모든 열이 짧고 예측 가능하면 (예 : MAC 주소, IMEI 등은 절대 변하지 않는 것) CHAR 열을 사용하고 행 크기를 고정 할 수 있으므로 MyISAM을 사용하는 경우 속도가 상당히 빨라질 수 있습니다. 나는 확실하지 않지만 InnoDb.
Matt

1
@ MichaelJ.Calkins MySQL 5.6에서 일어난 일. 이제 InnoDB에서도 전체 텍스트 검색이 가능합니다. 참조 dev.mysql.com/doc/refman/5.6/en/fulltext-search.html
PhoneixS

7
글자 수 제한 : TINYTEXT : 255; 텍스트 : 65,535; 중간체 : 16,777,215; 긴 텍스트 : 4,294,967,29.
빅토르 스토 다드

218

모범 사례를 명확히하기 위해 :

  1. 텍스트 형식 메시지는 거의 항상 TEXT로 저장해야합니다 (임의로 길다).

  2. 문자열 속성은 VARCHAR (대상 사용자 이름, 주제 등)로 저장해야합니다.

프런트 엔드 한도가 있으며, 그렇지 않을 때까지는 좋습니다. * grin * 트릭은 DB를 연결된 애플리케이션과 분리 된 것으로 생각하는 것입니다. 한 응용 프로그램이 데이터를 제한한다고해서 데이터가 본질적으로 제한되어있는 것은 아닙니다.

메시지 자체가 3000자를 넘지 않도록하는 것은 무엇입니까? 임의의 응용 프로그램 제약 조건 (예 : 텍스트 상자 등) 인 경우 TEXT데이터 영역에서 필드를 사용하십시오 .


"그렇지 않을 때까지 좋은"은 무엇을 의미합니까? "없다"는 무엇을 의미합니까?
Pacerier

7
@Pacerier James가 "그렇지 않은"예를 들자면 다음과 같습니다. Twitter를 예로 들어 보겠습니다. 최근 트위터에서 PM에 140 자 제한이있었습니다. 그들은 더 이상 현명하지 않다고 판단하고 그 한계를 완전히 제거하기로 결정했습니다. 그들이 그것에 대해 미리 생각하지 않았다면 (아마도 아마 그렇게했을 것입니다 ...) 그들은 위에서 설명한 시나리오를 시작했을 것입니다.
PaulSkinner

9
나는 단지 새로운 데이터베이스를 설치하고 있으며, 아무도 우리의 작은 주석 상자에 2000 자 이상을 넣을 수 없다고 가정했다. 그리고 제임스가 지적한 것처럼 오늘 밤 사용자가 2600 자 길이의 매우 유효한 주석입니다. varchar (2000)을 사용하여 그보다 길어질 수 있다고 생각했는데 잘못되었습니다. 그렇습니다. 그렇지 않을 때까지 훌륭합니다. 우리의 경우에는 며칠 밖에 걸리지 않았습니다. 마이클 J. 칼 킨스, 아래 규칙은 이제부터 사용하겠습니다. 메시지 텍스트, 설명.
Lizardx

1
@Pacerier "좋지 않을 때까지 훌륭합니다". 다시 말해서, 그것은 거의 항상 작동하며 훌륭합니다 ... 매우 좋지 않은 예외적 인 상황을 제외하고.
제한 속죄

@Pacerier 또 다른 흥미로운 예가 선택된 답변의 의견에 언급되어 있습니다. 기본적으로 2,000 문자의 프런트 엔드 제한이 있었지만 도입 된 문자는 실제로 일반 문자보다 더 많은 바이트를 사용하는 코드 페이지에 있었고 데이터베이스에는 공간이 필요했습니다. 그가 소개되는 문자의 실제 바이트 크기를 설명해야했기 때문에 24k 문자.
RaptorX

32

면책 조항 : 나는 MySQL 전문가가 아니지만 ...이 문제에 대한 나의 이해입니다.

TEXT는 mysql 행 외부에 저장되어 있지만 VARCHAR은 행의 일부로 저장되어 있다고 생각합니다. mysql 행의 최대 행 길이가 있습니다. 따라서 VARCHAR을 사용하여 행에 저장할 수있는 다른 데이터의 양을 제한 할 수 있습니다.

또한 VARCHAR이 행의 일부를 형성하기 때문에 해당 필드를 보는 쿼리가 TEXT 청크를 사용하는 쿼리보다 약간 빠를 것이라고 생각합니다.


38
행 길이 제한은 65,535 바이트입니다 [ dev.mysql.com/doc/refman/5.0/en/column-count-limit.html ]. 열이 utf8로 인코딩 된 경우 3000 자 varchar열이 최대 9000 바이트를 차지할 수 있습니다.
Jan Fabry

7
UTF-8 문자는 최대 4 바이트가 될 수 있으므로 12,000 바이트를 의미한다고 생각합니다 (여기에서 이해하지 못하는 MySQL이 없다면).
raylu

13
@raylu MySQL의 UTF-8은 문자 당 최대 3 바이트 만 지원한다는 점에서 "가짜 UTF-8"이므로 MySQL의 UTF-8에서 BMP 평면 이외의 유니 코드 문자를 직접 저장할 수있는 방법이 없습니다. 이것은 MySQL 5.5에서 수정되었습니다.
Pacerier

2
이 주장은 MyISAM에만 유효하다고 생각합니다. 나는 확실한 소스를 찾을 수 없지만 InnoDB는 TEXT테이블에 인라인으로 저장한다고 생각합니다 .
dotancohen

2
@dotancohen 나는 InnoDB를 사용하여 가변 길이 데이터를 저장하면 (외부 또는 인라인으로 저장할 수 있음) mysqlserverteam.com/externally-stored-in-innodb
KiX Ortillan

30

짧은 대답 : 실제, 성능 또는 스토리지 차이가 ​​없습니다.

긴 대답 :

본질적으로 VARCHAR(3000)(와 다른 큰 한계)와 ( MySQL에서) 차이는 없습니다 TEXT. 전자는 3000 에서 잘립니다 . 후자는 65535 바이트 에서 잘립니다. . ( 문자가 여러 바이트를 취할 수 있기 때문에 바이트문자를 구별 합니다.)

의 한계가 작을수록 VARCHAR몇 가지 장점이 TEXT있습니다.

  • "작게"는 버전, 컨텍스트 및에 따라 191, 255, 512, 767 또는 3072 등을 의미 CHARACTER SET합니다.
  • INDEXes열을 색인 할 수있는 크기가 제한됩니다. (767 또는 3072 바이트 ; 버전 및 설정에 따라 다름)
  • 컴플렉스에서 생성 된 중간 테이블 SELECTs은 MEMORY (빠른) 또는 MyISAM (느린)의 두 가지 방식으로 처리됩니다. '큰'열이 관련되면 느린 기술이 자동으로 선택됩니다. (버전 8.0에서는 중요한 변경 사항이 있으므로이 글 머리 기호 항목은 변경 될 수 있습니다.)
  • 이전 항목과 관련하여 모든 TEXT데이터 유형 (과 반대로 VARCHAR)은 MyISAM으로 바로 이동합니다. 즉, TINYTEXT생성 된 임시 테이블의 경우 해당 테이블보다 자동으로 더 나쁩니다 VARCHAR. (그러나 이것은 세 번째 방향으로 토론을합니다!)
  • VARBINARY같다 VARCHAR; BLOB같다 TEXT.

다른 답변에 대한 반박

원래의 질문은 한 가지 (사용할 데이터 유형)를 물었습니다. 허용 된 답변은 다른 것 (비 레코드 저장)에 대답했습니다. 그 대답은 이제 구식입니다.

이 스레드가 시작 되고 응답 되었을 때 InnoDB에는 두 개의 "행 형식"만있었습니다. 빨리 이후에, 두 개 더 형식 ( DYNAMICCOMPRESSED )이 추가되었습니다.

의 저장 위치 TEXT와는 VARCHAR()기반으로 크기 여부에, 데이터 형의 이름 . 큰 텍스트 / 블럼 열의 온 / 오프 레코드 저장에 대한 업데이트 된 설명은 내용을 참조 하십시오 .


1
여기에 좋은 통찰력이 있습니다. 이것이 정답입니다.
코스타 콘 토스

2
@ KostaKontos-칭찬과 오타 수정 주셔서 감사합니다. 더 나은 답변이 필요한 경우 8 년 800 년이 너무 늦게 답변하더라도 답변을 추가하겠습니다.
Rick James

7

위의 답변은 주요 문제를 충분히 주장하지 않습니다.

(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) 

임시 테이블이 필요할 수 있으며 VARCHAR필드가 관련된 CHAR경우 임시 테이블 의 필드 로 변환됩니다 . 따라서 테이블에 VARCHAR(65000)필드 가있는 500,000 줄이라고 말하면 이 열만 6.5 * 5 * 10 ^ 9를 사용합니다 바이트를 사용합니다. 이러한 임시 테이블은 메모리에서 처리 할 수 ​​없으며 디스크에 기록됩니다. 그 영향은 치명적일 수 있습니다.

(메트릭) 자료 : https://nicj.net/mysql-text-vs-varchar-performance/ (이 취급을 말한다 TEXTVARCHAR"표준"()의 MyISAM 스토리지 엔진에 그것은 다른 사람과 다를 수 있습니다,?. 예 : InnoDB)


3
InnoDB : 버전 5.7에도 동일하게 적용됩니다. 8.0에서 varchar temps는 가변 길이입니다.
Rick James

3

VARCHAR과 TEXT 사이 에는 차이가 있습니다. VARCHAR 필드는 색인화 될 수 있지만 TEXT 필드는 색인화 할 수 없습니다. VARCHAR 유형 필드는 인라인으로 저장되는 반면 TEXT는 오프라인으로 저장되며 TEXT 데이터에 대한 포인터 만 실제로 레코드에 저장됩니다.

VARCHAR보다 더 빠른 검색을 위해 필드를 색인화해야하는 경우, VARCHAR보다 아무리 크더라도 업데이트 또는 삭제하십시오. VARCHAR (10000000)은이 두 데이터 유형이 본질적으로 다르기 때문에 TEXT 필드와 절대 동일하지 않습니다.

  • 보관 용도로만 필드를 사용하는 경우
  • 데이터 속도 검색에 신경 쓰지 않습니다
  • 속도에 관심이 있지만 검색어에 연산자 '% LIKE %'를 사용하므로 색인 생성에 큰 도움이되지 않습니다.
  • 데이터 길이의 한계를 예측할 수 없습니다

TEXT보다


부분적으로 잘못된 정보 : TEXT 열은 전체적으로 색인을 생성 할 수 없습니다. 색인에 TEXT 컬럼을 포함시킬 때 길이를 지정해야합니다. 또한 인덱스 크기에 최대 길이가 있으므로 VARCHAR> 255의 경우 VARCHAR을 전체적으로 인덱스 할 수 없습니다.
eRadical

2

Varchar는 전자 메일 주소와 같은 작은 데이터를위한 것이고 Text는 뉴스 기사와 같은 훨씬 큰 데이터를위한 것이고 Blob은 이미지와 같은 이진 데이터를위한 것입니다.

Varchar의 성능은 메모리에서 완전히 실행되기 때문에 더 강력하지만, varchar(4000)예를 들어 데이터가 너무 큰 경우에는 그렇지 않습니다 .

반면에 텍스트는 메모리에 고정되지 않으며 디스크 성능의 영향을 받지만 별도의 테이블에서 텍스트 데이터를 분리하고 왼쪽 조인 쿼리를 적용하여 텍스트 데이터를 검색하면이를 피할 수 있습니다.

Blob은 훨씬 느리므로 10000 개의 이미지와 같이 10000 개의 레코드가 필요한 데이터가 많지 않은 경우에만 사용하십시오.

최대 속도와 성능을 얻으려면 다음 팁을 따르십시오.

  1. 이름, 제목, 이메일에 varchar 사용

  2. 대용량 데이터에 텍스트 사용

  3. 다른 테이블에서 별도의 텍스트

  4. 전화 번호와 같은 ID에서 왼쪽 조인 쿼리 사용

  5. Blob을 사용하려는 경우 텍스트와 동일한 팁을 적용하십시오.

이렇게하면 데이터가> 10 M이고 크기가 최대 10GB 인 테이블에서 쿼리 비용이 밀리 초가됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.