모든 텍스트 기반 필드에 일반 varchar (255)를 사용하는 데 단점이 있습니까? 테이블을 postcode, first name, last name, town,

나는이 contacts같은 필드가 포함 테이블을 postcode, first name, last name, town, country, phone number등으로 정의되어 모두 VARCHAR(255)도이 분야의 누구도 가까운 255 자있는에 올 것이다하지만. (궁금하신다면 Ruby on Rails 마이그레이션 VARCHAR(255)이 기본적으로 String 필드를 에 매핑 하고 재정의 할 필요가 없기 때문에 이런 식 입니다.)

VARCHAR은 (필드 길이와 함께) 분야의 실제 문자의 수를 저장하는 것이기 때문에, 말하자면, 사용에 대한 뚜렷한 장점 (그렇지 않으면 성능)이 VARCHAR(16)이상은 VARCHAR(255)?

또한 이러한 필드의 대부분에는 인덱스가 있습니다. 필드에서 더 큰 VARCHAR 크기가 인덱스의 크기 나 성능에 전혀 영향을 줍니까?

참고로 MySQL 5를 사용하고 있습니다.



답변

저장소에서는 항상 255자를 저장하는 VARCHAR(255)것과 달리 주어진 행에 필요한 길이 만 저장할 수있을만큼 똑똑 CHAR(255)합니다.

그러나이 질문에 MySQL에 태그를 지정 했으므로 MySQL 관련 팁을 언급하겠습니다. 행이 스토리지 엔진 계층에서 SQL 계층으로 복사되면 VARCHAR필드가로 변환 CHAR되어 고정 너비 행으로 작업하는 이점을 얻습니다. 따라서 메모리의 문자열은 선언 된 열의 최대 길이까지 채워집니다VARCHAR .

예를 들어 또는 정렬하는 동안 쿼리가 암시 적으로 임시 테이블을 생성하는 GROUP BY경우 많은 메모리를 사용할 수 있습니다. VARCHAR(255)그렇게 길지 않아도되는 데이터에 대해 많은 필드를 사용하면 임시 테이블이 매우 커질 수 있습니다.

또한이 “패딩 아웃”동작은 utf8 문자 세트로 선언 된 문자열이 단일 바이트 콘텐츠 (예 : ascii 또는 latin1 문자)로 저장 한 문자열에 대해서도 문자 당 3 바이트로 채워짐을 의미합니다. 마찬가지로 utf8mb4 문자 세트는 문자열이 메모리에서 문자 당 4 바이트까지 채워지도록합니다.

따라서 VARCHAR(255)utf8에서 “No 의견”과 같은 짧은 문자열을 저장하는 것은 디스크에서 11 바이트 (낮은 문자 집합 문자 10 개와 길이 1 바이트)를 사용하지만 메모리에서는 765 바이트를 사용하므로 임시 테이블 또는 정렬 된 결과가됩니다.

나는 무의식적으로 1.5GB 임시 테이블을 자주 생성하고 디스크 공간을 채우는 MySQL 사용자를 도왔습니다. VARCHAR(255)실제로는 매우 짧은 문자열을 저장하는 많은 열이 있습니다.

저장하려는 데이터 유형에 따라 열을 정의하는 것이 가장 좋습니다. 다른 사람들이 언급했듯이 응용 프로그램 관련 제약 조건을 적용하면 이점이 있습니다. 그러나 위에서 설명한 메모리 낭비를 피할 수있는 물리적 이점이 있습니다.

물론 가장 긴 우편 주소가 무엇인지 알기는 어렵 기 때문에 많은 사람들 VARCHAR이 어떤 주소보다 확실히 긴 긴 주소를 선택합니다. 그리고 255는 VARCHAR길이를 1 바이트로 인코딩 할 수있는 a의 최대 길이이기 때문에 일반적 입니다. 또한 VARCHAR5.0 이전 MySQL 의 최대 길이였습니다.


답변

varchar의 크기 설정에 대한 크기 및 성능 고려 사항 외에도 (저장 및 처리 비용이 매초마다 저렴 해짐에 따라 더 중요 할 수 있음) varchar (255) 사용의 단점은 데이터 무결성 이 감소하기 때문 입니다.

