[DB] VARCHAR(191) vs VARCHAR(255)

임동혁 Ldhbenecia·2023년 11월 20일
0

DataBase

목록 보기
2/14
post-thumbnail

[DB] Prisma에서 String VARCHAR 길이는 어째서 VARCHAR(191)일까?

최근 프로젝트를 진행하며 ERD를 설계하는 것에 어려움을 느끼고 있습니다.
ERD를 설계해본 경험도, 아직 데이터베이스에 대한 지식이 없어서 학습하며 궁금했던 내용을 학습하고 정리합니다.

이거 왜 기본 값이 VARCHAR(191)이야?

멘토어님에게 ERD에 대한 피드백을 요청했고 첫 번째로 온 질문은 이 질문이었습니다.
현재 NestJS를 사용하며 ORM으로 Prisma를 사용하여 개발을 진행하고 있습니다.

Prisma에서는 스키마 모델링을 하고 생성된 sql을 보면 전부 아래와 같이 기본 길이가 191로 저장됩니다.

왜 이럴까에 대해서 생각을 해보고 구글에 prisma VARCHAR 191이라는 코멘트로 검색을 해보았습니다.
역시나 Prisma에서 누군가 올린 질문이 있었고 해당 질문 속에 있는 답변을 통해 이유를 알 수 있었습니다.


해당 외국 포럼에 적힌 글을 발췌하여 번역하였습니다.

255는 191보다 훨씬 더 의미가 있습니다. 그리하면 어떻게 191에 도달하게 되었나요? 이모티콘으로 시작해보도록 하겠습니다. 😜. 첫 번째 이모티콘을 포함하는 문자 집합인 utf8mb4가 있었습니다.
2000년대 초반의 MySQL은 VARCHAR 열에서 255자를 지원하고 색인을 생성하는 데 만족했습니다. 
그러나 가장 널리 사용되는 MySQL 데이터베이스 엔진(innodb)에서 가장 널리 사용되는 텍스트 인코딩(라틴1 또는 utf8)은 모든 문자 2를 저장하는 데 3바이트가 충분하다고 가정했으며, utf8mb4가 한자 및 🐟와 같은 문자가 등장하자 각 문자를 저장하는 데 4바이트가 필요했습니다. 선택할 수 있는 문자가 더 많았으므로 이를 참조하는 데 더 많은 바이트가 필요했습니다.

MySQL 데이터베이스가 작동하는 방식은 innodb인덱스에 대해 767바이트만 가질 수 있다는 것입니다. 이는 255개의 3바이트 문자( 767/3 = 255)를 저장하기에 충분합니다. 
이는 인덱싱하는 데이터의 크기를 아는 것을 기반으로 한 인덱스 최적화의 극단적인 예입니다! 
따라서 문자를 저장하는 데 더 많은 공간이 필요하다면 색인화할 수 있는 문자 수는 더 적어져야 합니다. 
구체적으로는 767/4 = 191 입니다.

이 부분에 대해서 아래에서 한번 더 다루도록 하겠습니다.

더 많은 소프트웨어가 전 세계 고객을 지원함에 따라 기본값으로 VARCHAR(191)VARCHAR(255) 대체하였습니다. 
VARCHAR(255)해외 사용자를 지원할 필요가 없는 소프트웨어 애플리케이션의 경우 2010년대 초 사용자가 이모티콘 지원(종종 스마트폰의 등장과 관련됨)을 기대하기 시작하면 업그레이드도 필요했습니다.

요즘에는 최신 데이터베이스에서 "모든" 문자를 지원할 수 있는 utf8mb4 등의 문자 인코딩이 기본값으로 사용되며, 고정 길이 인덱스는 이제 과거의 일이 되었습니다. 그러나 호환성을 보장하기 위해 많은 애플리케이션에서 여전히 191자의 기본값을 사용하고 있습니다. 어쨌든 인덱스는 비교 대상 문자열의 크기를 알고 있을 때 가장 잘 작동하므로 속도상의 이유로 열 길이에 어느 정도 제한을 두는 것이 좋으며, 역사와 관성 덕분에 191자 제한은 여전히 유지되고 있습니다.

utf8, utf8mb4

위에서 한번 더 다룬다고 한 내용에 대해서 짧게 설명해보도록 하겠습니다.

VARCHAR(255)의 경우

  • utf8인 경우 255 * 3 = 765
  • utf8mb4인 경우 255 * 4 = 1020

VARCHAR(191)의 경우

  • utf8mb4인 경우 191 * 4 = 764

고로 VARCHAR(191)을 사용하면 현대에서 많이 사용되고 있는 이모지 사용까지 고려한 utf8mb4로 문자열이 깨지지 않으며 인덱싱이 가능해진다는 장점이 있습니다.

문자의 최대 바이트 수가 바뀌었을 때 인덱스가 걸려있다면 문제가 발생할 수 있기 때문에
인덱스가 걸린 VARCHAR(255)인 필드가 있었다면 이 필드는 utf8mb4로 변경이 불가능하고 VARCHAR(191)로 길이를 줄여줘야 인덱스를 유지한 상태로 utf8mb4로 변경이 가능해집니다.


참고자료
https://github.com/prisma/prisma/discussions/17781
https://www.grouparoo.com/blog/varchar-191
https://findmypiece.tistory.com/290

profile
지극히 평범한 공대생

0개의 댓글

관련 채용 정보