source

모든 텍스트 기반 필드에 범용 varchar(255)를 사용하면 단점이 있습니까?

goodcode 2022. 10. 6. 21:55
반응형

모든 텍스트 기반 필드에 범용 varchar(255)를 사용하면 단점이 있습니까?

나는 가지고 있다contacts다음과 같은 필드를 포함하는 테이블postcode,first name,last name,town,country,phone numberetc, 모두 다음과 같이 정의됩니다.VARCHAR(255)(Ruby on Rails의 이행으로 String 필드가 255글자에 근접하는 경우는 없습니다).VARCHAR(255)디폴트로는 무효로 하고 싶지 않습니다).

VARCHAR은 필드의 실제 문자 수(필드 길이와 함께)만 저장하기 때문에 다음과 같은 기능을 사용하는 데 뚜렷한 이점(퍼포먼스 또는 기타)이 있습니까?VARCHAR(16)에 걸쳐서VARCHAR(255)?

또한 대부분의 필드에는 인덱스가 있습니다.필드의 VARCHAR 크기가 크면 인덱스의 크기 또는 퍼포먼스에 영향을 미칩니까?

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

스토리지에서는,VARCHAR(255)특정 행에 필요한 길이만 저장할 수 있습니다.CHAR(255)항상 255자를 저장할 수 있습니다.

MySQL을 사용하여 이 질문에 태그를 지정했으므로 MySQL 관련 힌트를 언급하겠습니다. 스토리지 엔진 계층에서 SQL 계층으로 행이 복사될 수 있습니다.VARCHAR필드가 로 변환됩니다.CHAR고정 폭의 행으로 작업할 수 있는 이점을 얻을 수 있습니다.따라서 메모리의 문자열은 선언한 최대 길이까지 패딩 처리됩니다.VARCHAR기둥.

쿼리에서 임시 테이블이 암묵적으로 생성된 경우(예: 정렬 중 또는GROUP BY, 이것은 많은 메모리를 사용할 수 있습니다.많이 사용하시면VARCHAR(255)그렇게 길 필요가 없는 데이터의 경우, 이 경우 임시 테이블이 매우 커질 수 있습니다.

또한 이 "패딩" 동작은 utf8 문자 집합으로 선언된 문자열이 단일 바이트 컨텐츠(asciii 또는 latin1 문자 등)로 저장되는 문자열에 대해서도 문자당 3 바이트로 출력된다는 것을 의미한다는 것을 알고 싶을 수도 있습니다.마찬가지로 utf8mb4 문자 세트에서도 메모리 내의 문자당 문자열이 4바이트로 늘어납니다.

비상대기상태VARCHAR(255)utf8에서는 "No oppinition"과 같은 짧은 문자열을 저장하면 디스크에서는 11바이트(작은 문자 10자, 길이에서는 1바이트)가 소요되지만 메모리에서는 765바이트가 소요되므로 임시 테이블 또는 정렬된 결과가 됩니다.

저도 모르게 1.5를 만든 MySQL 사용자를 도와드렸습니다.GB의 임시 테이블이 자주 표시되며 디스크 공간이 가득 찼습니다.그들은 많은 것을 가지고 있었다.VARCHAR(255)실제로 매우 짧은 문자열을 저장했던 열입니다.

저장할 데이터 유형에 따라 열을 정의하는 것이 가장 좋습니다.다른 사람들이 언급한 바와 같이 애플리케이션 관련 제약을 적용할 수 있는 이점이 있습니다.그러나 위에서 설명한 메모리 낭비를 피할 수 있는 물리적 이점이 있습니다.

물론 가장 긴 우편 주소가 무엇인지 아는 것은 어렵기 때문에 많은 사람들이 긴 우편 주소를 선택하는 것이다.VARCHAR그 어떤 주소보다도 길어요그리고 255는 의 최대 길이이기 때문에 관례입니다.VARCHAR1 바이트로 부호화할 수 있습니다.또한 그것은 최대치였다.VARCHAR길이 5.0보다 오래된 MySQL의 경우

varchar의 크기를 설정할 때의 크기 및 성능 고려 사항(스토리지와 프로세싱 비용이 매초 저렴해짐에 따라 더욱 중요)과 더불어 varchar(255)를 사용할 때의 단점은 데이터 무결성이 떨어진다는 것입니다.

문자열의 최대 제한을 정의하는 것은 예상보다 긴 문자열이 RDBMS에 들어가 예상보다 긴 값을 데이터베이스에서 취득 및 해석할 때 나중에 버퍼 오버런 또는 예외/오류가 발생하는 것을 방지하기 위한 좋은 방법입니다.

예를 들어, 국가 약어에 2글자 문자열을 사용할 수 있는 필드가 있는 경우, 사용자(이 컨텍스트에서는 프로그래머)가 완전한 국가 이름을 입력하도록 기대할 수 없습니다."Antigua and Barbuda"(AG) 또는 "Heard Island and McDonald Island"(HM)를 입력하지 않도록 데이터베이스 계층에서 허용하지 않습니다.또, 일부의 프로그래머는, 설계 문서(확실히 존재하는 것)를 아직 RTFM으로 작성하지 않고 있는 경우가 있습니다.

필드를 2글자를 받아들이도록 설정하고 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(25)를 사용하면 사용자(최종 사용자, 프로그래머, 기타 프로그램)가 예기치 않게 긴 데이터를 입력하여 나중에 코드를 괴롭히는 문제를 제거할 수 있습니다.

또한 어플리케이션에서 사용하는 비즈니스 로직 코드에 이 제한을 적용해서는 안 된다고는 말하지 않았습니다.

난 네 편이야.세세한 부분까지 신경을 쓰는 것은 귀찮은 일이며 가치가 한정되어 있습니다.

옛날에는 디스크가 귀중한 물건이었기 때문에 우리는 디스크 최적화를 위해 많은 노력을 기울였습니다.스토리지 가격이 1,000배 하락하여 모든 바이트를 짜내는 데 드는 시간이 줄어들었습니다.

CHAR 필드만 사용하는 경우 고정 길이 행을 가져올 수 있습니다.이렇게 하면 필드의 정확한 크기를 선택한 경우 디스크를 실제 재시작할 수 있습니다.보다 조밀하게 채워진 데이터(테이블 스캔의 I/O 수가 적음)와 보다 빠른 업데이트(업데이트 및 삽입을 위한 블록의 빈 공간을 쉽게 찾을 수 있음)를 얻을 수 있습니다.

그러나 크기를 너무 많이 추정하거나 실제 데이터 크기가 가변적일 경우 CHAR 필드를 사용하여 공간을 낭비하게 됩니다.데이터의 밀도가 낮아집니다(대규모 검색의 I/O가 증가).

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

다만, 「작은」, 「중간」, 「큰」의 힌트를 줄 필요가 있는 경우가 있습니다.그래서 16, 64, 255 사이즈를 사용합니다.

요즘은 그게 더 이상 중요하지 않다고 생각해.

가변 길이 필드를 사용하면 계산 오버헤드가 발생하지만 오늘날 CPU가 과도하게 사용되고 있기 때문에 고려할 가치조차 없습니다.I/O 시스템이 너무 느려서 varchar를 효과적으로 처리하기 위한 계산 비용이 발생하지 않습니다.사실, 가변 길이 필드를 고정 길이 필드에 걸쳐 사용함으로써 절약되는 Disk 공간의 양에 대한 순이익이 계산적으로 계산될 수 있습니다.대부분의 경우 행 밀도가 더 높습니다.

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

따라서 다른 프라이머리 키와 마찬가지로 레코드 번호 인덱스를 유지해야 합니다.또는 ID에 상세(블록 등)를 인코딩하는 견고한 행 식별자를 만들어야 합니다.그러나 이 경우 행을 영구 스토리지로 이동할 경우 ID를 다시 계산해야 합니다.별거 아닙니다. 모든 인덱스 엔트리를 고쳐 쓰고 a) 소비자에게 공개하지 않거나 b) 수치가 신뢰할 수 있다고 주장하지 않도록 해야 합니다.

