SQL Server 의 데이터 형식 을 자세히 설명 합 니 다.

머리말
앞의 몇 편의 글 에서 우 리 는 색인 과 관련 된 지식 을 설명 했다.이 절 에서 우 리 는 다음 과 같은 내용 의 설명,짧 은 내용,깊이 있 는 이 해 를 계속 했다.
데이터 형식
SQL Server 는 두 가지 문자 데이터 형식 을 지원 합 니 다.하 나 는 일반적인 것 이 고 다른 하 나 는 유 니 코드 입 니 다.일반적인 데이터 형식 은 CHAR 와 VARCHAR 를 포함 하고 유 니 코드 데이터 형식 은 NCAHR 와 NVARCHAR 를 포함한다.일반적인 문자 의 모든 문 자 는 1 개의 바이트 로 저장 되 며,유 니 코드 데이터 의 모든 문 자 는 2 개의 바이트 가 필요 합 니 다.일반적인 문자 열 은 영어 에 만 바늘 로 제한 되 고 유 니 코드 는 다양한 언어 를 대상 으로 합 니 다.두 문자 데이터 형식의 텍스트 표시 방식 도 다 릅 니 다.일반적인 문자 텍스트 를 표시 할 때'Hello,my name is Jeffcky Wang,I'm from cnblogs'와 같은 작은 따옴표 만 사용 해 야 합 니 다.유 니 코드 문자 텍스트 에 대해 서 는 N'Hello,my name is Jeffcky Wang,I'm from cnblogs'를 접두사 로 지정 해 야 합 니 다.
이름 에 VAR 요소 가 없 는 모든 데이터 형식(CHAR,NCHAR)은 문자 의 실제 문자 에 따라 공간 을 유지 하 는 것 이 아니 라 열 에 따라 줄 공간 을 유지 하 는 고정 길 이 를 가지 고 있 습 니 다.예 를 들 어 특정한 열 이 CHAR(25)로 정의 하면 SQL Server 는 문자열 의 길 이 를 상관 하지 않 고 이 줄 에 25 글자 의 공간 을 유지 합 니 다.
이름 에 VAR 요 소 를 포함 하 는 데이터 형식(VARCHAR,NVARCHAR)은 가 변 길이 가 있 습 니 다.즉,SQL Server 는 저장 수요 에 따라 줄 에 가능 한 한 많은 저장 공간 을 사용 하여 문자열 을 저장 하 는 동시에 두 개의 추가 바이트 오프셋 데 이 터 를 추가 합 니 다.예 를 들 어 특정한 열 을 VARCHAR(25)로 정의 하면 이때 지원 하 는 최대 문자 수 는 25 이지 만 실제 문자열 의 실제 문자 에 따라 저장량 을 결정 합 니 다.-SQL Server 2012 T-SQL 기본 튜 토리 얼 에서 발췌 합 니 다.
유 니 코드 문자 데이터 형식 에 대해 서 는 중점적으로 이해 해 야 합 니 다.우 리 는 먼저 표를 만 듭 니 다.다음 과 같 습 니 다.

CREATE TABLE UnicodeType
(
 firstname VARCHAR(5) NOT NULL,
 lastname NVARCHAR(5) NOT NULL
);
이때 우 리 는 수 동 으로 데 이 터 를 삽입 하고 정상적으로 삽입 합 니 다.다음 과 같 습 니 다.

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '11111', -- firstname - varchar(5)
   N'     ' -- lastname - nvarchar(5)
   )
표 에 문 자 를 완전히 삽입 합 니 다.다음 과 같 습 니 다.

이때 우 리 는 firstname 을 다섯 개의 중국 어 를 삽입 해 보 겠 습 니 다.다음 과 같 습 니 다.

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '     ', -- firstname - varchar(5)
   N'     ' -- lastname - nvarchar(5)
   )
이때 다음 과 같은 결과 가 나타 납 니 다.

즉,상기 VARVHAR 와 같은 일반적인 문자 형식 에서 다섯 글자 로 정의 되 는데 이때 우 리 는 다섯 개의 중국어 문 자 를 삽입 하면 캡 처 되 고 물론 삽입 할 수 없다.위 에서 두 바이트 에 해당 하 는 비 영어 문자열 1 개 를 명 확 히 말 했 기 때문에 이때 중국어 가 10 개의 바이트 를 차지 하 는데 이때 VARCHAR 는 5 글자 밖 에 안 되 기 때문에 경고 가 나 왔 다.우 리 는 다시 firstname 을 중국어 두 개,영어 두 개,숫자 두 개 를 삽입 해 보 겠 습 니 다.

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '  1', -- firstname - varchar(5)
   N'     ' -- lastname - nvarchar(5)
   )
