나는 이미 꽤 많은 것이 있기 때문에 여기에 또 다른 대답을 추가하는 것을 망설이지 않지만 명확하게 만들어지지 않았거나하지 않은 몇 가지 사항을 만들어야합니다.
첫째, 음주 하지 항상 사용합니다 NVARCHAR
. 그것은 매우 위험하고 종종 비용이 많이 드는 태도 / 접근법입니다. " 커서를 사용 하지 마십시오 "라고 말하는 것은 좋지 않습니다. 때로는 커서가 특정 문제를 해결하는 가장 효율적인 방법이기 때문에 WHILE
루프 를 수행하는 일반적인 해결 방법 은 거의 항상 올바르게 수행되는 커서 보다 느립니다 .
"항상"이라는 용어를 사용해야하는 유일한 경우는 "항상 상황에 가장 적합한 것을 항상 수행"하는 것이 좋습니다. 특히 개발 시간의 단기적인 이익의 균형을 맞추려고 할 때 (관리자 : "지금까지 알지 못했던 일주일 전부터이 기능이 필요합니다!") 균형을 잡을 때 결정하기가 어려운 경우가 많습니다. 장기 유지 보수 비용 (처음 3 주 스프린트에서 3 개월 프로젝트를 완료하도록 팀에 압력을 가한 관리자 : "이러한 성능 문제가 발생하는 이유는 무엇입니까? 유연성이없는 X를 어떻게 수행 할 수 있었습니까? 우리는 우선 순위 항목으로 돌아갈 수 있도록 일주일 동안 무엇을 할 수 있을까요? 그리고 디자인에서 더 많은 시간을 보내야만이 일이 계속 발생하지 않습니다! ").
둘째 : @gbn의 대답은 경로가 100 % 명확하지 않은 경우 특정 데이터 모델링 결정을 내릴 때 고려해야 할 매우 중요한 사항을 다룹니다. 그러나 고려해야 할 사항이 더 있습니다.
- 트랜잭션 로그 파일의 크기
- 복제하는 데 걸리는 시간 (복제를 사용하는 경우)
- ETL에 걸리는 시간 (ETL의 경우)
- 로그를 원격 시스템에 전달하고 복원하는 데 걸리는 시간 (로그 전달을 사용하는 경우)
- 백업 크기
- 백업을 완료하는 데 걸리는 시간
- 복원하는 데 걸리는 시간 (언젠가 중요 할 수 있습니다 ;-)
- tempdb에 필요한 크기
- 트리거 성능 (tempdb에 저장된 삽입 및 삭제 된 테이블의 경우)
- 행 버전 관리 성능 (버전 저장소가 tempdb에 있으므로 SNAPSHOT ISOLATION을 사용하는 경우)
- CFO가 작년에 SAN에 백만 달러를 썼으며 추가 스토리지에 대해 2 억 5 천 달러를 더 이상 승인하지 않을 것이라고 CFO가 말하면 새로운 디스크 공간을 확보하는 능력
- INSERT 및 UPDATE 작업을 수행하는 데 걸리는 시간
- 인덱스 유지 관리를 수행하는 데 걸리는 시간
- 등
공간 낭비 는 전체 시스템에 큰 영향을줍니다. 이 주제에 대한 명확한 세부 사항에 대한 기사를 작성했습니다 : Disk Is Cheap! 오랄? (무료 등록이 필요합니다. 해당 정책을 관리하지 않습니다.)
셋째 : 일부 답변은 '이것은 작은 앱입니다'측면에 잘못 초점을 맞추고 있으며 일부는 "적절한 것을 사용하는 것"을 올바르게 제안하고 있지만 답변 중 어느 것도 OP에 대한 실제 지침을 제공하지 않았습니다. 이 학교 웹 페이지입니다. 큰! 따라서 다음과 같이 제안 할 수 있습니다.
- 학생 및 / 또는 교직원 이름에 대한 필드한다 아마 있을
NVARCHAR
시간이 지남에, 그것은 단지 가능성이 다른 문화에서 이름이 그 장소에 표시됩니다지고, 이후.
- 그러나 주소와 도시 이름은? 앱의 목적은 언급되지 않았지만 (도움이 되었음) 주소 레코드가있을 경우 특정 지리적 지역 (예 : 단일 언어 / 문화)과 관련된 것으로 가정 한 다음
VARCHAR
적절한 코드 페이지 ( 필드의 데이터 정렬에서 결정됩니다).
- 주 및 / 또는 국가의 ISO 코드 (저장소 필요없이 저장하면
INT
/ TINYINT
ISO 코드가 고정되어 있기 때문에 길이, 사람이 읽을 수있는, 잘, 표준 : 사용 CHAR(2)
두 글자 코드 및 CHAR(3)
3 개 문자 코드를 사용하는 경우입니다. 그리고와 같은 이진 데이터 정렬 사용을 고려하십시오 Latin1_General_100_BIN2
.
- 우편 번호 (우편 번호)를 저장하는 경우
VARCHAR
AZ 이외의 문자를 사용하지 않는 것이 국제 표준이므로 사용하십시오. 그렇습니다. VARCHAR
우편 번호는 숫자가 아니고 문자열이며 일부는 선행 "0"을 갖기 때문에 INT가 아닌 미국 우편 번호 만 저장하더라도 여전히 사용 합니다. 그리고와 같은 이진 데이터 정렬을 사용해보십시오 Latin1_General_100_BIN2
.
- 이메일 주소 및 / 또는 URL을 저장하는 경우
NVARCHAR
둘 다 유니 코드 문자를 포함 할 수 있으므로 사용하십시오 .
- 등등....
넷째 : 이제 NVARCHAR
데이터가 잘 맞고 VARCHAR
( "좋아요"= "?"로 바뀌지 않음) 데이터에 필요한 것보다 두 배 더 많은 공간을 차지하는 데이터를 가지게되었으므로 마치 마법에 의해 응용 프로그램이 커진 것처럼 이제 대부분의 행은 표준 ASCII이지만 일부는 유니 코드 문자를 포함하므로 이러한 필드 중 하나 이상에 수백만 개의 레코드가 있으므로 NVARCHAR
다음을 고려하십시오.
당신은 SQL Server 2008을 사용하는 경우에는 - 2016 RTM을 하고 엔터프라이즈 에디션에있다, 또는 당신이 사용할 수 있습니다, 이상 (데이터 압축은 모든 버전에서 제공) SQL 서버 2016 SP1 사용하는 경우 데이터 압축을 . 데이터 압축은 필드 NCHAR
와 NVARCHAR
필드 에서 유니 코드 데이터를 압축 할 수는 있지만 "항상"압축 할 수는 없습니다 . 결정 요인은 다음과 같습니다.
NCHAR(1 - 4000)
및 NVARCHAR(1 - 4000)
사용 유니 코드 표준 압축 구성표 만 2008 R2, 및에서만 ROW 데이터를 SQL 서버에서 시작하지 OVERFLOW! 이것은 일반적인 ROW / PAGE 압축 알고리즘보다 나은 것으로 보입니다.
NVARCHAR(MAX)
그리고 XML
(나는 또한 생각 VARBINARY(MAX)
, TEXT
그리고 NTEXT
) (하지 LOB 또는 용량 초과 페이지에서 행 OFF) 이상 PAGE 압축 할 수 있지만, IN ROW 데이터입니다 하지 압축 행. 물론 PAGE 압축은 행 내 값의 크기에 따라 다릅니다. VARCHAR (MAX)로 테스트 한 결과 6000 자 / 바이트 행이 압축되지 않지만 4000 자 / 바이트 행은 압축 된 것을 확인했습니다.
- 모든 ROW 데이터, LOB 또는 OVERLOW = 압축 없음!
Enterprise Edition이 아닌 SQL Server 2005 또는 2008-2016 RTM을 사용하는 경우 하나 VARCHAR
와 하나의 두 필드를 가질 수 있습니다 NVARCHAR
. 예를 들어, 대부분 기본 ASCII 문자 (값 0-127) 인 URL을 저장한다고 가정 해 봅시다 VARCHAR
. 그러나 때로는 유니 코드 문자를 갖습니다. 스키마에는 다음 3 개의 필드가 포함될 수 있습니다.
...
URLa VARCHAR(2048) NULL,
URLu NVARCHAR(2048) NULL,
URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
AND ([URLa] IS NULL OR [URLu] IS NULL))
);
이 모델에서는 계산 열 에서만 SELECT합니다 [URL]
. 삽입 및 업데이트의 경우 변환이 들어오는 값을 변경하는지 확인하여 사용할 필드를 결정합니다.이 값은 NVARCHAR
유형 이어야 합니다.
INSERT INTO TableName (..., URLa, URLu)
VALUES (...,
IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
);
들어오는 값을 GZIP VARBINARY(MAX)
한 다음 나갈 때 압축을 풀 수 있습니다 .
- SQL Server 2005-2014의 경우 : SQLCLR을 사용할 수 있습니다. SQL # (내가 작성한 SQLCLR 라이브러리)은 무료 버전에서 Util_GZip 및 Util_GUnzip 과 함께 제공됩니다.
- SQL 서버 2016 및 최신의 경우 : 당신이 사용할 수있는 내장
COMPRESS
과 DECOMPRESS
도 Gzip으로입니다 기능.
SQL Server 2017 이상을 사용하는 경우 테이블을 Clustered Columnstore Index로 만들 수 있습니다.
아직 실행 가능한 옵션은 아니지만 SQL Server 2019에는 UTF-8 in VARCHAR
/ CHAR
datatypes 에 대한 기본 지원이 도입되었습니다 . 현재 사용할 버그가 너무 많지만 수정 된 경우 일부 시나리오에 대한 옵션입니다 . 이 새로운 기능에 대한 자세한 분석 은 내 게시물 " SQL Server 2019의 기본 UTF-8 지원 : 구주 또는 거짓 예언자 "를 참조하십시오.