그러나 현재 varchar 필드가 있기 때문에 varchar(255)보다 varchar(16)의 유일한 값은 DB가 varchar(16)에 대해 16자 제한을 적용하는 것입니다.DB 모델이 실제 물리적 데이터 모델을 나타내야 하는 경우 필드 길이를 갖는 것이 유용할 수 있습니다.그러나 "모델과 스토리지"가 아닌 "스토리지"에 불과하다면 전혀 필요하지 않습니다.

그런 다음 색인화 가능한 텍스트 필드(예: 변수)와 색인화되지 않은 텍스트 필드(예: 텍스트 또는 CLOB 필드)를 구분하면 됩니다.인덱스 가능한 필드는 인덱스를 용이하게 하기 위해 크기 제한이 있는 반면 CLOB 필드는 (합리 범위 내에서) 없는 경향이 있습니다.

지금까지의 경험으로는 255자의 데이터 타입을 허용하면 어떤 멍청한 사용자(또는 경험이 풍부한 테스터)가 실제로 그것을 채웁니다.

그러면 응용 프로그램의 보고서 및 화면 표시에서 이러한 필드에 사용할 수 있는 공간 등 모든 종류의 문제가 발생합니다.데이터베이스의 데이터 행별 제한(이러한 255자 필드 중 몇 개 이상 있는 경우)을 초과할 가능성은 말할 것도 없습니다.

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

필요한 만큼만 할당하는 것이 좋습니다.전화번호가 이렇게 큰 건 처음이에요.

한 가지 이유는 큰 엔트리에 대해 검증하지 않는 한 누군가가 모든 것을 사용할 것이 틀림없기 때문입니다.그러면 행의 공간이 부족해질 수 있습니다.MySQL 제한은 잘 모르겠지만 MS SQL의 최대 행 크기는 8060입니다.

통상적인 디폴트는 50 imho 입니다.그 후 필요에 따라 증가합니다.

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

즉, 여러 varchar 255 컬럼에 인덱스를 추가하면 위의 답변에서 지적한 바와 같이 utf8 또는 utf8mb4 컬럼에서 이 제한에 빠르게 도달할 수 있습니다.

언급URL : https://stackoverflow.com/questions/262238/are-there-disadvantages-to-using-a-generic-varchar255-for-all-text-based-field

반응형