Programing

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

lottogame 2020. 8. 23. 09:40
반응형

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


나는이 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의 가격은 고정 길이 필드에 대해 가변 길이 필드를 사용하여 절약 된 디스크 공간의 양에 대한 순이익 일 것입니다. 행 밀도가 더 높을 가능성이 높습니다.

Now, the complexity of varchar fields is that you can't easily locate a record via it's record number. When you have a fixed length row size (with fixed length fields), it's trivial to compute the disk block that a row id points to. With a variable length rowsize, that kind of goes out the window.

So, now you need to maintain some kind of record number index, just like any other primary key, OR you need to make a robust row identifier that encodes details (such as the block, etc.) in to the identifier. If you do that, though, the id would have to be recalculated if ever the row is moved on persistent storage. No big deal, just need to rewrite all of the index entries and make sure the you either a) never expose it to the consumer or b) never assert that the number is reliable.

But since we have varchar fields today, the only value of varchar(16) over varchar(255) is that the DB will enforce the 16 char limit on the varchar(16). If the DB model is supposed to be actually representative of the physical data model, then having fields lengths can be of value. If, however, it's simply "storage" rather than a "model AND storage", there's no need whatsoever.

Then you simply need to discern between a text field that is indexable (such varchar) vs something that is not (like a text or CLOB field). The indexable fields tend to have a limit on size to facilitate the index whereas the CLOB fields do not (within reason).


In my experience, if you allow a datatype of 255 characters, some stupid user (or some experienced tester) will actually fill that up.

Then you have all sorts of problems, including how much space you allow for those fields in reports and on-screen displays in your application. Not to mention the possibility of exceeding the per-row limit for data in your database (if you had more than a few of these 255 character fields).

Much easier to pick a reasonable limit at the beginning, then enforce that through the application and database.


It's good practice to allocate only a little over what you need. Phone numbers would never go this large.

One reason is that unless you validate against large entries, no doubt someone will use all there is. Then you might run out of space in your row. I'm not sure about MySQL limit but 8060 is the max rowsize in MS SQL.

A more normal default would be 50 imho, and then increase where need proves it.


In a mysql context it can get important when working with indexes on said varchar columns, as mysql has a max. limit of 767bytes per index-row.

This means that when adding a index across several varchar 255 columns you can get to this limit rather quickly / even faster on utf8 or utf8mb4 columns as pointed out in the answers above

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

반응형