문자열에 대한 최대 제한을 정의하는 것은 예상보다 긴 (더 많은 바이트) 값을 데이터베이스에서 검색하고 구문 분석 할 때 예상보다 긴 문자열이 RDBMS에 들어가고 나중에 버퍼 오버런이나 예외 / 오류가 발생 하지 않도록 방지 하는 좋은 방법 입니다.

예를 들어 국가 약어에 대해 2 자 문자열을 허용하는 필드가있는 경우 사용자 (이 컨텍스트에서 프로그래머)가 전체 국가 이름을 입력 할 것이라고 예상 할 수있는 이유가 없습니다. “Antigua and Barbuda”(AG) 또는 “Heard Island and McDonald Islands”(HM)를 입력하는 것을 원하지 않기 때문에 데이터베이스 계층에서 허용하지 않습니다. 또한 일부 프로그래머는 설계 문서 ( 확실히 존재 함 )를 RTFM 하지 않아이를 수행하지 않는 것을 알 수 있습니다.

두 문자를 허용하도록 필드를 설정하고 RDBMS가 처리하도록합니다 (잘림으로써 정상적으로 또는 오류와 함께 SQL을 거부하여 비정상적으로).

특정 길이를 초과 할 이유가없는 실제 데이터의 예 :

  • 캐나다 우편 번호 는 A1A1A1 형식이며 산타 클로스의 경우에도 항상 길이가 6 자입니다 (6 자에서는 가독성을 위해 지정할 수있는 공백이 제외됨).
  • 이메일 주소 -@ 앞에 최대 64 바이트, 뒤에 최대 255 바이트. 더 이상 인터넷을 끊지 않도록하십시오.
  • 북미 전화 번호는 10 자리를 초과 할 수 없습니다 (국가 코드 제외).
  • Windows를 실행하는 컴퓨터 (최신 버전) 는 63 바이트보다 긴 컴퓨터 이름을 가질 수 없지만 15 개 이상은 권장되지 않으며 Windows NT 서버 팜을 손상시킵니다.
  • 주 약자는 2 자입니다 (위의 국가 코드 예와 같음).
  • UPS 조회 번호 는 18 자, 12 자, 11 자 또는 9 자입니다. 18 자리 숫자는 “1Z”로 시작하고 11 자리 숫자는 “T”로 시작합니다. 문자와 숫자의 차이를 모르는 경우 모든 패키지를 배송하는 방법이 궁금합니다.

등등…

시간을내어 데이터와 그 한계에 대해 생각하십시오. 당신이 건축가, 개발자, 프로그래머라면 그것은 결국 당신의 입니다.

varchar (255) 대신 varchar (n)을 사용하면 사용자 (최종 사용자, 프로그래머, 기타 프로그램)가 예기치 않게 긴 데이터 입력 하여 나중에 코드를 괴롭히는 문제를 제거 할 수 있습니다.

그리고 응용 프로그램에서 사용하는 비즈니스 논리 코드에서도이 제한을 구현해서는 안된다고 말하지 않았습니다.


답변

난 너와 함께있어. 세부 사항에 대한 까다로운 관심은 목의 통증이며 가치가 제한적입니다.

옛날 옛적에 디스크는 귀중한 상품이었고 우리는이를 최적화하기 위해 총알을 땀을 흘리 곤했습니다. 스토리지 가격이 1,000 배 하락하여 모든 바이트를 압축하는 데 소요되는 시간의 가치가 떨어졌습니다.

CHAR 필드 만 사용하는 경우 고정 길이 행을 얻을 수 있습니다. 필드에 대해 정확한 크기를 선택한 경우 일부 디스크 실제 복원을 절약 할 수 있습니다. 더 조밀하게 압축 된 데이터 (테이블 스캔을위한 I / O 감소)와 더 빠른 업데이트 (업데이트 및 삽입을 위해 블록에서 열린 공간을 더 쉽게 찾을 수 있음)를 얻을 수 있습니다.

그러나 크기를 과대 평가하거나 실제 데이터 크기가 가변적이면 CHAR 필드로 공간을 낭비하게됩니다. 데이터는 압축률이 낮아집니다 (대규모 검색을 위해 더 많은 I / O로 이어짐).

일반적으로 변수 필드에 크기를 입력하면 성능상의 이점은 미미합니다. CHAR (x)와 비교하여 VARCHAR (255)를 사용하여 쉽게 벤치마킹하여 차이를 측정 할 수 있는지 확인할 수 있습니다.

