SQL에서 VARCHAR이 아닌 CHAR을 선택하는 사용 사례는 무엇입니까?
모든 값이 고정 너비일 경우 CHAR이 권장됩니다.하지만 뭐 어때?안전을 위해 모든 텍스트 필드에 대해 VARCHAR을 선택하는 것이 좋습니다.
일반적으로 모든 행의 길이가 같은 경우 CHAR을 선택합니다.길이가 크게 달라지면 VARCHAR(또는 NVARCHAR)를 선택합니다.모든 행의 길이가 같기 때문에 CHAR이 조금 더 빠를 수도 있습니다.
DB 구현에 따라 다르지만 일반적으로 VARCHAR(또는 NVARCHAR)는 실제 데이터 외에 1~2바이트의 스토리지(길이 또는 종단)를 추가로 사용합니다.따라서 (1바이트 문자 집합을 사용한다고 가정하면) "FooBar"라는 단어를 저장합니다.
- CHAR(6) = 6 바이트(오버헤드 없음)
- VARCHAR(100) = 8 바이트 (2 바이트의 오버헤드)
- CHAR(10) = 10 바이트 (4 바이트의 낭비)
결론은 길이가 비교적 같은 데이터(2자 이내)에 대해 CHAR이 더 빠르고 공간 효율적일 수 있다는 것입니다.
주의: Microsoft SQL에는 VARCHAR의 오버헤드가 2바이트 있습니다.이는 DB마다 다를 수 있지만 일반적으로 VARCHAR에서 길이 또는 EOL을 나타내려면 최소 1바이트의 오버헤드가 필요합니다.
Gaven이 코멘트에서 지적한 바와 같이:멀티바이트 문자 세트에 대해서는 상황이 달라지며 VARCHAR이 훨씬 더 나은 선택이 될 수 있습니다.
VARCHAR의 선언된 길이에 대한 주의사항: VARCHAR에는 실제 콘텐츠의 길이가 저장되므로 사용하지 않는 길이가 낭비되지 않습니다.따라서 VARCHAR(6), VARCHAR(100) 또는 VARCHAR(MAX)에 6자를 저장해도 동일한 양의 스토리지가 사용됩니다.VARCHAR(MAX)를 사용할 때의 차이점에 대해 자세히 알아보십시오.VARCHAR 에 최대 사이즈를 선언하고, 보존량을 제한합니다.
코멘트에서 AlwaysLearning은 Microsoft Transact-SQL 문서는 그 반대인 것 같다고 지적했습니다.저는 그것이 오류이거나 적어도 문서가 불분명하다고 제안합니다.
만약 당신이 저와 함께 일하고 있고 오라클과 함께 일하고 있다면, 저는 아마도 당신에게 다음을 하게 할 것입니다.varchar
「 」 「 」 「 」의 전제char
에서는, 처리 이, 보다 적게 됩니다.varchar
★★★★★★★★★★★★★★★... 엔진은 에 따라 "변화를 일으킨다.그러나 데이터베이스 엔진은 시간이 지남에 따라 향상되고 이러한 일반적인 규칙은 미래의 "변화"를 일으킵니다.
하나 : 퍼포먼스 는 본 .가 퍼포먼스 문제로 입니다.varchar
. 콜 와 효율적인 SQL(, , )을 쓰는가 하는 할 수 exists
in
를 사용합니다.
마지막 생각:나는 의 사용에 관한 모든 종류의 문제를 봐왔다.CHAR
, " 를 때 " " 때 " " 를 찾고 때 " " 를 찾고 있을 때 " " 를 찾고 있을 때" 를 있을 때 " " " 를 찾고 를 있는 , 않은 , 개의 " " 를 찾고 있을 때 " " 를 찾고 있을 때 " " 를 찾고 있을 때 " " 를 찾고 있을 때 " " 를 찾고 있을 때" 를 찾고 있을 때 " " " 를 찾고 있을 때" 를 찾고 있는 사용자, 후행 공백을 자르지 않은 사용자, Oracle 절차에서 반환되는 가치에 최대 2000 개의 공백을 추가하는 Powerbuilder 오류.
이점에 해, 퍼포먼스상의 메리트에 가세해CHAR
는 모든 값이 동일한 길이여야 함을 나타내는 데 사용할 수 있습니다(예: 미국 주 약어 열).
Char가 조금 빠르기 때문에 어느 정도의 길이가 될 것으로 알고 있는 열이 있으면 char를 사용합니다.예를 들어 성별에 대해 알려진 저장(M)ale/(F)emale/(U)n, 미국 상태의 경우 2자 등입니다.
NChar 또는 Char가 다른 대안보다 더 나은 성능을 발휘합니까?
좋은 질문입니다.간단한 대답은 어떤 상황에서는 '그렇다'입니다.이걸 설명할 수 있는지 한번 봅시다.
varchar(255)(이 열을 myColumn이라고 부르자)로 테이블을 만들고 100만 개의 행을 삽입하지만 각 행에 대해 myColumn에 몇 개의 문자만 입력하면 myColumn을 char(255)로 만들 때보다 테이블이 훨씬 작아집니다.해당 테이블에서 작업(DML)을 수행하고 많은 행을 요청하면 myColumn이 varchar일 때 항상 속도가 빨라집니다. 왜냐하면 마지막에 모든 "추가" 공간을 이동할 필요가 없기 때문입니다.SQL Server가 고유 또는 결합 작업 중이나 쿼리 계획 중에 병합을 선택하는 등의 내부 정렬을 수행하는 경우와 같이 이동합니다.이동이란 서버에서 로컬 PC 또는 다른 컴퓨터로 데이터를 이동하거나 데이터를 소비하는 장소까지 이동하는 데 걸리는 시간을 의미하기도 합니다.
그러나 varchar 사용에는 약간의 오버헤드가 있습니다.SQL Server는 각 행에서 2바이트 표시기(오버헤드)를 사용하여 특정 행의 myColumn에 포함된 바이트 수를 알아야 합니다.문제가 되는 것은 추가 2바이트가 아니라 각 행의 myColumn 데이터 길이를 "디코딩"해야 하기 때문입니다.
내 경험으로는 쿼리에 결합되는 열에 varchar 대신 char를 사용하는 것이 가장 타당합니다.예를 들어 테이블의 기본 키 또는 인덱싱되는 다른 열 등이 있습니다.기록 정보 테이블의 고객 번호 또는 코드디코드 테이블의 ID 또는 주문 테이블의 Order Number.char를 사용하면 쿼리 엔진은 페이지를 읽을 때 포인터를 가변 바이트 양으로 이동하는 대신 직선 포인터 산술(결정적으로)을 수행할 수 있기 때문에 조인(join)을 보다 빠르게 수행할 수 있습니다.마지막 문장에서 당신을 잃었을지도 모른다는 걸 알아요SQL Server에서의 가입은 "예약" 개념을 기반으로 합니다.술어는 조건입니다.예를 들어 myColumn = 1, OrderNumber < 500 등입니다.
따라서 SQL Server가 DML 문을 실행하고 있고 결합되는 술어 또는 "키"가 고정 길이(char)인 경우 쿼리 엔진은 한 테이블의 행을 다른 테이블의 행과 일치시키기 위해 많은 작업을 수행할 필요가 없습니다.데이터 행의 길이를 파악한 후 그 끝을 찾기 위해 줄을 따라 이동할 필요가 없습니다.시간이 걸려요.
이것은 간단하게 실장할 수 있습니다.온라인 시스템에서 주요 키 필드에 사용되는 문자를 본 적이 있습니다.너비는 char(15) 또는 합리적인 것으로 작게 유지해야 합니다.또한 보통 소수의 행만 가져오거나 올리므로 결과 집합에서 얻을 수 있는 후행 공간을 "조정"해야 하는 것은 하나의 테이블에서 수백만 개의 행을 다른 테이블에서 수백만 개의 행으로 결합하는 것과 달리 간단한 작업입니다.
온라인 시스템에서 CHAR이 varchar보다 더 적합한 또 다른 이유는 페이지 분할을 줄이기 때문입니다.char를 사용하면 기본적으로 해당 공간을 예약(및 낭비)하게 됩니다.따라서 사용자가 나중에 와서 더 많은 데이터를 해당 열에 넣으면 SQL은 이미 해당 공간에 공간을 할당하고 있습니다.
CHAR을 사용하는 또 다른 이유는 두 번째 이유와 비슷합니다.프로그래머나 사용자가 노트 필드에 일부 문장을 추가하는 등 수백만 행에 대해 "배치" 업데이트를 수행하면 한밤중에 DBA로부터 드라이브가 꽉 찬 이유에 대한 문의 전화가 오지 않습니다.즉, 데이터베이스 크기의 예측 가능한 확대로 이어집니다.
즉, 온라인(OLTP) 시스템이 char over varchar를 통해 얻을 수 있는 이점은 다음과 같습니다.창고/분석/OLAP 시나리오에서는 char를 거의 사용하지 않습니다.대개 char 컬럼에 데이터가 너무 많아서 많은 공간이 낭비될 수 있기 때문입니다.
char는 데이터베이스를 훨씬 더 크게 만들 수 있지만 대부분의 백업 도구에는 데이터 압축 기능이 있으므로 백업 크기는 varchar를 사용한 경우와 거의 동일합니다.예를 들어 LiteSpeed 또는 RedGate SQL 백업입니다.
데이터를 고정 너비 파일로 내보내기 위해 작성된 뷰에서도 사용할 수 있습니다.메인프레임에서 읽을 수 있도록 데이터를 플랫 파일로 내보내야 한다고 가정해 보겠습니다.고정 폭(구분되지 않음)입니다.데이터를 "스테이징" 테이블에 varchar로 저장한 후(데이터베이스의 공간을 적게 사용) 보기를 사용하여 모든 데이터를 해당 열의 고정 너비에 해당하는 길이의 문자로 캐스트합니다.예를 들어 다음과 같습니다.
create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )
insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)
create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))
SELECT * from vwStagingTable
데이터는 varchar를 사용하기 때문에 내부적으로 차지하는 공간이 적기 때문에 이 기능은 매우 우수합니다.그러나 DTS나 SSIS를 사용하거나 SSMS에서 메모장으로 잘라 붙여넣기만 하면 뷰를 사용하여 적절한 수의 후행 공간을 얻을 수 있습니다.DTS(디지털 스로틀 및 시프트)에는 "제안 열"이라던가 하는 기능이 있었습니다.SSIS에서는 더 이상 이 작업을 수행할 수 없습니다. 플랫 파일 연결 관리자를 지루하게 정의해야 합니다.그러나 뷰 설정이 있기 때문에 SSIS는 각 열의 너비를 알 수 있으며 데이터 흐름 태스크를 작성할 때 많은 시간을 절약할 수 있습니다.
그러니까 결론은...바르샤를 사용합니다.char를 사용하는 이유는 극히 적으며 성능상의 이유일 뿐입니다.수백만 행의 헌드렌드가 있는 시스템의 경우 술어가 결정론적(char)인 경우 현저한 차이를 알 수 있습니다.단, char를 사용하는 대부분의 시스템에서는 단순히 공간을 낭비하고 있습니다.
도움이 됐으면 좋겠다.제프
퍼포먼스상의 이점이 있습니다만, 여기에서는 설명되지 않은 것이 행의 이행입니다.
CHAR을 사용하면 전체 공간을 미리 예약합니다.예를 들어 CHAR(1000)이 있고 10글자를 저장한다고 가정하면 1000글자의 공백이 모두 사용됩니다.VARCHAR2(1000)에서는, 10 문자 밖에 사용할 수 있습니다.
데이터를 수정할 때 문제가 발생합니다.열을 900자로 업데이트한다고 가정해 보겠습니다.현재 블록에서 varchar를 확장할 공간이 없을 수 있습니다.이 경우 DB 엔진은 행을 다른 블록으로 마이그레이션하고 원래 블록의 포인터를 새 블록의 새 행으로 만들어야 합니다.이 데이터를 읽으려면 DB 엔진이 2개의 블록을 읽어야 합니다.
아무도 바르샤르나 차르가 더 낫다고 애매모호하게 말할 수 없다.특히 데이터가 증가할 가능성이 높은 경우, 시간 균형을 맞출 수 있는 공간이 있고 데이터가 업데이트될지 여부를 고려해야 합니다.
초기 성능 최적화와 베스트 프랙티스 유형의 규칙 사용 사이에는 차이가 있습니다.항상 고정 길이 필드가 있는 새 테이블을 작성하는 경우 CHAR을 사용하는 것이 좋습니다.이 경우 CHAR을 사용해야 합니다.이는 초기 최적화가 아니라 경험칙(또는 베스트 프랙티스)을 구현하는 것입니다.
즉, 2글자 상태 필드가 있는 경우 CHAR(2)를 사용합니다.실제 상태 이름을 가진 필드가 있는 경우 VARCHAR을 사용합니다.
컬럼에 US 스테이트 코드와 같은 고정값이 저장되어 있지 않은 한 varchar를 선택합니다.이것은 항상 2글자 길이로 유효한 US 스테이트 코드 리스트는 자주 변경되지 않습니다.
그 외의 경우는 해시 패스워드(고정길이)를 격납하는 경우와 마찬가지로 varchar를 선택합니다.
Why -- char type 열은 항상 공백으로 채워집니다. 그러면 my_column은 내부 비교에서 값이 'ABC'인 char(5)로 정의됩니다.
my_column = 'ABC' -- my_column stores 'ABC ' value which is different then 'ABC'
거짓의.
이 기능은 개발 중에 많은 자극적인 버그로 이어질 수 있으며 테스트를 더 어렵게 만듭니다.
필드의 모든 데이터 값이 같은 길이일 경우 CHAR은 VARCHAR보다 스토리지 공간을 적게 차지합니다.2009년에는 VARCHAR를 CHAR로 변환하는 경우 800GB 데이터베이스가 810GB와 모든 면에서 동일하지만 짧은 문자열(1~2자)의 경우 CHAR은 여전히 업계의 "베스트 프랙티스"라고 할 수 있습니다.
대부분의 데이터베이스가 정수(bit, tiny, int, bigint)에 대해 제공하는 다양한 데이터 유형을 살펴보면 다른 데이터 유형보다 하나를 선택해야 하는 이유가 있습니다.단순히 매번 bigint를 선택하는 것은 사실 그 분야의 목적과 용도를 조금 모르는 것이다.만약 어떤 분야가 단순히 사람의 나이를 나타낸다면, 비긴트는 과잉 살상입니다."틀렸다"고 할 필요는 없지만 효율적이지는 않습니다.
그러나 이것은 흥미로운 논쟁이며, 시간이 지남에 따라 데이터베이스가 개선됨에 따라 CHAR 대 VARCHAR의 관련성이 낮아진다고 주장할 수 있습니다.
나는 절대 문자를 사용하지 않을 것이다.나는 많은 사람들과 이 토론을 해왔고 그들은 항상 char가 더 빠르다는 진부한 말을 꺼낸다.음, 얼마나 더 빠를까요?여기서 말하는 것은 어떤 밀리초, 초이며, 만약 그렇다면 몇 초입니까?누군가가 몇 밀리초 더 빠르다고 해서 시스템에 버그를 수정하기 위해 수많은 하드디스크를 도입해야 한다고 말하는 건가요?
여기서 몇 가지 문제가 발생합니다.
모든 필드가 패딩되어 있기 때문에 RTRIMS가 어디에나 있는 코드가 영원히 남습니다.또, 장기의 필드에서는, 디스크 스페이스의 낭비가 커집니다.
이제 하나의 문자 필드의 전형적인 예가 있지만 필드는 선택 사항이라고 가정해 보겠습니다.누군가가 빈 문자열을 해당 필드에 전달하면 하나의 공백이 됩니다.따라서 다른 응용 프로그램/프로세스가 이를 쿼리할 때 rtrim을 사용하지 않을 경우 단일 공간을 얻게 됩니다.xml 문서, 파일 및 기타 프로그램을 사용하여 옵션 필드에 공백 하나만 표시하여 내용을 구분합니다.
따라서 빈 문자열이 아닌 null을 char 필드에 전달해야 합니다.그러나 그것은 null의 올바른 용법이 아니다.다음은 null의 사용법입니다.벤더로부터 파일을 입수했다고 합시다.
Name|Gender|City
Bob||Los Angeles
Bob을 입력하는 것보다 성별이 지정되지 않은 경우 테이블에 문자열과 로스앤젤레스를 비웁니다.이제 파일을 가져오면 파일의 형식 변경과 성별은 더 이상 포함되지 않지만 과거로 돌아간다고 가정해 보겠습니다.
Name|City
Bob|Seattle
성별은 포함되어 있지 않기 때문에 늘을 사용합니다.VARCHAR는 문제없이 지원합니다.
반면 CHAR은 다릅니다.항상 NULL을 전송해야 합니다. 빈 문자열을 전송하면 공백이 있는 필드가 표시됩니다.
약 20년의 개발 기간 동안 CHAR에서 수정해야 했던 모든 버그를 계속 사용할 수 있었습니다.
나는 Jim McKeeth의 코멘트를 지지한다.
또한 테이블에 CHAR 열만 있는 경우 인덱싱 및 전체 테이블 검색이 더 빠릅니다.기본적으로 최적기는 각 레코드에 CHAR 열만 있는 경우 각 레코드의 크기를 예측할 수 있으며 모든 VARCHAR 열의 크기 값을 확인해야 합니다.
또한 VARCHAR 열을 이전 컨텐츠보다 큰 크기로 업데이트하면 데이터베이스가 인덱스를 강제로 재구성할 수 있습니다(데이터베이스가 디스크에서 레코드를 물리적으로 이동하도록 강제했기 때문입니다).CHAR 컬럼에서는 그런 일은 일어나지 않습니다.
하지만 테이블이 크지 않으면 퍼포먼스에 신경을 쓰지 않을 것입니다.
Djikstra의 현명한 말을 기억하세요.초기 성능 최적화는 모든 악의 근원입니다.
많은 사람들이 정확한 길이의 값을 알면 CHAR을 사용하는 것이 몇 가지 이점이 있다고 지적해 왔다.그러나 현재 미국 주를 CHAR(2)로 저장하는 것은 훌륭하지만, 영업으로부터 '우리는 호주로 첫 판매를 막 시작했다'는 메시지를 받았을 때, 여러분은 고통의 세계에 빠져들게 될 것입니다.저는 항상 미래의 사건을 취재하기 위해 '정확한' 추측을 하기보다는 제가 생각하는 분야가 얼마나 길어야 하는지 과대평가하도록 보냅니다.VARCHAR은 이 분야에서 더 많은 유연성을 제공할 것입니다.
당신의 경우 Varchar를 선택하지 않을 이유가 없다고 생각합니다.유연성이 있으며, 많은 응답자가 언급했듯이, 현재 퍼포먼스는 매우 구체적인 상황을 제외하고는 (Google DBA와 달리) 차이를 인식하지 못할 정도로 향상되었습니다.
DB Type에 관해 주목할 만한 흥미로운 점은 sqlite(성능이 매우 뛰어난 인기 있는 미니 데이터베이스)가 모든 것을 문자열과 유형으로 데이터베이스에 즉시 저장한다는 것입니다.
저는 항상 VarChar를 사용하고 있으며, 보통 필요한 것보다 훨씬 더 크게 만듭니다.예를 들어, 당신이 말하는 것처럼, First name은 50입니다.
전형적인 공간과 성능의 균형입니다.
MS SQL 2005에서는 Varchar(또는 중국어 1자당 2바이트가 필요한 언어용 NVarchar)는 가변 길이입니다.하드 디스크에 데이터를 쓴 후에 행에 추가하면 데이터가 원래 행의 중요하지 않은 위치에 위치하여 데이터 파일이 조각화됩니다.이것은 퍼포먼스에 영향을 줍니다.
따라서 공간이 문제가 되지 않으면 Char가 성능에 더 좋지만 데이터베이스 크기를 줄이려면 varchar가 더 좋습니다.
플래그멘테이션CHAR은 공간을 예약하지만 VARCHAR은 예약하지 않습니다.VARCHAR 업데이트에 대응하기 위해 페이지 분할이 필요할 수 있습니다.
열 값의 실제 필요한 크기를 계산하고 Varchar의 공간을 할당하는 데 약간의 처리 오버헤드가 있으므로 값이 항상 얼마나 오래 유지되는지 확실히 알 수 있다면 Char를 사용하여 히트를 피하는 것이 좋습니다.
varchar 값을 사용하는 경우 SQL Server는 해당 열에 대한 정보를 저장하기 위해 행당 2바이트가 더 필요합니다. char를 사용하는 경우에는 그렇지 않으면 필요하지 않습니다.
CHAR(NCHAR) 및 VARCHAR(NVARCHAR)를 사용하면 데이터베이스 서버의 데이터 저장 방법이 달라집니다.첫 번째는 후행 공백이 도입되어 SQL SERVER 함수에서 LIKE 연산자와 함께 사용할 때 문제가 발생하였습니다.그래서 항상 VARCHAR(NVARCHAR)를 사용하여 안전하게 만들어야 합니다.
예를 들어 TEST(ID INT, Status CHAR(1)) 테이블이 있고 다음과 같은 특정 값을 가진 모든 레코드를 나열하는 함수를 작성할 수 있습니다.
CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'
이 함수에서는 기본 파라미터를 입력하면 모든 행이 반환되지만 실제로는 반환되지 않습니다.@Status 데이터 유형을 VARCHAR로 변경하면 문제가 해결됩니다.
일부 SQL 데이터베이스에서는 VARCHAR이 오프셋을 최적화하기 위해 최대 크기로 패딩됩니다. 이는 전체 테이블 스캔 및 인덱스의 속도를 높이기 위함입니다.
따라서 VARCHAR(200)을 사용하면 CHAR(200)에 비해 공간을 절약할 수 없습니다.
언급URL : https://stackoverflow.com/questions/59667/what-are-the-use-cases-for-selecting-char-over-varchar-in-sql
'programing' 카테고리의 다른 글
PowerShell의 코드를 어떻게 코멘트합니까? (0) | 2023.04.16 |
---|---|
iOS Simulator에서 콘솔 로그를 가져오려면 어떻게 해야 합니까? (0) | 2023.04.16 |
Dispatch Queue.main.async와 Dispatch Queue.main.sync의 차이점 (0) | 2023.04.16 |
저장 프로시저란 무엇입니까? (0) | 2023.04.16 |
"Write-Host", "Write-Output" 또는 "[console]"의 차이점은 무엇입니까?: WriteLine? (0) | 2023.04.16 |