이때 삽입 하면 경고 가 나타 납 니 다.이때 두 개의 중국어 문자 인 네 개의 바이트 에 한 개의 숫자 바이트 가 딱 다섯 개의 바이트 가 있 기 때문에 정상적으로 삽입 할 수 있 습 니 다.우 리 는 lastname 을 다시 볼 수 있 습 니 다.위 에서 알 수 있 듯 이 영어 나 숫자 가 하나의 바이트 로 여 겨 지 는 이상 lastname 에 네 개의 중국어 문자 와 두 개의 영어 바이트 가 딱 열 개의 바이트 가 삽입 되 어야 합 니 다.어디 보 자.

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '  1', -- firstname - varchar(5)
   N'    ab' -- lastname - nvarchar(5)
   )
oh,shit,이때 오류 가 발생 했 습 니 다.다음 과 같 습 니 다.

우리 가 상술 한 분석 은 일리 가 있 고 근거 가 있 지 않 습 니까?여기 서 영 어 는 하나의 바이트 를 차지 하지 않 습 니까?우 리 는 영 어 를 삽입 해 보 겠 습 니 다.

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '  1', -- firstname - varchar(5)
   N'    b' -- lastname - nvarchar(5)
   )
결 과 는 정확 하 다.실천 은 진 리 를 검증 하 는 유일한 기준 이다.여기 서 알 수 있 듯 이 일반적인 문자 에서 하나의 중국 어 는 두 개의 바이트 로 사용 되 고 하나의 영 어 는 하나의 바이트 로 사용 되 지만 유 니 코드 에서 하나의 중국어 도 두 개의 바이트 로 사용 되 지만 하나의 영어 도 두 개의 바이트 로 사용 된다.이로써 우 리 는 개인 적 으로 유 니 코드 에서 영 어 를 하나의 바이트 로 저장 하고 식견 이 짧다 고 생각 했다 는 결론 을 얻 을 수 있다.
일반적인 문자 와 유 니 코드 의 중국어 문 자 는 두 개의 바이트 로 저장 되 며,영어 에 대해 서 는 일반적인 문 자 는 하나의 바이트 로 저장 되 며,유 니 코드 는 여전히 두 개의 바이트 로 저장 된다.
문자열 함수
문자열 에 대한 함 수 는 SUBSTRING,LEFT,Right,CHARINDEX,PATINDEX,REPLACE,REPICATE,STUFF,UPPER,LOWER,RTRIM,LTRIM,FORMAT 입 니 다.간단 한 함수 에 대해 우 리 는 생략 하고,다음은 우리 가 주의해 야 할 몇 가지 부분 을 이야기 합 니 다.
LEN 과 DATALENGTH 의 비교
우 리 는 먼저 다음 과 같은 테스트 표를 만 듭 니 다.

CREATE TABLE StringFun
(
 firststr VARCHAR(max) NOT NULL,
 secondstr TEXT NOT NULL
);
테스트 데이터 삽입

INSERT dbo.StringFun
  ( firststr, secondstr )
VALUES ( '  JeffckyWang,       ,   .NET  ', -- firststr - varchar(max)
   '  JeffckyWang,       ,   .NET  ' -- secondstr - text
   )
우선 LEN 함 수 를 이용 하여 firststr 와 secondstr 의 문자열 길이 크기 를 되 돌려 줍 니 다.