그러나 때때로 “작은”, “중간”, “대형”힌트를 제공해야합니다. 그래서 저는 크기로 16, 64, 255를 사용합니다.


답변

요즘에는이게 더 이상 중요하다는 것을 상상할 수 없습니다.

가변 길이 필드를 사용하는 데는 계산 오버 헤드가 있지만 오늘날 CPU가 너무 많아서 고려할 가치가 없습니다. I / O 시스템이 너무 느려서 varchar를 효과적으로 처리하기위한 계산 비용이 존재하지 않습니다. 사실, 계산적으로 varchar의 가격은 고정 길이 필드에 대해 가변 길이 필드를 사용하여 절약 된 디스크 공간의 양에 대한 순이익 일 것입니다. 행 밀도가 더 높을 가능성이 높습니다.

이제 varchar 필드의 복잡성은 레코드 번호를 통해 레코드를 쉽게 찾을 수 없다는 것입니다. 고정 길이 행 크기 (고정 길이 필드 포함)가있는 경우 행 ID가 가리키는 디스크 블록을 계산하는 것은 간단합니다. 가변 길이 행화를 사용하면 그러한 종류가 창 밖으로 나갑니다.

따라서 이제는 다른 기본 키와 마찬가지로 일종의 레코드 번호 인덱스를 유지해야합니다. 또는 식별자에 세부 정보 (예 : 블록 등)를 인코딩하는 강력한 행 식별자를 만들어야합니다. 하지만 그렇게하면 행이 영구 저장소로 이동 될 경우 ID를 다시 계산해야합니다. 큰 문제는 아닙니다. 모든 인덱스 항목을 다시 작성하고 a) 소비자에게 절대 노출하지 않거나 b) 숫자가 신뢰할 수 있다고 주장하지 않도록해야합니다.

그러나 오늘날 varchar 필드가 있으므로 varchar (255)보다 varchar (16)의 유일한 값은 DB가 varchar (16)에 16 자 제한을 적용한다는 것입니다. DB 모델이 실제로 실제 데이터 모델을 대표해야하는 경우 필드 길이를 갖는 것이 가치가있을 수 있습니다. 그러나 “모델 및 스토리지”가 아니라 단순히 “스토리지”인 경우에는 전혀 필요하지 않습니다.

그런 다음 인덱싱 할 수있는 텍스트 필드 (예 : varchar)와 그렇지 않은 항목 (예 : 텍스트 또는 CLOB 필드)을 구분하기 만하면됩니다. 인덱싱 가능한 필드는 인덱스를 용이하게하기 위해 크기에 제한이있는 경향이 있지만 CLOB 필드는 그렇지 않습니다 (이유 내에서).


답변

내 경험상 255 자의 데이터 유형을 허용하면 어리석은 사용자 (또는 숙련 된 테스터)가 실제로이를 채울 것입니다.

그러면 보고서의 해당 필드와 응용 프로그램의 화면 표시에 허용되는 공간을 포함하여 모든 종류의 문제가 발생합니다. 데이터베이스의 데이터에 대한 행당 제한을 초과 할 가능성은 말할 것도 없습니다 (이러한 255 자 필드가 몇 개 이상있는 경우).

처음에 합리적인 제한을 선택하고 애플리케이션과 데이터베이스를 통해 적용하는 것이 훨씬 쉽습니다.


답변

필요한 것보다 약간만 할당하는 것이 좋습니다. 전화 번호는 이렇게 커지지 않을 것입니다.

한 가지 이유는 큰 항목에 대해 유효성을 검사하지 않는 한 누군가가있는 모든 항목을 사용한다는 것입니다. 그러면 행의 공간이 부족할 수 있습니다. MySQL 제한에 대해 잘 모르겠지만 8060은 MS SQL의 최대 행 수입니다.

더 일반적인 기본값은 50 imho이며 필요한 경우 증가합니다.


답변

mysql 컨텍스트에서는 mysql이 최대 값을 가지고 있기 때문에 언급 된 varchar 열의 인덱스로 작업 할 때 중요해질 수 있습니다. 인덱스 행당 767 바이트로 제한됩니다.

즉, 여러 varchar 255 열에 인덱스를 추가 할 때 위의 답변에서 지적한대로 utf8 또는 utf8mb4 열에서이 제한에 다소 빠르게 / 더 빨리 도달 할 수 있습니다.