SELECT LEN(firststr) AS VARCAHRFieldSize 
FROM dbo.StringFun
SELECT LEN(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

잘 못 했 어,잘 못 했 어.LEN 함 수 는 TEXT 를 조작 할 수 없습니다.우 리 는 이어서 아래 를 내 려 다 보 았 다.

SELECT DATALENGTH(firststr) AS VARCAHRFieldSize 
FROM dbo.StringFun
SELECT DATALENGTH(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

이 때 오 류 를 알 리 지 않 았 는데 47 바이트 크기 로 나 타 났 습 니 다.LEN 이 텍스트 에 잘못 되 었 으 니 텍스트 조작 을 하지 않 으 면 됩 니 다.

SELECT LEN(firststr) AS VARCAHRFieldSize 
FROM dbo.StringFun
SELECT DATALENGTH(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

이 때 유형 이 VARCAHR 인 firststr 바이트 의 크기 는 31 입 니 다.왜 이 를 보면 우 리 는 문득 깨 달 을 것 입 니 다.상기 에서 우리 가 말 한 일반적인 문 자 는 중국어 에 한 글자 두 바이트 크기 로 저 장 됩 니 다.그러나 여기 서 실제 문자 크기 로 돌아 갑 니 다.물론 하 나 는 저장 입 니 다.하 나 는 검색 입 니까?아니면 조금 다 릅 니 다.동시에 우 리 는 중국 어 를 VARCHAR 에 저장 하지 않 을 것 이다.여기까지 우 리 는 결론 을 얻 을 수 있다.
결론:DATALENGTH 함 수 는 TEXT 에 대한 것 이 고 LEN 은 VARCHAR 에 대한 것 이 며 TEXT 에 대한 무효 보고 가 잘못 될 수 있 습 니 다.
여기까지 우 리 는 처리 하지 않 은 특수 값 이 하나 더 있 습 니 다.바로 NULL 입 니 다.그럼 문제 가 생 겼 습 니 다.LEN 과 DATALENGTH 대 NULL.길이 가 얼마 일 까요?0 일 까요?0 일 까요?0 일 까요?0 일 까요?
우리 가 테스트 해 보 자.

DECLARE @MyVar VARCHAR(10)
SET @MyVar = NULL
IF (LEN(@MyVar) = 0)
PRINT 'LEN of NULL is 0'
ELSE
PRINT 'LEN of NULL is NULL'

우리 가 상술 한 결 과 는 LEN of NULL is NULL 이 고 DATALENGTH 는 더 이상 시연 하지 않 습 니 다.
결론:LEN 과 DATALENGTH 가 NULL 에 대해 계산 한 결 과 는 NULL 이다.
우 리 는 두 사람의 차이 점 을 다시 한 번 살 펴 보 자.

SELECT LEN('JeffckyWang ') AS 'LEN'
SELECT DATALENGTH('JeffckyWang ') AS 'DATALENGTH'

결론:LEN 은 빈 칸 을 삭제 하고 DATALENGTH 는 삭제 하지 않 습 니 다.
CHARINDEX 와 PATINDEX 비교
CHARINDEX 와 PATINDEX 문자열 함 수 는 지 정 된 문자열 의 시작 위 치 를 되 돌려 주 는 것 을 조회 합 니 다.
우 리 는 먼저 문자열 을 조회 합 니 다.이 문자열 은 표 에 존재 합 니 다.다음 과 같 습 니 다.

USE AdventureWorks2012;
GO
SELECT CHARINDEX('Worn', DocumentSummary) AS 'CHARINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;
GO
SELECT PATINDEX('Worn', DocumentSummary) AS 'PATINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;

왜 CHARINDEX 함 수 는 찾 았 지만 PATINDEX 는 찾 지 못 했 습 니까?이때 이들 의 차 이 를 말 해 보 세 요.두 번 째 매개 변 수 는 모두 두 개의 매개 변수 가 있 습 니 다.두 번 째 매개 변 수 는 일치 하 는 문자열 이지 만 PATINDEX 함 수 는 일치 하 는 문자열 이 필요 하기 전이 나 그 다음 에 백분율 즉 어댑터 를 추가 해 야 합 니 다.CHARINDEX 함 수 는 필요 하지 않 습 니 다.다음 과 같 으 면 됩 니 다.

USE AdventureWorks2012;
GO
SELECT CHARINDEX('Worn', DocumentSummary) AS 'CHARINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;
GO
SELECT PATINDEX('%Worn%', DocumentSummary) AS 'PATINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;

결론:PATINDEX 일치 문자열 은 문자열 앞 이나 뒤 또는 앞 뒤에 마스크 를 추가 해 야 하 며,CHARINDEX 는 추가 할 필요 가 없습니다.
총결산
이 절 에서 우 리 는 주로 SQL 의 데이터 유형 과 몇 가지 주의해 야 할 부분,짧 은 내용,깊이 있 는 이 해 를 설명 하고 다음 절 에 다시 만 납 시다.
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 면 댓 글 을 남 겨 서 교류 할 수 있 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다!

좋은 웹페이지 즐겨찾기