이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요. 이스트럭(강동운) 입니다.

 

이번에는 커서에 대해서 소개해드리도록 하겠습니다.

 

원문1: http://www.sqler.com/127325

원문2: http://www.sqler.com/127327

 

커서는 SELECT 되는 특정 집합에 대해서 각 행에 대해 특정한 처리를 할 때 주로 사용됩니다.

예를 들어쌓여있는 우편 물을 예로 들어보겠습니다.

 

1. 쌓여있는 우편물 중 맨 위에 것 하나를 집는다.

2. 우편번호와 주소를 확인한다.

2-1. 우편번호가 있다면 체크 표시를 싸인 펜으로(이용도 입니다.) 한 후 해당 지역의

       나무 박스에 넣는다.

2-2. 우편 번호가 없다면 체크표시를 한 후 싸인 펜으로(아주 유용!) 우편번호를 우편번호

       책에서 찾아(대부분 머리 속에 있음쓴 후 나무 박스에 넣는다.

2-3. 이 작업을 쌓여 있는 우편물이 없을 때까지 계속한다.

 

SQL 서버의 데이터 처리를 다시 생각해 봅시다..

SQL서버는 모든 작업을 컬럼()기반으로 처리 합니다.

작업의 처리 방식은 컬럼에 대해서 수행 된다는 의미 입니다.

WHERE절은컬럼의 특정 값에 대해서 로우()을 선택할 뿐입니다.

여기서 또 정신적으로 많이 불안하신 분들은 이런 생각을 하실 겁니다.

identity로 컬럼을 잡은후.. 

1. identity값이 가장 낮은 녀석을 SELECT 한다.

2. identity 값을 + 1한 녀석을 SELECT 한후 가져온다없다면 +1 한 녀석을 가져온다.

3. Max 값까지 한다

이렇게 생각하시는 분도 계실 겁니다천천히 몇번을 전체 테이블을 뒤져서 처리해야

할지 생각해 보세요.

 

그렇다면..!!!

위의 우체국의 일중에서.. 쌓여있는 우편물 = 테이블의 로우(이라고 생각해 보세요.

우편물(로우)을 하나 가져와서 우편번호 체크(어떠한 처리작업 

해당하는 나무박스(테이블이나 저장소)에 넣는 작업을 우편물(로우)가 없을 때까지 계속

합니다.

 

!!  커서는 로우를 기반으로 하는 작업이 된다!!! 라는 것입니다.

저러한 로우를 하나 SELECT해서 여러가지 처리를 한후 어떠어떠한 작업을 한다~~

이것을 가능하게 하는 것이 바로!!! 커서 입니다.

물론 SQL구문만을 가지고 어거지로 어찌어찌 한다면~~ 가능할 겁니다.

하지만 커서를 이용하시면 훨씬 빠르고 간단히 저러한 처리를 가능하게 할 수 있습니다.

 

자 조금 이해가 가시나요~~

이제 커서를 왜 사용하는지.. 왜 저런 이야기를 주저리주저리 떠든건지 이해가 가실 겁니다.

 

커서는 

1. 커서 선언(Declare)

2. 커서 오픈(Open)

3. 데이터 행 가져오기(Fetch)

4. 커서 클로즈(Close)

5. 커서 선언 제거(Deallocate)

로 이루어 집니다.

 

간단히 샘플을 이용해 하나의 작업을 수행해 보도록 하지요.

샘플 데이터를 생성해 보도록 합시다.

 

 

 

CREATE TABLE 우편물(

번호 int identity(1,1)

, 우편번호 varchar(3)

, 우편주소 varchar(6)

)

 

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('001', '코난동')

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('002', '악마동')

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('003', '악어동')

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('004', '태오동')

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('', '코난동')

INSERT INTO 우편물(우편번호, 우편주소)

VALUES('', '악마동')

 

CREATE TABLE 우편번호(

우편번호 varchar(3)

, 우편주소 varchar(6)

)

 

INSERT INTO 우편번호 VALUES('001', '코난동')

INSERT INTO 우편번호 VALUES('002', '악마동')

INSERT INTO 우편번호 VALUES('003', '거북동')

INSERT INTO 우편번호 VALUES('004', '태오동')

INSERT INTO 우편번호 VALUES('005', '악어동')

 

SELECT * FROM 우편물

SELECT * FROM 우편번호

 

1.png

 

 

 

자 어떠한 데이터인지 감이 좀 잡히시지요? ^_^

데이터를 보시면대부분의 사람들이 우편번호를 잘못 넣거나 아예 넣지 않습니다.

그래서 우리의 앙마 동생이 필요했던 거지요또한 팬시 봉투를 쓸 경우 자동화 처리가

안되기 땜시 앙마 동생이 일이 더 많았다고 합니다. - 규격 봉투를 사용합시다!!

먼저 악어동은 005번인데..  003번으로 잘 못 넣었습니다.

다음으로 맨 마지막의 두건은아예 우편 번호를 넣지 않았습니다.

 

이를 어떻게 처리하면 좋을까요바로 커서를 사용해 완빵으로 마무리 지어 보지요.

 

 

 

--커서선언

DECLARE cur_konan_Test CURSOR

FOR

SELECT 번호, 우편번호, 우편주소 FROM 우편물

 

--커서오픈

OPEN cur_konan_Test

 

--변수선언

DECLARE @v_번호 INT

DECLARE @v_우편번호 VARCHAR(3)

DECLARE @v_우편주소 VARCHAR(6)

 

--첫로우FETCH

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

 

WHILE @@FETCH_STATUS = 0

BEGIN

--FETCH된데이터를tempdb에삽입

UPDATE 우편물

SET 우편번호 = (SELECT 우편번호 FROM 우편번호 WHERE 우편주소 = @v_우편주소)

WHERE 번호 = @v_번호

 

--다음로우FEETCH - 루프

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

END

 

--커서CLOSE

CLOSE cur_konan_Test

 

--커서DEALLOCATE

DEALLOCATE cur_konan_Test

GO

 

SELECT * FROM 우편물

SELECT * FROM 우편번호

2.png

 

 

 

자 우편물 테이블에서 데이터를 조회해 보세요.

어떠십니까~~~

자 지금은 간단히 수작업으루 해두 되겠네.....

만약 회사 회원이 10만명이라면아울러 전국 수만개 우편번호에서 찾아야 된다면?

충분히 닭이 될 수 있는 저런 작업을 순식간에 커서를 이용해 마무리 지을 수 있겠지요?

바로 이것이 커서를 사용하는 목적 입니다.

 

이제 커서의 샘플에 대해서 알아보도록 하겠습니다.

 

이제 실제 커서에 대해서 이야기할 때가 되었습니다.

아직도 커서를 왜 사용해야 하는지 의구심이 드는 분들이 계실 겁니다.

천천히 커서 샘플을 보시면서언제 사용을 해야할지 찬찬히 판단해 보세요. ^_^

 

자 역시나 샘플을 가지고 이야기를 해 보지요.

요 앞의 커서 입니다. ^_^

 

 

 

CREATE TABLE 우편물(

번호 int identity(1,1)

, 우편번호 varchar(3)

, 우편주소 varchar(6)

)

 

--커서선언

DECLARE cur_konan_Test CURSOR

FOR

SELECT 번호, 우편번호, 우편주소 FROM 우편물

 

 

 

자 여기서 커서를 선언 하지요? ^_^ 그러면 해당 커서는 SELECT구문을

가지고 선언 되는 겁니다글치요? ^_^

사실 커서에서 가장 중요하고 속도를 좌지우지 하며 여러 기능을 사용 가능하게

할지 말지를 결정하는 이곳이 가장 중요한 곳입니다.

여기서!!! 키 포인트 입니다.

READ ONLY FORWARD ONLY가 빠릅니다.

하지만 데이터 처리에 제약이 있습니다예를 들면.. 전진 커서만 가능하고

한  앞의 녀석을 가져오기 등을 못하는 제약 이지요.

아울러 정적 커서인 STATIC KEYSET커서 방식, DYNAMIC 커서 방식이

있는데요경우에 따라서 틀립니다만. STATIC은 사용할 데이터를 tempdb에 복사 합니다.

KEYSET 방식은 행과 순서를 고정하여 keyset이라는 키 집합이란 녀석만.

즉 테이블의 일부만을 tempdb에 저장합니다만약 데이터가 삽입되거나 삭제 된다면?

아울러 DYNAMIC커서는 모든 데이터 변경사항이 반영됩니다데이터 삽입

삭제 등이 있어도 반영이 된다는 의미 입니다.

예를들어.. STATIC으로 커서를 선언하고.. OPEN까지 한후..

데이터를 INSERT합니다그럼이 커서에서는 tempdb에 데이터가 있으므로 데이터

반영이 안된다는 것이며 DYNAMIC은 반영이 되고 이어서 KEYSET

어중간하다는 의미 입니다자세한건 아래 상세 설명을 봐 보세요.

 

 

--커서오픈

OPEN cur_konan_Test

 

 

이어서 커서를 오픈 합니다. 어떤건지 역시나 감이 오시죠? ^_^

활성화를 시킨다고 생각 하시면 됩니다.

 

이어서.. 변수를 선언합니다.

 

 

--변수선언

DECLARE @v_번호 INT

DECLARE @v_우편번호 VARCHAR(3)

DECLARE @v_우편주소 VARCHAR(20)

 

 

요런 식으로 변수를 선언 하는데요. DECLARE 로 변수를 선언하기

어렵지 않으실 겁니다여지껏 봐왔던 녀석이니까요. ^_^

 

 

--첫로우FETCH

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

 

 

커서의 또한 중요한 녀석 입니다.!!! FETCH!!!

하나의 행을 반입해서 메모리에 올린다는 의미 입니다.

자 가장 중요합니다여기서!!!!! @v_번호, @v_우편번호, @v_우편주소 변수 각각에는

어떤 녀석이 들가 있을까요?!!!!

첫행의 값인 1, 001, 코난동이 각각의 변수에 들가 있는 겁니다.!!!! 가장 중요합니다.

이걸 이해 하시면 다 이해 하신 겁니다관계형 데이터 처리인 열단위-컬럼단위

처리가 아닌 행단위 처리를 합니다.!!!

 

 

 

WHILE @@FETCH_STATUS = 0

BEGIN

           --FETCH된데이터를tempdb에삽입

           UPDATE 우편물

           SET 우편번호 = (SELECT 우편번호 FROM 우편번호 WHERE 우편주소 = @v_우편주소)

           WHERE 번호 = @v_번호

 

이어서 나타난 난적 같은 녀석... 하지만 암것도 아닙니다.

WHILE @@FETCH_STATUS = 0 요녀석은!!! @@FETCH_STATUS 바로 요건

행 반입 상태를 의미 합니다.!!!

반환 값

설명

0

FETCH 문은 성공적이었습니다.

-1

FETCH 문은 실패했거나 행이 결과 집합의 범위를 벗어났습니다.

-2

반입된 행이 없습니다.


요렇게!!! 0일 경우성공 했을 때만!!!! 아래 구문을 수행하고

성공이 아니면에러이너나.. 더이상 가져올 행이 없을때!!! 테이블의 모든 데이터를 가져 왔을때!!!

WHILE 루프를 벗어나는 겁니다.

자 여기서 중요사항!!!

UPDATE 우편물 
SET 
우편번호 = (SELECT 우편번호 FROM 우편번호 WHERE 우편주소 = @v_우편주소)
WHERE 
번호 = @v_번호

구문에서 @v_우편주소 에는 무슨 값이 있지요위의 변수 값을 봐 보세요.

이어서 @v_번호 에는 무슨 값이 있지요?  !!!

 

이해가 되시나요이게 바로 커서의 끝입니다.

 

 

 

--다음로우FEETCH - 루프

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

END

 

 

루프를 돌면서.. 계속 행을 반입하게 합니다.

루프 방식이 조금 틀리져~~

이어서..

 

 

 

--커서CLOSE

CLOSE cur_konan_Test

 

--커서DEALLOCATE

DEALLOCATE cur_konan_Test

GO

 

 

요녀석으로 커서를 닫고!!! 이어서 다 사용한 커서를 해제합니다.

이해가 되시나요? ^_^

자 아래 내용은 상세한 북스 온라인의 설명입니다.

그냥 찬찬히 읽어 보세요아주 많은 도움 되실 겁니다.

코난이 역시 실무에서는 저 템플릿 하나를 가지고 이것저것 다 한답니다.

 

중요한 것은 DECLARE CURSOR입니다.

저의 경우 대부분을 전진전용읽기 전용으로 하고 합니다.

FAST_FORWARD가 두개 선언이며 가장 빠릅니다.

 

커서의 사용 방법은 무지무지 다양할 수 있습니다코난이의 경우 배치작업 - (여기서 배치는

T-SQL문법상의 SQL구문 실행 단위가 아닌 업무에서 일반적으로 말하는 데이터의

이관작업이나 시간이 오래 걸리는 데이터 처리 작업을 말합니다.) 간에 주로 많이

이용을 합니다데이터를 정밀하게 여러가지 방법으로 처리를 할 수 있어 유용 하지요.

 

위에 정리된 내용을 하나의 형태로 합친다면.. 아래와 같이 되겠네요 ^^

 

 

--커서선언

DECLARE cur_konan_Test CURSOR

FOR

SELECT 번호, 우편번호, 우편주소 FROM 우편물

 

--커서오픈

OPEN cur_konan_Test

 

--변수선언

DECLARE @v_번호 INT

DECLARE @v_우편번호 VARCHAR(3)

DECLARE @v_우편주소 VARCHAR(20)

 

--첫로우FETCH

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

WHILE @@FETCH_STATUS = 0

BEGIN

           --FETCH된데이터를tempdb에삽입

           UPDATE 우편물

           SET 우편번호 = (SELECT 우편번호 FROM 우편번호 WHERE 우편주소 = @v_우편주소)

           WHERE 번호 = @v_번호

--다음로우FEETCH - 루프

FETCH NEXT FROM cur_konan_Test INTO @v_번호, @v_우편번호, @v_우편주소

END

 

--커서CLOSE

CLOSE cur_konan_Test

 

--커서DEALLOCATE

DEALLOCATE cur_konan_Test

GO

 

 

마지막으로 커서를 활용한 간단한 예제로  pubs db의 모든 테이블의 조회하기 위해 사용하는 예제 입니다.

 

 

 

use pubs

go

SET NOCOUNT ON

 

DECLARE cur_konan_Test CURSOR FAST_FORWARD

FOR

SELECT name FROM sysobjects WHERE xtype='U'

 

OPEN cur_konan_Test

 

DECLARE @v_name VARCHAR(100)

 

FETCH NEXT FROM cur_konan_Test INTO @v_name

 

WHILE @@FETCH_STATUS = 0

BEGIN

           SELECT 'SELECT COUNT(*) FROM ' +@v_name

FETCH NEXT FROM cur_konan_Test INTO @v_name

END

 

--커서CLOSE

CLOSE cur_konan_Test

 

--커서DEALLOCATE

DEALLOCATE cur_konan_Test

GO

 

3.png

 

 

이런 식으로 문자열 생성을 해낸후 처리할 수 있겠지요?

 

 

하지만 커서는 단점을 가지고 있습니다. SQL Server의 리소스를 많이 잡아먹을 뿐 아니라 프로그램의 성능을 떨어뜨리게 되므로 반드시 필요한 곳에서만 사용하도록 합시다.

 

SQL Server 2005부터는 이런 커서의 단점을 보완하기 위해 어느정도 CROSS APPLY 를 대체해서 사용할 수 있습니다.

 

DECLARE CURSOR(Transact-SQL): http://msdn.microsoft.com/ko-kr/library/ms180169(v=SQL.110).aspx

 

CROSS APPLY(Transact-SQL): http://msdn.microsoft.com/en-us/library/ms175156(v=SQL.110).aspx

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/400339


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?


이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.


이번에는 백업과 복구 전략에 대해서 설명드리겠습니다.

원문http://www.sqler.com/127360

 

 

 

USE master

GO

 

--백업을테스트할DB 생성

CREATE DATABASE bkupTest

 

 

먼저 테스트할 데이터베이스를 기본 옵션으로 생성합니다.

아시다시피 가장 기본적인 세팅이지요?

간단히 데이터베이스의 정보를 보도록 하지요.

 

 

 

sp_helpdb bkupTest

go

1.png

 

어떠세요흥미있게 보실 부분으로..

status라는 부분을 보시면? Recovery=FULL 이라는게 있을 겁니다.

기본 옵션으로 데이터베이스를 생성하면 복구 모델은 FULL이라는 거지요.

 

백업의 타겟은 크게 두가지로 나눌수 있습니다.

디바이스와 파일 입니다.

디바이스라는 가상의 장치 또는 테입장치 등을 연결해 백업을 하거나..

파일단위로 백업을 하실 수 있습니다.

최근의 상황을 볼때 디스크가 매우 저렴해졌지요디바이스 백업을 수행시

디바이스라는 하나의 장치에 여러 백업을 두게 되므로 편할 수 있을지 모르나..

독립적인 파일로 위치시키실 경우 조금 더 눈으로 쉽게 확인이 가능하므로

코난이의 경우 유지관리계획에 등록시켜 파일로 생성해 두는 것을 좋아 한답니다.

참고로 제가 말씀 드리는 디바이스는 영구 디바이스라고도 불리며

파일 단위 백업은 임디 시바이스라고도 합니다.

차근차근 보도록 하겠습니다.

먼저 파일로 백업하는 경우 입니다.이렇게 테이블을 생성하고 데이터를 넣은 후 백업을 진행 했습니다.

 

 

 

 

--테이블을생성합니다.

USE bkupTest

GO

 

CREATE TABLE tblBkupTest(

name varchar(10)

, age int

)

GO

 

INSERT INTO tblBkupTest(name, age) VALUES('코난', 20)

INSERT INTO tblBkupTest(name, age) VALUES('까까', 30)

GO

 

--파일로백업

SET LANGUAGE '한국어'

BACKUP DATABASE bkupTest TO DISK='C:\bkupTest.bak' WITH INIT

GO

 

 

백업 후 결과는

파일2에서데이터베이스'bkupTest', 파일'bkupTest'에대해296개의페이지를처리했습니다.

파일2에서데이터베이스'bkupTest', 파일'bkupTest_log'에대해2개의페이지를처리했습니다.

BACKUP DATABASE() 298개의페이지를0.437초동안처리했습니다(5.312MB/).

식으로 결과를 보실 수 있을 겁니다. - 결과역시 중요합니다특히 백업 수행 시각을

자세히 보는 습관을 들이세요.

복구는 어떻게 할까요간단히 해 보도록 할까요?

 

 

 

 

--테이블삭제

DROP TABLE tblBkupTest

GO

 

--데이터조회불가.

SELECT * FROM tblBkupTest

GO

 

--masterDB 사용해당DB가사용중이면복구가불가하기때문

USE master

GO

 

--복구

 

restore database bkupTest from disk ='C:\bkupTest.bak'

WITH REPLACE

GO

 

 

USE bkupTest

GO

 

--데이터조회

SELECT * FROM tblBkupTest

 

 

복구시 완료 메세지는 다음과 같을 겁니다.

파일1에서데이터베이스'bkupTest', 파일'bkupTest'에대해296개의페이지를처리했습니다.

파일1에서데이터베이스'bkupTest', 파일'bkupTest_log'에대해6개의페이지를처리했습니다.

RESTORE DATABASE() 302개의페이지를0.557초동안처리했습니다(4.224MB/).

 

역시나 주의하실 점으로 항상 복구 완료 시각을 눈여겨 보시길 바랍니다.

위의 케이스는 단순히 데이터베이스를 풀 백업 했습니다. WITH INIT은 해당 백업 타겟을

초기화 시키고 백업을 진행하라는 의미 이지요. - 백업의 여러 옵션은 천천히

다룰 겁니다.

아울러 풀 백업을 restore 구문으로 복구 했습니다.

DROP으로 날린 테이블이 잘 복구가 되었지요?

복구하기 전에 USE master 구문으로 master DB에서 복구를 진행한 이유는..

해당하는 DB가 사용중이면 복구가 불가하기 때문입니다.

만약 넷웍을 통해 사용자가 붙을 가능성이 있다면.. 잠시 사용자를..

sp_who 명령으로 SPID를 보신후.. KILL <SPID번호>로 죽이시고 수행하시면 되며

처음 SQL서버를 시작할때.. 시작 매개변수를 주어서..

sqlservr.exe -m   

형식으로 단일사용자 모드로 SQL서버 시작을 하시고.. 복구를 하시는 것도 좋은

방법 입니다.

 

계속 이야기를 진행하죠.. 파일로 백업(임시 디바이스)하고 복구하는걸 해 보셨죠..

이젠 개인적으로 별로 사용하지 않지만.. 영구 디바이스를 생성하고

백업하고 복구하는것을 해 보도록 하지요.

 

 

 

--영구백업디바이스생성

sp_addumpdevice 'disk', 'bkupTestDevice','c:\bkupTestDevice_full_bkup'

 

--디바이스로백업할때는?

BACKUP DATABASE bkupTest TO bkupTestDevice

 

 

 

결과를 보시면?

'Disk' 장치를 추가했습니다.

라는 결과와 함께 디바이스가 추가 된걸 아실 겁니다.

아울러.. 디바이스에 백업 완료시 메세지는..

파일3에서데이터베이스'bkupTest', 파일'bkupTest'에대해296개의페이지를처리했습니다.

파일3에서데이터베이스'bkupTest', 파일'bkupTest_log'에대해2개의페이지를처리했습니다.

BACKUP DATABASE() 298개의페이지를0.444초동안처리했습니다(5.227MB/).

식일 겁니다.

 

 

 

--테이블삭제

DROP TABLE tblBkupTest

GO

 

--데이터조회불가.

SELECT * FROM tblBkupTest

GO

--masterDB 사용해당DB가사용중이면복구가불가하기때문

USE master

GO

 

--복구

restore database bkupTest from bkupTestDevice

WITH REPLACE

GO

 

USE bkupTest

GO

 

--데이터조회

SELECT * FROM tblBkupTest

 

 

복구 시 메세지는 

파일1에서데이터베이스'bkupTest', 파일'bkupTest'에대해296개의페이지를처리했습니다.

파일1에서데이터베이스'bkupTest', 파일'bkupTest_log'에대해6개의페이지를처리했습니다.

RESTORE DATABASE() 302개의페이지를0.491초동안처리했습니다(4.792MB/).

식일 것입니다아울러 데이터를 조회해 보면 잘 된 것을 아실 겁니다.

많은 분들이 여기까지는 쉽게 이해하시고 잘 하시는데..

 

다음에 보시는 로그 백업에 대해서 많이 이해를 못하시지요.

이제 전략적인 측면에서.. 전체 / 로그 / 차등 백업을 이해해 보도록 하지요.

1. 풀백업만을 진행할 경우

2.JPG

먼저 이러한 타임라인이 있다고 생각해 봅시다.

주단위이며.. 위는 월요일 / 화요일 / ...  식으로 나올 겁니다.

두번째로시각은 08시부터 회사의 업무 시간인 6시까지 있을 겁니다.

이럴때 풀백업만을 진행할 경우 입니다풀 백업은 매일 아침 08시 업무가 시작되기 전에

이루어 집니다매일매일 하루에 한번씩 08시에 풀 백업을 받는 거지요!

이렇게 운영하시는 분들이 대단히 많을 겁니다문제 상황을 생각해 보지요.

1. 로그를 백업하지 않으므로 로그가 계속 불어나는 상황이 발생할 수 있다.

로그는 데이터의 변경본 입니다백업하면 지워지지만 지우지 않으므로.. 데이터는

50메가인데.. 로그는 1기가 이런 사태가 발생하게 되지요.

2. 문제 발생시 복구 가능한 데이터가 가장 적다.

실제 문제 상황을 생각해 봅시다.

3.JPG

자 이렇게 12 30분에 데이터베이스가 깨졌다고 가정해 봅시다.

언제까지의 데이터로 복구가 가능할까요? - 진짜 쉽죠? ^_^;;

가장 최근의 백업본이 월요일 08시 이니..

월요일 08시의 데이터로만 복구가 가능한 겁니다. - 물론 한번도 백업한 적이 없다면?

복구 불가 하지요. -_-;; 

08시부터 4시간 30분간의 데이터는 복구가 불가해 지는 겁니다아득하지요.

만약 다른 분 말씀으로.. "그렇다면 풀백업을 한시간에 하나씩 받으면 되자나요"

하지만.. 여기에 맹점이 있을 수 있지요.

SQL2000부터는 대단히 백업작업이 가벼워 진 편입니다온라인상에서 백업을 진행해도

큰 무리없이 진행이 가능하지요하지만.. 대부분의 일반적인 회사에서..

데이터의 용량은 대단히 큽니다어느곳은 데이터가 1기가를 훌쩍 넘기도 하지요.

만약 이럴때 한시간에 한번씩 백업을 한다면대단히 많은 부하가 걸려 백업만 하다가

시스템 리소스를 다 잡아 먹힐수도 있게 되겠지요그래서 좋은 방법이 될 수 없습니다.

다른 방법으로 풀백업 + 로그 백업의 방법이 있습니다.

 

2. 풀백업 + 로그 백업

4.JPG

이러한 식으로.. 매일 아침 08시 풀 백업.. 매시간마다 로그를 백업하는 겁니다.

그럼 어떨까요? - 이때의 제약 사항으로 SQL서버의 해당 DB는 반드시 단순 모델이 아니어야

합니다. SQL서버의 데이터베이스가 단순 모델이면로그 백업이 불가해 집니다.

샘플에서 보여 드릴 거구요..  - 전체 모델이나.. 또는 대량 로그(Bulk Load)모드 

이어야 합니다.

"저렇게 한시간에 한번씩 로그를 백업하는것도 부하가 대단히 많지 않나요?"

라고 생각하실지도 모르지만.. 로그는 대단히 그 크기가 작습니다.

예를들어 게시판을 생각해 보세요. INSERT UPDATE DELETE 작업은 대단히 작지만..

실제 내용은 수천건이 들어가 있을 수 있지요실제 회사의 기간 데이터일 경우는

더더욱 그렇습니다이제 실제 문제 상황을 생각해 보도록 하지요.

5.JPG

이럴 경우는 어디까지 복구가 가능할까요?

6.JPG

이렇게 보는 바와 같이.. 08시 부터의 데이터가 저렇다고 생각해 보도록 하지요.

08시에 풀 백업본이 있었지요풀 백업본을 리스토어 하면데이터는 어떻게 될까요?

7.JPG

네 맞습니다위와 같은 데이터가 살아나겠지요?

그러면.. 우리는 여기까지만 복구가 가능한 걸까요아니요!!!

우리에겐 로그 백업본이 있었습니다. 09시의 로그 백업본을 리스토어 하면?

네 맞습니다.

9.JPG

이렇게 데이터가 수정된 녀석으로 복구가 되겠지요?

!! 로그는 데이터의 변경이므로.. 데이터의 변경을 그대로 적용시켜 나가면?

우리의 데이터가 나오게 되겠지요!!! - 이작업을 REDO라고 말하기도 합니다.

여기서 문제 입니다. 9, 10, 11, 12시 까지의 로그를 잘 리스토어 했습니다.

10.JPG

여기까지 데이터를 잘 복구 했군요.

그렇지만.. 이후 12 20분의 데이터는?

로그를 백업하지 못했지요그러므로 복구가 불가해 지는 겁니다.

!!! SQL2000의 전체 복구 모델일 경우는 12 20분뿐 아니라... 12 29분 까지 복구가

가능합니다. - 이유는데이터베이스가 깨졌지만!!! 만약 데이터 파일만 깨지고

로그가 깨진것이 아니라면로그를 데이터베이스가 깨진 후 백업할 수 있습니다.

안될것 같지만 됩니다. - 그후!! 이 로그를 복구하면? 12 29분까지의 데이터를

복구할 수 있게 되는 것이지요.

이 샘플은 잠시 후 보여 드리기로 하구요.

마지막으로 차등 모델에 대해서 간략하게 말씀 드리지요.

3. 차등 백업

11.JPG

로그 백업의 범위는 이렇습니다정확히 마지막 로그 백업 이후의 로그 데이터를

백업하게 되지요따라서.. 09시의 로그 백업은? 08~09시 까지의 데이터 변경만을

백업하게 되며.. 10시의 로그 백업본은 09~10시 사이의 데이터 변경만을.. 식으로

백업을 하게 됩니다.

하지만 차등 백업은?

12.JPG

이러한 방식으로.. 가장 최근의 풀백업본 부터 전체 변경을 포함하게 됩니다.

! 09시의 차등 백업본은? 08~09시 까지의 데이터 변경을 가지게 되며

12시의 차등 백업본은? 08~12시 까지의 데이터 변경을 가지게 됩니다.

로그를 중복해서 가지게 된다는 의미 이지요.

하지만 중복보다도.. 어느정도의 복구 속도를 높일 수 있으며..

SQL2000부터는 비트맵 백업 방식이라고 해서 대단히 빠르게 백업이 가능하다는 장점이

있게 되었습니다하지만 역시 개인적으로는 풀백업 + 로그 백업을 선호하며

여러 장점이 있기 때문에 더 선호합니다.

차등 백업일 경우 역시나 12 30분에 데이터베이스가 깨졌다고 생각해 보도록

하지요.

13.png

이럴 경우 어떻게 복구를 하면 될까요?

08시의 풀백업본을 리스토어 합니다.

이어서!!!

12시의 차등 백업본 하나만!! 복구를 하면가능한 데이터의 복구가 된 것이겠지요.

 

자 세가지의 복구 방법을 차근차근 보신 겁니다.

이해가 되시나요?

그렇다면!!!

조금더 다른 이야기를 해 보도록 하지요.

복구 모델에 대한 이야기 입니다.

 

복구 모델

먼저 말그대로 단순한 단순 모델부터 보도록 하지요.

1. 단순 복구 모델

 

 

 

 

USE pubs

GO

 

--pubsDB의복구모델을단순으로한다.

ALTER DATABASE pubs SET RECOVERY simple

 

--풀백업수행

BACKUP DATABASE pubs TO DISK = 'c:\pubsFull' WITH INIT

 

--데이터조회

SELECT TOP 1 title_id, price FROM titles

 

--조회된값은? - 꼭적으세요.

 

--데이터수정

UPDATE titles SET price = price * 2

 

--데이터조회조회된값꼭적으세요.

SELECT TOP 1 title_id, price FROM titles

 

--복구모델이단순일경우로그백업이가능한가?

BACKUP LOG pubs TO DISK = 'c:\pubsLog' WITH INIT

 

--불가능 하다.

Msg 4208, Level 16, State 1, Line 1

복구모델이단순이면문BACKUP LOG(사용할수없습니다. BACKUP DATABASE를사용하거나ALTER DATABASE를사용하여복구모델을변경하십시오.

Msg 3013, Level 16, State 1, Line 1

BACKUP LOG(비정상적으로종료됩니다.

 

--SQL서버시스템종료SHUTDOWN

 

--탐색기등으로pubs의데이터파일인

--mdf 파일을지우자.

--C:\Program Files\Microsoft SQL Server\MSSQL\Data

--이기본경로이다.

 

--다시SQL서버를시작한다.

 

 

 

 

SQL서버를 시작하면 당연히 문제가 있습니다. PubsDB를 로드할 수 없다고 나오지요.


 

이런 식으로요..

pubs - 주의대상 - 바로 공포의 서스펙트 모드라고 하는 혼수상태 입니다.

이렇게 데이터베이스 이름이 나오는 이유는데이터베이스 이름과 같은 정보는

바로 MasterDB에 있기 때문입니다.

여하간 우리가 mdf 파일을 지웠으니 당연한가요이제 복구를 해 보도록 하지요.

 

 

 

 

 

--master DB 에서작업한다.

USE master

GO

 

--복구를진행하자.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull.bak'

GO

 

 

use pubs

go

 

--데이터조회

SELECT TOP 1 title_id, price FROM pubs..titles

 

 

자 복구를 하고 조회를 해 보았습니다값이 얼마가 나왔죠?

BU1032 19.9900 

의 값이 나왔을 겁니다왜 그렇죠?

위에서 분명히 UPDATE를 한번 하지 않았나요?

하지만.. 우리가 UPDATE를 하기 전에 풀 백업을 진행 했지요?

아울러 로그 백업도 불가했고 데이터베이스가 깨진 이후에도 아무것도 할 수 없었기

때문에 오로지 가장 최근의 풀 백업본 까지만!!! 복구가 가능한 겁니다.

이게 바로 단순 모델입니다. - 물론 로그 백업 자체가 불가합니다.

하지만 자동으로 로그를 비워주니 로그가 한없이 커지는 사태는 발생하지 않지요.

다음으로 대량 로그 모델을 봐 보도록 할까요?

 

2. 대량 로그 모델

먼저 샘플텍스트화된 파일  을 다운로드 받으세요.

압축을 푸시면 titles.txt titles2.txt 파일이 있습니다.

아래 샘플에서 사용되니 이두 녀석을 c:\ 에 두시길 바랍니다.

 

 

 

 

 

--pubs DB를대량로그모델로바꾼다.

ALTER DATABASE pubs SET RECOVERY bulk_logged

 

--데이터베이스를풀백업한다.

BACKUP DATABASE pubs to DISK = 'c:\pubsFull' WITH INIT

 

--데이터를조회한다.

SELECT TOP 1 title_id, price FROM pubs..titles

--조회된값은?

 

--가격을*2 한다.

UPDATE pubs..titles SET price = price * 2

 

--데이터를조회한다.

SELECT TOP 1 title_id, price FROM pubs..titles

--조회된값은?

 

--BULK 작업을한다.

--다운로드받은titles.txt 파일을c:\에둔다. - SQL7에서

--BULK 작업은로그에남지않았으나SQL2000에서는남는다.

--일반적인INSERT, UPDATE, DELETE는기본적으로로그에남는다.

--그리고작업한다.

BULK INSERT pubs..titles FROM 'c:\titles.txt'

 

--데이터를조회한다.

SELECT top 2 title_id, price FROM pubs..titles

--Bulk INSERT로삽입된값은BU1001 39.98이다.

--SQL7과틀리게sp_dboption없이BULK INSERT가가능하다.

 

--로그를백업하자. - BULK INSERT가로그에남을까남지않을까?

--SQL7까지는LOG에남지않는작업이었다.

BACKUP LOG pubs TO DISK = 'c:\pubsLog' WITH INIT

 

--다시하나의데이터를BULK INSERT로넣자.

--지금넣는값은title_idBU1002이며가격은23.9 이다.

BULK INSERT pubs..titles FROM 'c:\titles2.txt'

 

--데이터를조회해보자.

SELECT top 3 title_id, price FROM pubs..titles

--조회된값은?

 

 

자 이 샘플에서 언급하는 조회되는 값을 잘 적어 두시길 바랍니다.

그래야 어디까지 복구가 가능한지 알 수 있지요.

이제 복구 작업을 진행해 보도록 하지요.

 

 

 

--다시SQL서버를시작시키자.

USE master

GO

 

--데이터가조회가능한가? - 불가하다.

SELECT TOP 3 title_id, price FROM pubs..titles

 

--데이터베이스를복구하자.

--현재풀백업본을복구하는것이다.

--이후LOG를복구할게더있으므로옵션으로

--WITH NORECOVERY를붙인다.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull'

WITH NORECOVERY

 

--로그를복구하자.

--이때마지막복구본이므로

--WITH RECOVERY 옵션을준다.

RESTORE LOG pubs FROM DISK = 'c:\pubsLog'

WITH RECOVERY

 

--데이터를조회해보자.

SELECT TOP 3 title_id, price FROM pubs..titles

 

 

데이터를 맨 마지막에 조회해 보니 어떤가요?

대량 로그 백업 샘플에서는 분명히 마지막에 어떤 값이었지요?

BU1001, BU1002, BU1032였을 겁니다분명히 LOG BULK INSERT의 데이터가 남았기

때문에 BU1001이 보이지요또한 두번째 BULK INSERT BU1002값은?

추후 로그를 백업하지 않았기 때문에 볼 수 없지요.

따라서.. 대량로드 작업에서는 가장 최근의 로그 백업본 까지만!!! 

복구가 가능한 겁니다.

이제 전체 모델을 봐 보도록 하지요.

 

3. 전체 모델

 

 

 

--사용된데이터베이스를최초상태로복구합니다.

--맨처음단순모델할때사용했던백업본입니다.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull'

 

--다음풀모델을위해풀백업을진행합니다.

BACKUP DATABASE pubs TO DISK = 'c:\pubs1' WITH INIT

 

--데이터를조회해보면?

SELECT TOP 1 title_id, price FROM pubs..title

--조회된값은?

 

--price*2 합니다.

UPDATE pubs..titles SET price = price * 2

 

--BULK INSERT로데이터를넣습니다값은BU1001입니다.

BULK INSERT pubs..titles FROM 'c:\titles.txt'

 

--데이터를조회하면?

SELECT TOP 2 title_id, price FROM pubs..titles

--조회된값은?

 

--로그를백업합니다.

BACKUP LOG pubs TO DISK = 'c:\pubsLog' WITH INIT

 

--또다시BULK INSERT를합니다.

BULK INSERT pubs..titles FROM 'c:\titles2.txt'

 

--데이터를조회하면?

SELECT TOP 3 title_id, price FROM pubs..titles

--조회된값은?

 

--시스템셧다운

SHUTDOWN

 

--pubsmdf 파일을삭제합니다!

--ldf 파일은건드리지마세요.

 

 

mdf 파일을 삭제 했습니다조회된 값은 얼마죠?

BU1001, BU1002, BU1032일 겁니다그렇죠?

그럼 이제 복구를 해 볼까요?

 

 

 

 

--복구를진행합니다.

USE master

GO

 

--데이터를조회가가능한가요? - 불가합니다.

SELECT TOP 2 title_id, price FROM pubs..titles

 

--로그를백업합니다.

--바로풀백업의중요한부분으로

--문제가발생해도로그가깨지지않았다면?

--로그가백업이됩니다.

--이때반드시WITH NO_TRUNCATE 옵션이필요합니다.

--INIT는초기화시켜백업하라는옵션이지요.

BACKUP LOG pubs TO DISK = 'c:\pubsLogNoTrunc' WITH NO_TRUNCATE, INIT

--로그백업이성공합니다.

 

--데이터베이스를복구해보도록하지요.

--복구할게더있으니NORECOVERY로합니다.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull'

WITH NORECOVERY

 

--로그를복구해보도록하지요.

--복구할게더있으니NORECOVERY로합니다.

RESTORE LOG pubs FROM DISK = 'c:\pubsLog'

WITH NORECOVERY

 

--로그를복구해보도록하지요.

--이로그는? pubs가깨진후로그만백업한것이죠?

--위에서옵션인WITH NO_TRUNCATE옵션으로백업한로그입니다.

--복구할게더이상없으니RECOVERY로합니다.

RESTORE LOG pubs FROM DISK = 'c:\pubsLogNoTrunc'

 

--데이터를조회해보면?

SELECT TOP 3 title_id, price FROM pubs..titles

--어디까지복구가되었나요?

 

 

 

 

자 여기까지 보셨으면 이제 다 보신 겁니다.

어떠세요데이터 백업 + 로그백업 이해 되시나요?

아울러 SQL2000의 새로운 복구 모델 세가지두 이해 되시구요?

그럼 이제 많이 받는 질문인....  개발자나 관리자의 실수로..

WHERE절 없이 DELETE UPDATE를 쳐 버렸을때 복구하는 방법을 말씀 드리지요.

 

4. STOPAT을 이용한 복구

이때는 반드시 모델이 전체 모델 또는 대량 로그 이어야 합니다.

 

 

 

 

--데이터베이스를초기화시키기위해리스토어합니다.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull'

 

--데이터베이스를풀백업합니다.

BACKUP DATABASE pubs TO DISK = 'c:\pubs1' WITH INIT

 

--데이터를조회합니다.

SELECT TOP 1 title_id, price FROM pubs..titles

--초기화가잘되었는지확인하는겁니다.

 

--데이터를하나삽입합니다.

BULK INSERT pubs..titles FROM 'c:\titles.txt'

 

--데이터를조회하면?

SELECT TOP 2 title_id, price FROM pubs..titles

--조회된값은?

 

--로그를백업해보도록하지요.

BACKUP LOG pubs TO DISK = 'c:\pubsLog' WITH INIT

 

--역시나데이터를하나더넣도록합니다.

BULK INSERT pubs..titles FROM 'c:\titles2.txt'

 

--데이터를조회하면?

SELECT TOP 3 title_id, price FROM pubs..titles

--조회된값은?

 

--!!자이제문제상황입니다.

--개발자의실수로UPDATEWHERE절없이쳐버렸습니다.

UPDATE pubs..titles SET price = 0

 

--컨트롤+ Z는아무리눌러도데이터는복구안됩니다.

SELECT title_id, price FROM pubs..titles

 

--바로문제가발생한시각을알아야만합니다.

SELECT GETDATE()

--결과시각은?

--코난이의경우아래와같은시각입니다.

2011-06-17 00:00:13

 

--어떻게해야할까요?

--1. 즉시로그를백업합니다.

--2. STOP AT 구문으로복구합니다.

 

--로그를백업합니다.

BACKUP LOG pubs TO DISK = 'c:\pubsLogNoTrunc' WITH NO_TRUNCATE, INIT

 

--데이터베이스를복구합니다.

--이때첫번째로그백업과.. 문제가발생한후로그백업사이로

--복구를진행해야합니다그렇지요?

--STOP AT을적절히사용하도록하지요.

--풀백업본을리스토어합니다.

RESTORE DATABASE pubs FROM DISK = 'c:\pubsFull'

WITH NORECOVERY

 

--첫번째로그백업본을복구합니다.

RESTORE LOG pubs FROM DISK = 'c:\pubsLog'

WITH NORECOVERY

 

--문제가발생한후로그를백업한것입니다.

--약간특이하게STOP AT이있습니다.

--시각지정은.. 문제가발생한시각- 1분정도로하겠습니다.

--2001-08-23 16:06:14.320 빼기1

--그래야만.. 문제가발생하기바로전시각으로되돌릴수있겠지요?

--당연히문제가발생한후즉시알아야만데이터손실을그만큼줄일수있겠죠

--한일주일정도지난후문제가발생한걸알고.. 또한

--중요한회원데이터였다면생각하기도끔찍해지겠지요.

RESTORE LOG pubs FROM DISK = 'c:\pubsLogNoTrunc'

WITH STOPAT = '2011-06-17 00:00:13.320', RECOVERY

 

--데이터를조회해보면?

SELECT TOP 3 title_id, price FROM pubs..titles

--원하는데이터인BU1001, BU1002, BU1032가맞습니까?

 

 

어떠세요?

이제 STOPAT을 어떻게 사용하는지 감이 좀 잡히시나요? ^_^

.. 그러면!!

이제 자동화를 이용해서 이러한 백업과 리스토어를 쉽게 하는 이야기를 조금

드려 보지요.

데이터베이스 유지관리 계획은.. 총체적으로 데이터베이스를 유지 관리하기 위한

기능입니다.

백업 / 인덱스 구축 등등의 관리자의 손이 개입되어야 하는 작업들을..

자동적으로 수행할 수 있게 도움을 주는 매우 유용한 기능입니다.

 

우리는 풀백업을 일정으로 만드는 방법에 대해서 한번 알아보도록 하겠습니다.

 

우선 SQL Server Agent 가 중지된 경우에는 아래와 같은 방법으로 실행합니다.

99.png

 

SQL Server Agent가 실행 중이면이렇게 해당 DB에서.. Maintenance Plan Wizard를 선택합니다.

100.png

 

Maintenance Plan Wizard를 실행하면 아래와 같은 그림이 나오는데 다음을 누릅시다.

101.png

 

102.png

 

여기서는 각각의 작업마다 스케줄을 나눠서 셋팅 하는 방법과

하나의 스케줄로 작업을 만드는 방법이 있습니다.

일단 저희는 아래거인 하나의 스케줄로 만들고 Change를 눌러서 일정을 선택합시다.

103.png

 

일정 선택 화면 입니다.

1.     스케줄 타입에는 총 4가지가 있습니다.

103-1.png

 

Start automatically when SQL Server Agent starts: SQL Server Agent가 시작했을 때 자동으로 수행

Start whenever the CPUs become idle: CPU가 유휴상태가 될 때마다 시작

Recurring: 반복 수행

One time: 한번

 

2.     Frequency(빈도는 총 3가지가 있습니다일별주별월별입니다빈도에 따라서 설정할 수 있는 방법이 다양하게 나타납니다.

 

보통 풀 백업은 하루에 한번.. 트랜잭션 로그 백업은 30분 또는 1시간에 한번씩 백업 받는 것이 좋습니다예를 들어 새벽 3시에 풀 백업을 받고, 1시간 마다 트랜잭션 로그 백업을 하면서.. 오후 11시 데이터로 복원을 해야 한다면복원하는데 상당히 귀찮을 수 있습니다만약 복원을 자주 해야 한다면차등 백업도 함께 이용하는 것도 좋은 선택이라고 생각이 됩니다.

 

저희는 풀백업을 셋팅하는 것이기 때문에.. 스케쥴 타입은 Recurring(반복과 빈도는 일별을 선택하고 매일 오전 3시에 수행되도록 셋팅 합니다.

 

아래와 같이 설정이 되겠지요~!

103-2.png

 

 

일정을 셋팅한 뒤에 OK를 눌러서 창을 닫습니다.

 

그리고 Next 를 누르면 아래와 같은 화면이 나타나게 됩니다.

 

104.png

 

저희가 하고자 하는 것은 풀 백업이기 때문에 Back up Database(Full)을 선택을 하고Next를 선택합시다.

 

105.png

 

이번 화면은 실행 순서를 정하는 화면입니다만약 이전 창에서 여러 개를 선택한 경우여기서 실행 순서를 결정할 수 있습니다.

 

저희는 하나 밖에 없기 때문에 바로 Next를 누릅시다.

106.png

 

이번 화면에서 상단에 Database(s)를 누르면 내가 백업하고 싶은 Database를 선택할 수 있습니다.

그리고 나서 Backup set will expire를 통해 특정 일자 후에 자동으로 삭제할 수 있도록 설정할 수 있습니다.

 

그리고 저희는 Back up to  disk 그리고 Create a backup file for every database 를 선택하고, Create a sub-directory for each database(각각의 데이터베이스를 위한 서브 폴더 생성)을 체크하고 백업할 디렉토리를 선택합시다.

아래와 같은 그림이 되겠죠~!

106-1.png

 

그리고 나서 Next 를 누릅시다.

107.png

 

이번에는 백업된 결과를 Text 또는 이메일을 통해 받을 수 있는 부분을 셋팅 합니다.

 

Next를 누릅시다.

 

108.png

 

마지막으로 Finish를 누릅시다 ^^

 

109.png

 

위의 화면이 나오면 정상적으로 스케쥴이 생성된 것입니다.

 

복잡하면서도 간단한 백업 셋팅이 완료되었습니다.

 

트랜잭션 로그 백업 설정도 비슷하게 하실 수 있겠지요? ^^

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/395926

 

SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?


이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

오늘은 SQL Server에서 백업과 복구에 대해서 설명드리겠습니다.

 

원문http://www.sqler.com/127358

 

이번에 소개해 드릴 내용은 백업과 복구 입니다.

백업 / 복구라는 단어는 대부분의 이 글을 보시는 SQLER 님들은 한번씩

들어 보셨을 겁니다그렇다면 질문 입니다.

 

1. 백업과 복구를 주기적으로 하시는지요?

2. 사용자의 데이터베이스뿐 아니라.. MASTER, MSDB, MODEL 디비 역시 

정기적으로 백업을 받으시는지요?

3. 복구 모델을 적절히 이해 하시는지요?

 

이에 대한 글입니다.

첫 번째 글인 1. 백업과 복구에 대한 이해는 기술적인 부분이 아닌 조금 더 상황적인

이야기를 진행하려 합니다천천히 이야기를 진행해 보도록 하지요.

 

백업이란 무엇인가?

백업은 간단히 데이터를 복사해 둔다는 의미 입니다.

물론 그냥 복사 하는게 아니라 정확히가능한 많은 데이터를 문제가 발생시 복구하기 위해

복사본을 만들어 두는 겁니다.

 

 

전체백업 = 풀백업과 같은말이며

차등백업 = 디퍼런셜 백업과 같은 말입니다혼동하지 마시구요..

 

SQL Server는 복구 모델이라고 해서 3가지 방식을 제공합니다.

1.     단순

2.     대량 로그

3.     최대

 

엔터프라이즈 관리자의 아무 데이터베이스에서 등록정보 -> 옵션 탭을 보시면

 

 

 

1.png

 

 

 

Full: 전체

Bulk-logged: 대량 로그

Simple: 단순

 

이러한 화면을 볼 수 있지요.

복구 모델은 데이터베이스를 특정 상태로 지정하는 것입니다.

내부적인 깊은 모델 비교는 다음에 기회가 생기면 해 보도록 하구요.

여기서는 그 기능성과 복구 가능 범위에 초점을 맞추도록 하겠습니다좀더 실질적인

이야기가 되겠지요.

 

약간 이야기를 건너서..

로그가 뭔가요제가 데이터베이스 강좌를 하면서 로그에 대해서 말씀 드렸지요.

로그는 데이터의 변경이 저장되는 곳입니다.

따라서 대부분의 경우 실제 데이터에 비해서 로그의 크기는 매우 작습니다.

데이터의 변경보다 대부분의 경우 데이터 조회가 훨씬 더 많으니까요.

일반적인 게시판을 생각해 보신다면 좋겠지요.

 

로그는 백업하면 비워집니다. - 지워진다기 보다는 비워진다는게 정확합니다.

껍데기는 그대로 이며 오로지 로그 데이터만이 비워지기 때문입니다.

만약 로그를 한번도 백업을 받지 않으셨다면?

다음 그림처럼.. 약간 이상한 상태를 보게 되지요.

 

2.png

대단히 흥미 있게도..데이터는 54메가 인데..

트랜잭션 로그는 한번도 백업을 받지 않았기 때문에 트랜잭션 로그 공간은

2.4 기가 가까이 됩니다.  로그는 매우 작은 분량임에도 불구하고 한번도 로그를 

백업하지 않아 생기는 상황입니다사용되는 공간도 문제이지만 로그 데이터로 인해

시스템이 대단히 느려지는 사태 역시 발생할 수 있게 되지요.

 

만약 SQLER님들중 관리하고 계신 시스템이 있다면 이렇게 검사를

해 보시길 바랍니다위의 화면을 보시려면..

엔터프라이즈 관리자에서 해당 DB를 클릭하신후.. 왼쪽 맨위의 매뉴중

보기 -> 작업창을 보시면 위의 그림을 보실 수 있습니다.

 

위의 상황을 해결하시려면..

1.예를들어 pus 디비라면..

 

 

use pubs

go

 

DBCC SHRINKFILE (pubs_log, TRUNCATEONLY)

 

 

명령으로 로그를 비워낸후 불필요하게 커져버린 로그 화일의 크기를 줄일 수 있습니다.

 

2. 두번째로 코난이가 조금더 선호하는 확실한 방법으로..

 

 

 

--작업을수행하기전만약을위해풀백업을받는다.

--해당하는DBdetach로떼어낸다.

EXEC sp_detach_db 'pubs', 'true'

 

--잠시ldf 화일의이름을바꿔두자. - 만약을위해지우지않는다.

--mdf 화일만으로다시붙인다.

--이때ldf(로그화일)화일은최소크기인1M로재생성된다.

EXEC sp_attach_single_file_db 'pubs'

, 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs.mdf'

 

 

이런 방법도 있으니 참고 하시길 바랍니다.

 

다음으로 복구의 모델 세가지를 알아 보도록 합시다.

복구 가능 분량에 대해서 보는게 좋겠지요.

최대 모델 : 가장 많은 데이터를 복구할 수 있습니다.

실제 문제가 발생한 시각까지의 모든 데이터를 복구가 가능합니다.

대량로그 : 마지막 로그 백업 때까지만 복구가 가능합니다.

단순 : 이 모델로 지정시 로그 백업이 불가하므로 오로지 마지막 전체 백업시 까지만

복구가 가능합니다.

 

 

또한 종종접하는 문제 상황 발생시의 해결 방법을 알아 보도록 하지요.

Q. 현재 웹사이트를 개발하는 중입니다개발중이라 한번도 백업을

받은적이 없습니다. 개발자의 실수로 update 회원테이블 set 이름 = '아무개'

 WHERE절 없이 update를 해 버렸습니다복구할 방법이 없을까요?

A. 복구는 불가합니다.

 

Q. 지속적으로 전체 백업만을 받아 왔습니다.

개발자의 실수로 update 회원테이블 set 이름 = '아무개'

 WHERE절 없이 update를 해 버렸습니다복구할 방법이 없을까요?

A. 제약 조건이 있습니다. 1. 복구 모델이 전체 모델일것(DB를 생성하면 기본입니다.)

2. 문제 발생후 풀백업이나 로그에 쓰지 않는 작업을 하지 않았을것

3. 로그 백업이 가능할것 입니다.

만약 이 세 조건이 맞다면 바로 로그를 with no_truncate 옵션으로 백업하신후..

Stop at 명령으로 복구할 수 있습니다.

 

Q. 풀백업과 로그백업을 혼용해 지속적으로 백업하고 있습니다.

개발자의 실수로 update 회원테이블 set 이름 = '아무개'

 WHERE절 없이 update를 해 버렸습니다복구할 방법이 없을까요?

A. 가능합니다

1. 복구 모델이 전체 모델일것(DB를 생성하면 기본입니다.)

2. 문제 발생후 풀백업이나 로그에 쓰지 않는 작업을 하지 않았을것

이 두 조건이 맞다면 즉시 로그를 with no_truncate 옵션으로 백업하신후..

Stop at 명령으로 복구할 수 있습니다.

 

Q. 이전 서버에서 사용하던 시스템의 문제로 해당하는 데이터베이스의

mdf 화일과 ldf 화일만 남았습니다새로 설치하는 시스템에 복구가 가능할까요?

A. 이전 서버와 문자셋 정보(sp_helpsort 명령으로 보실수 있습니다.)가 같고

이전에 사용하던 SQL서버가 정상적인 상태로 종료 되었을때(엔터프라이즈 관리자에서

SQL서버를 스탑 시켰거나.. 정상적으로 윈도우 시스템을 종료시킨 경우 - 해당

mdf 화일과 ldf 화일이 정상적으로 닫혔을 경우복구가 가능하며 이때 사용하는 명령은

 

 

 

 

EXEC sp_attach_db 'pubs'

, 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs.mdf'

, 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs_log.ldf'

 

명령으로 복구할 수 있습니다.

 

Q. 이전 서버에서 사용하던 시스템의 문제로 해당하는 데이터베이스의

mdf 화일만 남았습니다새로 설치하는 시스템에 복구가 가능할까요?

A. 가능합니다.

이전 서버와 문자셋 정보(sp_helpsort 명령으로 보실수 있습니다.)가 같고

이전에 사용하던 SQL서버가 정상적인 상태로 종료 되었을때(엔터프라이즈 관리자에서

SQL서버를 스탑 시켰거나.. 정상적으로 윈도우 시스템을 종료시킨 경우 - 해당

mdf 화일이 정상적으로 닫혔을 경우복구가 가능하며 이때 사용하는 명령은

 

 

 

EXEC sp_attach_single_file_db 'pubs'

, 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs.mdf'

 

 

명령으로 복구하실 수 있습니다.

 

Q. 이전시스템에서 사용하던 풀 백업본이 있습니다.

새로 시스템을 설치한후 이 풀 백업본을 복구하려 하는데 방법이 없을까요?

A. 가능합니다.

약간 다른 방식으로 아래처럼 하심 됩니다.

1. 같은 이름의 db를 만든다 (텅빈 db)

2.  db를 그냥 풀 백업 한다.

3. 원본서버에서 가져온 백업본으로 리스토어 한다.

4. 리스토어시 옵션의 강제로 덮어쓰기 하시면 됩니다.

의 순서로 진행하시면 무리없이 하실 수 있습니다.

 

자 이렇게 많이 받는 백업과 복구에 대한 질문을 들었습니다.

조금 귀찮을 수 도 있지만..

바로 뒤에서 자동화를 이용해 스케쥴로 SQL서버에 대한 백업을 진행할 수 있으니..

별로 신경 안쓰시고 모든 작업이 가능해 지실 겁니다.

그럼 다음 이야기 백업의 전략에서 실제 백업과 복구에 대해서 공부를 해 보도록

하지요.

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/394749


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?



SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

오늘은 트랜잭션에 대해서 알아보도록 하겠습니다.

 

원문http://www.sqler.com/127372

 

트랜잭션이라는 녀석과 잠금이라는 녀석은 대단히 밀접한 관계가 있습니다.

-- 그럼 강좌를 마치겠습니다.

라고 하면 물론 집에 가는 길에 등뒤에서 번쩍이는 칼을 보게 될지도 모르니..

계속 진행하겠습니다. -_-;;

 

잠금을 설명할 때 좋은 샘플이 있습니다.

예를 들어.. 공유 폴더에 워드 문서를 두시고..

워드 문서를 오픈 하고.. 다른 사용자나.. – 한번 더 워드 파일을 오픈 하면?

다른 프로세스나 사용자가 현재 해당 파일을 오픈 하고 있습니다

읽기 전용으로 여시겠습니까라는 메세지와 함께 

파일은 읽기 전용으로 열리거나 열수 없을 것입니다.

이런 상황이 바로 잠금의 개념과 비슷합니다.

두 사용자가 모두 쓰기를 해 버리면어느 것을 적용시켜야 할지 알 수 없겠지요?

DB의 경우라면 더더욱 큰 문제가 됩니다.

기본적으로 병행DBMS는 기본적으로 여러 명의 사용자프로세스가 붙어서 작업을

하게 되니 위와 같은 병행처리는 기본적으로 제공이 되어야 하지요.

그 개념이 바로 잠금이며 SQL서버는 이 잠금이 대단히 다양하고 세분화 되어 있습니다.

차근차근 봐 나가도록 하지요.

 

먼저 잠금 내역을 봐 보도록 할까요?

억지로 잠금을 보실 수 있는 쿼리 입니다.

 

 

--//1번 세션

use pubs

go

 

--가격* 2

begin tran

update titles set price = price * 2

 

 

 

--//2번 세션

 

--하나의창을더오픈한다.

--파일-> 연결을하고같은서버에접속한다.

use pubs

go

 

--데이터조회

select * from titles

 

--조회가불가하다.

 

 

 

 

 

 

--//3번 세션

 

--하나의창을더오픈한다.

--파일-> 연결을하고같은서버에접속한다.

use pubs

go

 

--잠금정보를조회한다.

sp_lock

 

1.png


 

맨처음 보시는 쿼리는 begin tran으로 트랜잭션 범위 내에서 시작하고 commit이나

rollback 등 트랜잭션 끝 이라는 키워드가 없습니다.

트랜잭션 중으로 하겠다는 것이지요그리고 이때 다른 사용자는 계속 pubs에서

대기하게 되는 겁니다. - 나중에 배우시겠지만 블러킹(Blocking)이라고 합니다.

바로 현재 spid 53번인 부분에 Status WAIT인 것을 볼 수 있습니다.

 

자 그러면 조금더 sp_lock 한 결과를 조금 봐 보도록 하지요.

먼저 type으로 잠금의 타입인데요잠금이 걸리는 형식 입니다.

보시면 DB, PAG, KEY, TAB등이 있지요.

 

잠금이 걸리는 단위는 무엇일까요?

이 단위를 상세하게 알아 보도록 하지요.

리소스 유형

설명

RID

테이블에 있는 한 행을 잠그기 위한 행 식별자입니다.

KEY

인덱스에 있는 행 잠금입니다순차 가능한 트랜잭션에서 키 범위를 보호하기 위해 사용합니다.

PAG

데이터 또는 인덱스 페이지입니다.

EXT

인접한 여덟 개의 데이터 페이지 또는 인덱스 페이지 그룹입니다.

TAB

모든 데이터와 인덱스가 포함된 전체 테이블입니다.

DB

데이터베이스입니다.

이렇게 잠금이 걸릴 수 있습니다.

로우페이지익스텐츠등으로 조금더 다양 하지요~

SQL서버는 이렇게 잠금의 단위를 쿼리에 따라서 자동으로 설정합니다.

물론 사용자가 개입해서 잠금을 걸 수도  있습니다하지만 이렇게 사용자가 잠금을

거는것은 거의 권장되지 않으며 오로지 BCP, Bulk insert등과 같은 대용량 벌크 작업시

TABLE Lock을 걸 경우를 걸때를 제외하고는 권장하지 않습니다.

벌크작업시는 걸고 하셔야만 제속도를 얻을 수 있습니다. - 많은 분들이 아마 모르셨을듯..

간단히 사용자가 직접 정의해 잠금을 거는 샘플을 보여 드리면..

 

 

 

use pubs

go

 

begin tran

select * from authors (ROWLOCK) where au_id = '172-32-1176'

 

 

이렇게 사용이 가능하며..

잠금의 힌트로 사용 가능한 옵션들은...  아래와 같습니다.

잠금 참고

설명

HOLDLOCK

필요한 테이블행 또는 데이터 페이지가 더 이상 필요 없게 되자마자 해제하지 않고 트랜잭션이 완료될 때까지 공유 잠금을 보유합니다. HOLDLOCK SERIALIZABLE과 같은 의미입니다.

NOLOCK

공유 잠금을 실행하거나 단독 잠금을 유지하지 않습니다이 옵션을 적용하면 커밋되지 않은 트랜잭션이나 읽는 중 롤백된 페이지 집합을 읽을 수 있습니다커밋되지 않은 읽기가 가능합니다. SELECT 명령문에만 적용됩니다.

PAGLOCK

주로 단일 테이블 잠금이 취해지는 곳에서 페이지 잠금을 사용합니다.

READCOMMITTED

READ COMMITTED 격리 수준에서 실행되는 트랜잭션과 같은 잠금 방법을 사용하여 스캔을 수행합니다기본적으로, SQL Server 2000은 이 격리 수준에서 실행됩니다.

READPAST

잠겨 있는 행을 건너뜁니다이 옵션을 사용하면 다른 트랜잭션이 이러한 행에 대해 잠금을 해제할 때까지 기다리지 않고 다른 트랜잭션에 의해 잠겨 있는 행을 건너뜁니다그렇지 않으면 일반적으로 결과 집합에 나타납니다. READPAST 잠금 참고는 READ COMMITTED 격리 수준에서 작동하는 트랜잭션에만 적용되며 행 수준 잠금 뒤만 읽습니다. SELECT 문에만 적용됩니다.

READUNCOMMITTED

NOLOCK과 같습니다.

REPEATABLEREAD

REPEATABLE READ 격리 수준에서 실행되는 트랜잭션과 같은 잠금 방법으로 스캔을 수행합니다.

ROWLOCK

성긴 페이지 잠금 및 테이블 수준의 잠금 대신 행 수준 잠금을 사용합니다.

SERIALIZABLE

SERIALIZABLE 격리 수준에서 실행되는 트랜잭션과 같은 잠금 방법으로 스캔을 수행합니다. HOLDLOCK과 같습니다.

TABLOCK

세부적인 행 또는 페이지 수준 잠금 대신 테이블 잠금을 사용합니다. SQL Server는 명령문이 끝날 때까지 이 잠금을 보유합니다그러나HOLDLOCK을 함께 지정했으면 트랜잭션이 끝날 때까지 잠금이 보유됩니다.

TABLOCKX

테이블에 대해 단독 잠금을 사용합니다이 잠금을 사용하면 다른 트랜잭션이 테이블을 읽거나 업데이트할 수 없고 명령문이나 트랜잭션이 끝날 때까지 보유됩니다.

UPDLOCK

테이블을 읽는 중 공유 잠금 대신 업데이트 잠금을 사용하며 명령문이나 트랜잭션이 끝날 때까지 보유됩니다. UPDLOCK을 사용하면 다른 트랜잭션이 읽는 것을 차단하지 않고 데이터를 읽을 수 있고 마지막으로 읽은 후 데이터가 변경되지 않으며 나중에 업데이트할 수 있습니다.

XLOCK

명령문에 의해 처리되는 모든 데이터에 대해 트랜잭션이 끝날 때까지 보유될 단독 잠금을 사용합니다이 잠금은 PAGLOCK 또는 TABLOCK으로 지정할 수 있으며 이 경우 단독 잠금이 해당 세부성 수준에 적용됩니다.

분명히 말씀 드리지만.. 사용자가 잠금 힌트를 주는 것 보다는..

SQL서버가 자동으로 정하게 하는 것이 대부분의 상황에서 좋으며 잠금의 범위가

커질 경우 역시 SQL서버가 자동으로 락을 에스켈레이션 하게 하는 것이 좋습니다.

 

.. 형식은 어떤 것인지 감이 조금 잡히실 겁니다역시나 형식과 함께 이어지는

리소스 컬럼의 정보 입니다.

리소스 유형

설명

RID

테이블 내의 잠겨진 행의 행 식별자입니다행은 필드:페이지:rid 조합으로 식별됩니다여기서 rid는 해당 페이지의 행 식별자입니다.

KEY

SQL Server에서 내부적으로 사용되는 16진수입니다.

PAG

페이지 번호입니다페이지는 필드:페이지 조합으로 식별됩니다여기서 파일 번호는 sysfiles 테이블의 fileid이며페이지는 해당 파일 내의 논리적인 페이지 번호입니다.

EXT

익스텐트에서 첫 번째로 잠글 페이지 번호입니다페이지는 필드:페이지 조합으로 식별됩니다.

TAB

ObjId 열에 테이블의 개체 ID가 이미 있으므로 아무 정보도 제공되지 않습니다.

DB

dbid 열에 데이터베이스의 데이터베이스 ID가 이미 있으므로 아무 정보도 제공되지 않습니다.

 

이어서 잠금의 모드 입니다이 부분이 조금 난해할 수 있으니 잘 봐 보세요.

잠금 모드

설명

공유(S)

SELECT 문처럼 데이터를 변경하거나 업데이트하지 않는 작업(읽기 전용 작업)에 사용합니다.

업데이트(U)

업데이트할 수 있는 리소스에 사용합니다여러 개의 세션이 리소스를 읽고잠그고나중에 업데이트할 때 발생하는 일반적인 교착 상태를 방지합니다.

단독(X)

INSERT, UPDATE, DELETE와 같은 데이터 수정 작업에 사용합니다여러 개의 업데이트 작업이 같은 리소스에 대해 동시에 이루어지지 못하게 합니다.

내재

잠금 계층 구조를 만드는 데 사용합니다내재된 잠금의 종류에는 내재된 공유(IS) 잠금내재된 단독(IX) 잠금공유 및 내재된 단독(SIX) 잠금이 있습니다.

스키마

테이블의 스키마에 종속되는 작업이 실행될 때 사용합니다스키마 잠금의 종류에는 스키마 수정(Sch-M)과 스키마 안전성(Sch-S) 두 가지가 있습니다.

대량 업데이트(BU)

데이터를 테이블로 대량 복사하는 경우와 TABLOCK 참고가 지정된 경우 사용합니다.

 

그리고 이어서 내재 라고 되어있는 잠금이 있는데요.

잠금 모드

설명

내재된 공유(IS) 잠금

트랜잭션이 각 리소스에 대해 S 잠금을 설정하여 계층의 아래쪽에 있는 일부 리소스를 읽으려 하는 것입니다.

내재된 단독(IX) 잠금

트랜잭션이 각 리소스에 대해 X 잠금을 설정하여 계층의 아래쪽에 있는 일부 리소스를 수정하려 하는 것입니다. IX IS의 상위 집합입니다.

공유 및 내재된 단독(SIX) 잠금

트랜잭션이 각 리소스에 대해 IX 잠금을 설정하여 계층의 아래쪽에 있는 모든 리소스를 읽고 일부 리소스를 수정하려 하는 것입니다최상위 수준 리소스에서는 동시 IS 잠금이 허용됩니다.예를 들어테이블에 대한 SIX 잠금은 테이블에 대해 SIX 잠금을 설정하여 동시 IS 잠금을 허용하고수정 중인 페이지에 IX 잠금을 설정하고 수정된 행에 대해 X 잠금을 설정합니다리소스 당 한 번에 하나의 SIX 잠금을 설정할 수 있으므로 다른 트랜잭션이 테이블 수준에서 IS 잠금을 얻어 계층 아래쪽에 있는 리소스를 읽을 수 있어도 다른 트랜잭션이 리소스를 업데이트할 수는 없습니다.

이렇게 내재된 잠금에 대한 정보 역시 있습니다.  내재 잠금은..

계층으로 볼때.. 예를들어.. 여러개의 로우에 잠금이 걸린다면? - 페이지 잠금등으로

잠금을 관리 할 수 있습니다그런 계층적인 잠금에서 상위 잠금에 대해서 내재된 잠금을

걸고 처리하게 되는 것이지요보시는 바와 같이 하위에 대해서 X(단독잠금)이 걸릴 경우

상위 개체는 (IX)내재된 단독 잠금 모드가 걸리게 된다는 의미 입니다.

 

~~ 여기까지가 잠금 / 개체에 대한 이야기이구요잠금이 걸린 여러 시스템 개체를 보신

것입니다.

 

중요하게 또한 보셔야 하는 부분은 잠금 / 프로세스 입니다.

예를들어.. 맨 위의 쿼리를 생각해 보세요.

그 쿼리는 update titles set price = price * 2 라는 구문으로 다른 사용자의 select * from titles

쿼리를 막고 있었습니다그렇다면.. 바로 문제가 되는 update쿼리의 사용자가

잠금의 차단 주체(차단하는 녀석)이 될 것이고 select하는 사용자는차단을 받고

있을 것입니다이것을 볼 수 있게 해주는 것은 sp_who라는 명령이 있는데요.

 

 

 

sp_who2


2.png

 

 

하시게 되면 blk라는 컬럼에 차단 주체를 볼 수 있게 됩니다.

 

이렇게 SPID 54번 프로세스가 막고 있다고 하네요.

SPID 54번 프로세스는 53번 바로 아래 있습니다.

 

자 그럼 이제 잠금의 차단 주체가 어떤 녀석인지 역시 감이 잡히실 겁니다. ^_^

이렇게 차단이 일어날 경우를 블러킹(Blocking)이 일어난다고 보통 말을 하게 되며..

블러킹은 데이터베이스 리소스를 여러명이 사용하기 때문에 당연히 일어나는

것입니다. - 특히 돈이나 재무와 관련되는 프로세스일 경우는 대부분 이 트랜잭션을

이용한 처리를 하기 때문에 종종 블러킹이 일어 나지요하지만 대단히 응답속도가

늦거나 - CPU는 놀고 있는데도 불구하고.. 그렇다면 여러 블러킹 처리를 봐 보셔야

하지요.

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/394745


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?


이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요. 이스트럭(강동운) 입니다.


SQL Server 는 총 6가지 격리 수준을 제공하고 있습니다. 


하지만 오늘은 1~4번에 해당하는 격리 수준에 대해서 알아보려고 합니다.



[트랜잭션 격리 수준]  

1. READ UNCOMMITTED

2. READ COMMITTED

3. REPEATABLE READ

4. SERIALIZABLE


SQL Server 2005부터 추가된 두가지

5. READ COMMITTED WITH SNAPSHOT

6. SNAPSHOT






[선행 필요 Lock에 대한 지식]

1. S Lock: 공유 잠금(Shared Lock)

2. X Lock: 단독 잠금(Exclusive Lock)

3. Row, Page, Extent에 대한 기본 개념 및 잠금 범위

4. 암시적과 명시적 트랜잭션에 대한 이해


S Lock은.. 데이터를 읽어올때 주로 걸리는 Lock 입니다.

X Lock은.. 데이터를 입력/수정/삭제 할 때 걸리는 Lock 입니다.


X Lock은 혼자만 잠글 수 있기 떄문에.. 다른 어떤 Lock이랑도 호환되지 않습니다. 하지만.. S Lock은... 다른 S Lock과 호환이 되기 때문에.. 서로 공유할 수 있습니다.


이 외에도 업데이트락, 인텐트 락등이 있지만.. 이번에 설명드릴 부분외라 따로 설명드리진 않겠습니다!




[테스트를 위해 임시 테이블 생성]

IF OBJECT_ID('tblOnlyHeap') IS NOT NULL

  DROP TABLE tblOnlyHeap

GO

IF OBJECT_ID('tblClusteredIndex') IS NOT NULL

  DROP TABLE tblClusteredIndex

GO


CREATE TABLE tblOnlyHeap(IDX INT NOT NULL, DATA VARCHAR(2) NULL)  --//인덱스가 없는 테이블

GO

CREATE TABLE tblClusteredIndex(IDX INT NOT NULL, DATA VARCHAR(2) NULL) --//인덱스가 있는 테이블

GO


INSERT INTO tblOnlyHeap SELECT 1, '가'

INSERT INTO tblOnlyHeap SELECT 2, '나'

INSERT INTO tblOnlyHeap SELECT 3, '다'

INSERT INTO tblOnlyHeap SELECT 4, '라'

INSERT INTO tblOnlyHeap SELECT 5, '마'

INSERT INTO tblOnlyHeap SELECT 6, '바'

INSERT INTO tblOnlyHeap SELECT 7, '사'



INSERT INTO tblClusteredIndex SELECT 1, '가'

INSERT INTO tblClusteredIndex SELECT 2, '나'

INSERT INTO tblClusteredIndex SELECT 3, '다'

INSERT INTO tblClusteredIndex SELECT 4, '라'

INSERT INTO tblClusteredIndex SELECT 5, '마'

INSERT INTO tblClusteredIndex SELECT 6, '바'

INSERT INTO tblClusteredIndex SELECT 7, '사'

GO


--//tblClusteredIndex 에는 IDX Column에 PRIMARY KEY 생성

ALTER TABLE tblClusteredIndex

ADD CONSTRAINT tblClusteredIndex_PK PRIMARY KEY(IDX)

GO




1. READ UNCOMMITTED

READ UNCOMMTED 를 해석을 하게되면 => COMMIT 되지 않은 데이터를 읽을 수 있다.


이 말은.. 다른 세션에서 트랜잭션을 걸어서 데이터를 INSERT 나 UPDATE 할 경우... COMMIT 이 되지 않았는데도 불구하고, 데이터를 읽을 수 있다는 말입니다.


마치 남자친구의 맘속을 훤희 모두 들여다보는..변심도 미리 알아채는 여친님의 마음이라 볼 수 있죠~!


예제를 통해 살펴보도록 하겠습니다.


#1번 세션

BEGIN TRAN

UPDATE tblClusteredIndex

SET DATA = '하'



#2번 세션

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM tblClusteredIndex

GO

--결과

IDX   DATA

1       하

2       하

3       하

4       하

5       하

6       하

7       하



데이터를 SELECT 할때 S Lock으로 잠근다고 미리 언급을 했습니다.


하지만.. READ UNCOMMITTED 에서는 S Lock 조차 걸지 않기 때문에..

다른 세션에서 커밋되지 않은 수정하는 (X Lock 데이터) 데이터를 볼 수 있습니다.


바로 변심한 남친의 마음을 즉각 알아채는 여친의 마음!


이걸 Dirty Read 라고 합니다.






2. READ COMMITTED

READ COMMITTED 를 해석을 하게되면 => COMMIT 된 데이터만 읽을 수 있다. 

READ UNCOMMITTED와 다른 점은 실제 SELECT 할때 S Lock을 소유 합니다. 하지만!!! SELECT 가 끝나는 동시에 S Lock을 해제 합니다.


이말은..... 트랜잭션 내에서 SELECT가 끝나더라도(커밋되기전) 다른 세션에서 INSERT나 UPDATE가 가능하다는 말이 됩니다.



남친의 변한 마음만 확인할 수 있는 여친의 마음... 훗~~ 속마음까진 확인할 방법이.........없다!



예제를 통해 살펴보도록 하겠습니다.


1번 예제


#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

SELECT * FROM tblClusteredIndex

GO

--결과

IDX   DATA

1       가

2       나

3       다

4       라

5       마

6       바

7       사


--트랜잭션이 커밋되지 않았지만... SELECT로 이미 결과를 반환했습니다. (S Lock에 해제 된 상태)



#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


BEGIN TRAN

UPDATE tblClusteredIndex

SET DATA = '가'

WHERE IDX = 7

COMMIT  --//수정한 데이터를 COMMIT(1번 세션 S Lock이 해제 되었기 때문에 UPDATE 가 가능)


#다시 1번 세션

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT * FROM tblClusteredIndex

GO

--결과

IDX   DATA

1       가

2       나

3       다

4       라

5       마

6       바

7     가

--//2번 세션에서 이미 커밋을 했기 때문에 변경된 내용을 불러옵니다.



만약 SELECT 하더라도 COMMIT 되기 전까지 S Lock을 소유 한다면...

다른 세션에선 업데이트가 불가능 하겠죠..

(사실 이게 REPEATABLE READ 입니다. 뒤에서 설명드리겠습니다.)




SELECT가 아닌 업데이트는 어떻게 다른지 보도록 하겠습니다.


2번 예제


#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tblClusteredIndex

SET DATA = '가'

WHERE IDX = 7

GO



#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT * FROM tblClusteredIndex WHERE IDX = 7

--대기 상태...............


READ COMMITTED의 해석 기억하십니까? 커밋된 데이터만 읽기가 가능하다는 얘기죠!


1번 세션에서 아직 COMMIT을 하지 않았기 때문에.. 2번 세션에선 IDX = 7을 읽지 못하고 1번 세션의 COMMIT을 기다리게 됩니다.


그렇다면 2번 세션에서 아래와 같은 쿼리를 날리면 어떻게 될까요?


#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SELECT * FROM tblClusteredIndex WHERE IDX = 1

--결과

IDX   DATA

1       가


1번 세션에서 수정으로 인해 IDX = 7 인 row를 X Lock을 걸은 상태기 때문에.. 다른 컬럼들은 가지고 나오는데 문제는 없습니다.


그렇다면 .. 아래도 충분히 가능하겠죠~!

#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tblClusteredIndex

SET DATA = '가'

WHERE IDX = 1

GO

ROLLBACK


다른 ROW에 대해서 X 락을 걸었으니까요~ 이 증거가 SQL Server가 ROW Lock이 가능한 이유입니다.






3. REPEATABLE READ

REPEATABLE READ 를 해석을 하게되면 => 반복 읽기


한 트랜잭션 안에서 내가 읽었던 녀석은 절대 변하면 안되~~!


마치.. 간절한 여자친구처럼 오빠 마음 절대 변하면 안되!! 이렇게 Lock을 걸어두는 것이죠...

만날때부터 헤어질때까지~~~ㅎㅎ


이미 위에서 한번 설명을 드렸죠!! 트랜잭션내에서 읽은 녀석은.. 다른 세션에서 변경조차 안됩니다.

물론 S Lock이기 때문에.. 읽을 순 있겠죠 ^^;


1번 예제


#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN

SELECT * FROM tblClusteredIndex

GO

--결과

IDX   DATA

1       가

2       나

3       다

4       라

5       마

6       바

7       사


--트랜잭션이 커밋되지 않았지만...  S Lock은 계속 유지 됩니다.



#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


BEGIN TRAN

UPDATE tblClusteredIndex

SET DATA = '가'

WHERE IDX = 7

---------- 대기 상태


이런 경우 1번세션에서 이미 S Lock을 걸고 있기 때문에..수정할 수가 없게 됩니다.

하지만 읽을 순 있겠죠~



#2번 세션 을 중지하고..

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN

SELECT * FROM tblClusteredIndex

GO

--결과

IDX   DATA

1       가

2       나

3       다

4       라

5       마

6       바

7       사

--읽는건 정상적으로 됩니다. 당근 S Lock은 S Lock 끼리 공유할 수 있으니깐요 ^^





2번 예제를 위해서 데이터를 1,3,5만 남기고 지워봅시다.


2번 세션에 ROLLBACK을 하지 않았기 때문에.. 우선 ROLLBACK을 시킵니다.


#2번 세션(혹시나 모를 롤백 시키기)

IF(@@TRANCOUNT > 0) ROLLBACK

GO



#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO

DELETE FROM tblClusteredIndex WHERE IDX NOT IN (1,3,5)

GO



2번 예제

REPEATABLE READ는 처음 읽은놈은 끝까지 유지한다고 했습니다.

그럼 중간에 낑겨 드는 놈들은 어떻게 될까요?


#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN

SELECT * FROM tblClusteredIndex

--결과

IDX         DATA

1           가

3           다

5           마


#2번 세션

INSERT INTO tblClusteredIndex SELECT 2,'나'

--오~~ 입력이 됩니다.


#1번 세션(커밋되기전..)

SELECT * FROM tblClusteredIndex

--결과

IDX         DATA

1           가

2         나

3           다

5           마


REPEATABLE READ는 처음 읽었을 당시에 존재하는 데이터에 대해서만 Lock을 걸게 됩니다.

따라서 2번째 세션에서 입력된 IDX = 2의 값은.. 첫번째 세션에서 SELECT 할 당시엔 없었기 때문에.. LOCK이 걸리지 않았으므로.. INSERT가 되는것이죠


오빠 마음이 변하진 않지만.... 다른 미모의 여인이 나타나면.. 여친몰래 마음속에 INSERT 되듯이 말이죠!!

물론 여친은 알아채지 못하겠죠 ㅋㅋㅋ..


이 외도의 주인공!! 바로 팬텀이라고 부릅니다. ^^


그렇다면 미모의 여인도 접근 못하게 확실히 틀어 막는 방법은 없을까요???...




4. SERIALIZABLE

SERIALIZABLE => 직렬화......



마치.. 일거수 일투족을 감시하는 여자친구처럼 옆에 찰싹 붙어서 다른 어떤 여자도 들어오지 못하게 막는게 바로!

SERIALIZABLE 입니다.


예제를 바로 보시죠!


1번 예제


1번 예제를 위해서 데이터를 1,3,5만 남기고 다시 지워봅시다. 그리고 7을 넣습니다.

#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO

DELETE FROM tblClusteredIndex WHERE IDX NOT IN (1,3,5)

GO

INSERT INTO tblClusteredIndex SELECT 7,'사'

GO



#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

SELECT * FROM tblClusteredIndex WHERE IDX BETWEEN 3 AND 5

GO

--결과

IDX   DATA

3       다

5       마

-- RangeS-S Lock이라는 녀석으로 범위로 S Lock을 걸어버립니다.


이때 4가 들어가려 한다면??? REPATABLE READ와 다르게 분명 막힐 것입니다.


#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


INSERT INTO tblClusteredIndex SELECT 4, '나'

---------- 대기 상태


하지만 여기서 3~5 범위에 상관없는  2가 들어가려고 하면 어떻게 될까요??


#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


INSERT INTO tblClusteredIndex SELECT 2, '나'

---------- 대기 상태


똑같이 대기 상태입니다.


SERIALIZABLE은.. 3 AND 5 로 SELECT로 잠궜다고 하더라도... 3~5 까지 잠그는 것이 아닙니다.


3 이전행인 1 부터... 5 다음행인 7까지 잠그게 됩니다.


결국... 1 <= IDX <=7인 값은 다른 세션에서 INSERT가 되지 않습니다.


#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


INSERT INTO tblClusteredIndex SELECT 100, '나'

--성공!



만약... 1 AND 3으로 잠궜다면??? 테이블에 1보다 작은 값은 존재하지 않고, 3보다 큰 값은 5기 때문에..

IDX >= 6인 값만 INSERT 가 가능하게 됩니다. 물론 0보다 작은 값은 절대 들어갈 수 없습니다.


물론 다른 세션에서 말이죠!




SERIALIZABLE에서 테이블에 인덱스가 없으면 어떻게 될까요?



#1번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

BEGIN TRAN

SELECT * FROM tblOnlyHeap WHERE IDX BETWEEN 3 AND 5

GO

--결과

IDX   DATA

3       다

5       마



#2번 세션

IF(@@TRANCOUNT > 0) ROLLBACK

GO


INSERT INTO tblClusteredIndex SELECT 0, '나'

---------- 대기 상태


INSERT INTO tblClusteredIndex SELECT 100000, '나'

---------- 대기 상태


테이블에 인덱스가 없기 때문에.. 범위를 알 수 없습니다. 그래서 모두 잠그게 됩니다.




감사합니다.

[출처] SQLER.COM http://www.sqler.com/394743 


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

오늘은 트랜잭션에 대한이해입니다.

 

원문http://www.sqler.com/127366

 

트랜젝션에 대한 이야기 입니다. ^_^

트랜젝션에 대한 이야기는 많은 곳에서.. 이런 저런 이유로 들어 보셨을 겁니다.

프로그래밍을 하실때도 이 트랜젝션은 분명히 대단히 속도에 영향을 주는

요소 입니다.

특히나 데이터 수정이 있을 경우인 Insert, Update, Delete를 잘못 수행했을 경우

대단히 많은 문제를 줄 수 있으며.. - CPU등의 시스템은 펑펑 놀고 있는데..

SELECT의 조회 속도가 대단히 느려지는 사태가 발생하는 겁니다.

이럴때는 한번쯤 트랜젝션 처리 모듈의 문제를 어플리케이션에서 점검을 해 보셔야

하지요. - 물론 마지막쯔~음에.. 문제상황인 블러킹이나 데드락을 막는 방법과..

어플리케이션을 개발하실때.. 주의에 주의를 거듭하셔야 하는 부분도

살짝 언급을 해 드릴겁니다.

 

이 장의 이름은 트랜젝션과 잠금처리인데요..

트랜젝션은 뭘까요? ^_^

늘 그랬던 것처럼.. 군더더기 없이 깔끔하게 알아 보도록 하지요.

 

트랜젝션은 작업의 단위를 지정해 주는 중요한 부분이기 때문입니다.

 

또한 트랜젝션은 SQL구문이나 쿼리를 실제로 처리할 경우의 가장 작은 단위 입니다.!!

은행이야기를 조금 해 볼까요?

코난이 계좌에 200원이 있고....  수선이 계좌에 300원이 있다...

짤짤이에서 진 코난이가 100원을 수선이에게 잃어 200원중 100원을 온라인으로 계좌이체

를 시켜줘야 한다....

은행에사거 온라인으로 입금을 하기위해

 

 

1. 코난이 통장에서 100원을 뺌  - 코난이 통장 = 100   수선이 통장 = 200

2. 수선이 통장에 100원을 더함 - 코난이 통장 = 100   수선이 통장 = 300

 

 

 

하려고 했다...

그런데 웬일.. 정전이 나서... 1번 작업을 끝마치니 시스템이 죽었다...

"대우네 은행"에서 그당시 온라인으로 계좌 이체를 시킨 사람이 1000명이었다...

 999명과 코난이는(도합 1000)  이 문제를 어케할 것인가?

-_-;; 아마 기억하시는분들은.. MSSQL7 중급강좌의 트랜젝션 부분을 역시나..

손가락 두개로 컷 & 페이스트 한걸 아실 겁니다. -_-;;

양해하시고.. 저런 문제가 발생할 수 있지요.. !!!

 

저 내용을 우리가 사용하는 구문으로 살짝 돌려 본다면 이런 이야기가 될지 모릅니다.

 

 

 

update 계좌 set 금액 = 금액 - 100 where id like '코난'

update 계좌 set 금액 = 금액 + 100 where id like '수선'

 

 

하지만 위의 쿼리가 아닙니다!!!!!

SQL서버에서 위와 같은 처리를 위해서는 위처럼 쓰시면 안됩니다.

위와 같은 구문으로 쓰시면?

위의 쿼리는 다음과 같이 변환 됩니다.

 

 

begin tran

update 계좌 set 금액 = 금액 - 100 where id like '코난'

commit tran

 

begin tran

update 계좌 set 금액 = 금액 + 100 where id like '수선'

commit tran

 

 

이렇게 변화하게 됩니다. - 내부적으로 SQL서버의 엔진이 저렇게 바꾸는 겁니다.

그렇다면!!! 어떻게 해야.. 하나의 단위로.. 위 두개의 작업을 하나로 묶어서 수행하게

할 수 있을까요?

바로 다음과 같이 명시적으로 begin tran commit tran을 사용하시면 됩니다.

 

 

 

begin tran

update 계좌 set 금액 = 금액 - 100 where id like '코난'

update 계좌 set 금액 = 금액 + 100 where id like '수선'

commit tran

 

 

이렇게 사용하시면 두개의 작업이 하나의 단위로 처리가 되게 되지요.

별로 어렵지 않으실 겁니다그리고 이정도는 컴쪽의 일을 하신다면 한번쯔음~~

들어 보셨을 이야기일 거구요그럼 조금 다른 이야기로.. 내용을 돌려 보도록 하지요.

 

트랜젝션의 네가지 성격

트랜젝션은 DBMS차원에서.. 다음 네가지 성격을 만족해야만 합니다.

1. 원자성(atomicity) : 트랜젝션은 전부전무의 실행만이 있지.. 일부 실행으로

트랜젝션의 기능을 가질 수는 없다.

2. 일관성(consistency) 트랜젝션이 그 실행을 성공적으로 완료하면 언제나 일관된

데이터베이스 상태로 된다라는 의미입니다.. 이 트랜젝션의 실행으로 일관성이

깨지지 않는다 라는 의미 이지요...

3. 격리성(isolation) 연산의 중간결과에 다른 트랜젝션이나 작업이 접근할 수 없다..

라는 의미입니다.

4. 영속성(durability) : 트랜젝션의 일단 그 실행을 성공적으로 끝내면 그 결과를 어떠한

경우에라도 보장받는다.. 라는 의미입니다....

 

그렇다면 도대체~~ 저 어려운 단어들의 나열이 트랜젝션의 성격이라는 것은 알겠는데..

그 트랜젝션 이라는 녀석으로 과연 어떻게 문제가 생겼을때 데이터를 복구하냐??

이때는 UNDO REDO의 이야기가 나오게 됩니다.

우선 많이들 이야기 하시는 이야기로 알아 보지요.

 

장애(failure)와 회복(recovery)

회복(recovery)이란 장애(failure)가 일어났을 때 데이터 베이스를 장애 이전의 상태로

다시 복구 시켜 일관된 상태로(consistent state)로 복구 시키는 작업이지요

당연하지요? -_-;;

장애를 조금더 알아본다면관리자가 구두로 컴퓨터 파워 버튼을 실수로 차버리거나.

해서 문제가 생기는 상황?? 이렇게 대충은 생각이 가능하실 겁니다.

조금만 더 세분화를 시켜 본다면..

 

 

 

1. 트랜젝션 장애

트랜젝션 내의 논리적 오류나 내부조건입력 데이터의 불량데이터의 불명시스템 자원의

과다한 사용요구 등으로 정상적인 실행을 계속 할 수 없는 상태를 의미 합니다.

2. 시스템 장애

이는 하드웨어의 오동작으로 메인 메모리에 있는 정보의 손실이나 교착 상태가 발생하여

더 이상 실행을 계속할 수 없는 상태를 의미 하지요...

3. 미디어 장애

디스크 헤드 붕괴나 고장으로 인하야... 저장 장치의 데이터베이스 일부 또는 전부가

손상된 상태를 의미하구요 ^_^

 

 

이렇게 세분화가 가능해 집니다.

그렇다면 회복이라는 것은?

말 그대로 데이터를 안정된 상태로 복구 시키는 것을 의미하지요.


감사합니다.
 

[출처] SQLER.COM http://www.sqler.com/394741


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

이번에는 클러스터드 인덱스와 넌 클러스터드 인덱스에 대해서 소개해드리겠습니다.

 

원문http://www.sqler.com/127352

 

 

 

색인의 종류 SQL서버는 두가지 종류의 색인이 있습니다두가지 뿐이라니 뭔가 기분

좋지요 두가지는 Clustered 인덱스와 Non-Clustered 인덱스 두가지 입니다.

각각 한글로는 클러스터된 인덱스 / 클러스터되지 않은 인덱스로 불립니다.

-_-;;  늘 그런것처럼 혼용해서 코난이는 쓸겁니다아시져? ^_^;;

 

인덱스는 분명 만들어야 하는 것입니다

이 말은 

1. 만드는 비용이 있다라는 것이지요.

다음 인덱스는 공간이 필요하다고 했습니다.

2. 디스크 비용이 필요하며 항상 공간 유지를 적절해야 한다는 겁니다.

만들면 끝인가요아니죠만들었으면?

3. 유지보수에 비용이 필요하겠지요.

인덱스를 만들면 데이터를 조회하는 속도를 높일 순 있지만..

만약 데이터가 삽입 / 수정 / 삭제 된다고 생각해 보세요.

앞에서 본 인덱스의 구조를 변경하면서 재생성 해야 겠지요?

4. 데이터 변경이 있을때 비용이 추가 된다는 겁니다.

앞에서 또한 말씀 드렸지만 인덱스를 사용하면 항상 빨라진다고 말씀 안드렸죠.

5. 인덱스는 항상 빠르지 않다.

인덱스를 사용하면 유용한 부분은?

5-1. WHERE절에서 참조되는 컬럼

5-2. 참조키가 설정되어 있는 컬럼

5-3. 참조키는 아니지만 JOIN에 사용되는 컬럼

5-4. 범위 검색이 일어나는 컬럼

5-5. ORDER BY로 정렬 되는 컬럼, GROUP BY로 그룹핑 되는 컬럼

5-6. TOP 구문과 함께 사용되는 SELECT

등에서 사용하면 좋습니다.

그렇다면어디에 사용하면 바보 될까요?

5-7. WHERE절에서 사용되지 않는 컬럼에는 물론 효과 없음.

5-9. WHERE절에서 변환(함수등이 사용되는)되는 컬럼과 비교시 효과 없음.

5-10. 선택도(찾을 데이터 / 전체 데이터)가 클 경우 효과 적음.

잠시후 말씀 드리겠지만.. 예를들어 성별 컬럼과 같은 남 / 여 비율적으로 대략 50 : 50 

구성비가 있는 컬럼이라면인덱스의 효과가 떨어 지겠죠.

이런 주의 사항이 필요합니다.

 

자 이제 인덱스 생성 구문을 실제로 봐 보도록 하지요.

 

 

 

CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name

    ON <object> (column [ ASC | DESC ] [ ,...n ] )

    [ INCLUDE (column_name [ ,...n ] ) ]

    [ WHERE <filter_predicate> ]

    [ WITH ( <relational_index_option> [ ,...n ] ) ]

    [ ON { partition_scheme_name (column_name)

         | filegroup_name

         | default

         }

    ]

    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]

 

[ ; ]

 

<object> ::=

{

    [ database_name. [ schema_name ] . | schema_name. ]

    table_or_view_name

}

 

<relational_index_option> ::=

{

    PAD_INDEX = { ON | OFF }

  | FILLFACTOR =fillfactor

  | SORT_IN_TEMPDB = { ON | OFF }

  | IGNORE_DUP_KEY = { ON | OFF }

  | STATISTICS_NORECOMPUTE = { ON | OFF }

  | DROP_EXISTING = { ON | OFF }

  | ONLINE = { ON | OFF }

  | ALLOW_ROW_LOCKS = { ON | OFF }

  | ALLOW_PAGE_LOCKS = { ON | OFF }

  | MAXDOP =max_degree_of_parallelism

  | DATA_COMPRESSION = { NONE | ROW | PAGE}

     [ ON PARTITIONS ( { <partition_number_expression> | <range> }

     [ , ...n ] ) ]

}

 

 

 

 

몇가지 중요한 정보만 말씀드리도록 하겠습니다.

UNIQUE: 지정해 고유 인덱스 또는 고유하지 않은 인덱스 생성이 가능합니다.

색인의 종류는 두가지로 CLUSTERED | NONCLUSTERED 로 할지 지정이 가능 합니다.

table이나 view에 생성이 가능합니다. 

컬럼을 ASC 또는 DESC로 정렬해 생성 가능합니다. 특히 클러스터드 인덱스를 생성시

유용하며 ORDER BY 구문과도 밀접합니다.

 

다음 인덱스 옵션에서

PAD_INDEX는 중간 레벨을 적절히 비워 데이터 삽입 등에 대비하기 위한 것이며

FILLFACTOR는 리프 레벨을 적절히 비워 역시 삽입 등에 대비하는 것입니다.

샘플에서 이야기를 해 드리도록 하지요.

IGNORE_DUP_KEY 는 중복되는 값을 무시한다는 의미입니다.

DROP_EXISTING 은 이미 존재하는 인덱스가 있으면 제거하고 재 생성하라는 의미 입니다.

SORT_IN_TEMPDB TEMPDB상에서 정렬하라는 옵션 입니다예를들어 데이터와 인덱스가

같은 물리적인 디스크에 있고 데이터가 한 1000만건 정도 된다면 인덱스 생성에 대단히

많은 시간이 소요 됩니다이때 TEMPDB에서 인덱스 생성시 필요한 정렬작업을 시키고

사용자 데이터베이스의 물리적인 디스크와 TEMPDB 물리적인 디스크가 틀리다면 인덱스

생성시 부하를 줄일 순 있지만 TEMPDB에 다른 불필요 공간이 생기니 주의 하셔야 하지요.

끝으로 ON FILEGROUP은 인덱스 역시 데이터라고 말씀 드렸습니다데이터베이스 강좌에서

filegroup 을 적절히 분산시켜 생성해 속도를 높일 수 있다고 말씀 드린 것처럼 인덱스 역시

적절한 filegroup에 위치시켜 최적의 속도를 낼 수 있게 할 수 있지요.

 

백견이 불여일타라고 우선 한번 만들어 보도록 하지요.

 

 

CREATE DATABASE konanTestDB

GO

 

USE konanTestDB

GO

--테이블생성

CREATE TABLE konan_test_table(

konan_id int IDENTITY (1, 1) NOT NULL

, konan_data char (50) NOT NULL

, konan_date char (50) NOT NULL

)

GO

 

--10000건의샘플데이터삽입

set nocount on

GO

 

declare @i int

set @i = 0

while @i < 10000

begin

--WAITFOR DELAY '00:00:01'

insert into konan_test_table values

(

@i ,

convert(varchar, datepart(yy, getdate())) + ''

+ convert(varchar, datepart(mm, getdate())) + ''

+ convert(varchar, datepart(dd, getdate())) + ''

+ convert(varchar, datepart(hh, getdate())) + ''

+ convert(varchar, datepart(mi, getdate())) + ''

+ convert(varchar, datepart(ss, getdate())) + ''

+ convert(varchar, datepart(ms, getdate())) + '미리초'

)

set @i = @i + 1

end

GO

--10.

 

set nocount off

GO

--샘플데이터조회

SELECT TOP 100 * FROM konan_test_table

SELECT COUNT(konan_id) FROM konan_test_table

 

1.png

 

 

 

대략적인 샘플데이터 100건과 만건이 잘 들어간게 보일 겁니다.

여기서 어느정도의 IO 비용이 소요되는지 보도록 할까요?

물론 시간 / IO비용 모두가 중요하지만 우선 IO비용만 보도록 하지요.

 

 

--IO통계보기

SET STATISTICS IO ON

 

SELECT * FROM konan_test_table WHERE konan_id = 5000

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 10

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 45

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 1000

 

--IO통계?

 

--IO통계끄기

SET STATISTICS IO OFF


2.png


3.png

 

 

메시지 부분을 보시면 IO통계를 확인하실 수 있을 겁니다.

이제 인덱스를 생성해 보도록 하지요.

 

 

--간단한인덱스생성

CREATE INDEX idx ON konan_test_table (konan_id)

GO

 

 

 

 

인덱스 생성은 잘 되셨을 거구요다시 데이터를 조회해 보도록 할까요?

 

 

 

--IO통계보기

SET STATISTICS IO ON

 

SELECT * FROM konan_test_table WHERE konan_id = 5000

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 10

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 45

 

--IO통계?

 

SELECT * FROM konan_test_table WHERE konan_id < 1000

 

--IO통계?

 

--IO통계끄기

SET STATISTICS IO OFF

 

4.png

 

통계를 봐 보세요어떠세요?

아마도 WHERE konan_id < 30 부터 인덱스가 없을 때와 비슷한 수치가

나올 겁니다.

이것은 뭘 말하는 걸까요실행 계획을 보면서 설명 드리겠습니다.

 

실행 계획 활성화를 위해서.. Query => Include Actual Execution Plan을 선택하세요.

(단축키는 Ctrl+M) 입니다.

 

 

 

5.png

 

 

 

 

그리고 나서 쿼리를 수행해보면.. Results  Message 말고 Execution plan 탭이 생성됩니다.

 

 

6.png

 

 

 

 

위의 그림처럼 실행 계획을 보실 수 있습니다.

중요한건 Index Seek를 했다는 점이지요.

 

다음 쿼리에서 수행 계획을 보면?

 

 

7.png

 

 

 

 

이렇게 konan_id < 45 을 봐 보시면 Table Scan을 하는 것을 알 수 있습니다.

분명 어떤것은 인덱스를 타고 어떤것은 인덱스를 타지 않지요?

앞에서 말씀드린 선택도 라고 해서 (찾을 데이터수 / 전체 데이터수)로 판단 되게 됩니다.

천천히 말씀 드리지요.

 

다음 인덱스의 정보를 보려면 어떻게 할까요?

 

 

 

--인덱스정보조회

sp_helpindex konan_test_table

 

8.png

 

 

그러면 인덱스의 정보를 확인할 수 있을 겁니다.

흥미있게 보실 부분으로 인덱스의 종류를 지정하지 않으면뒤에서 보시겠지만

넌클러스터드 인덱스로 잡히게 됩니다참고하세요.

 

인덱스의 변경 구문은 없으며 DROP INDEX 구문을 이용해 인덱스를 제거할 수 있습니다.

 

 

 

--인덱스제거

DROP INDEX konan_test_table.idx

 

 

 

물론 앞에서 말씀드린 CREATE INDEX구문의 DROP EXISTING 구문으로 존재하는 인덱스를

지우고 생성할 수 도 있습니다.

 

우선 인덱스를 생성하고 돌려는 보셨네요.

이제 본격적인 SQL서버의 인덱스에 대해서 알아 보도록 할까요.

 

클러스터드 인덱스

클러스터드 인덱스는 간단히 인덱스의 리프레벨이 데이터 페이지와 같은 겁니다.

뭔소리냐구요천천히 설명 드리지요.

11.JPG

이런 화면을 생각해 보세요.

클러스터드 인덱스는 물리적으로 행을 재배열해 리프 레벨이 차곡차곡 오른쪽의 데이터 

페이지처럼 쌓이게 합니다그럼 인덱스를 봐 볼까요?

인덱스가 설정된 컬럼의 값이 순차적으로 재배열 되게 되므로 왼쪽에 보시는

인덱스 페이지는 단지 키값과 페이지의 번호만이 지정되게 됩니다.

자 그럼 우리가 만약 5번 강해원을 찾으려 한다고 생각해 보도록 하지요.

이때는 먼저 클러스터드 인덱스의 값을 보니 4 < 5 < 7 사이가 되므로

4 - 2  2번 페이지로 가게 됩니다. 2번 페이지로 가서 바로 5번 강해원을 찾게 되지요.

12.JPG

대략 이러한 그림으로 이루어 지게 되는 겁니다.

만약 12번 김태영을 찾는다면이때는 역시 10 < 12 < 13 이므로 4페이지로 가서

12번 김태영을 찾을 수 있게 되겠지요.

 

이것이 가능한 이유가 뭘까요바로 물리적으로 행이 정렬되어 있기 때문에 가능한 거지요

만약 물리적으로 행이 재배열 되어 있지 않다면이런 작업은 불가해 지는 겁니다.

아울러 물리적으로 행들이 재배열 되어 있으므로 범위 검색에 대단히 유용합니다.

이 말은 선택도가 어느정도 높아도 - 클러스터드 인덱스의 경우 30%정도도 가능 - 인덱스

를 이용해 데이터를 조회할 수 있게 되지요.

아울러 클러스터드 인덱스가 저렇게 테이블에 하나 생성되어 있는데요.

만약 클러스터드 인덱스를 하나 더 테이블에 만들고 싶다면 어떨까요?

안타깝게도 다음번 클러스터드 인덱스는 테이블을 다시 재구성 하고 싶겠지만..

이미 한번 테이블이 정렬된 상태로 재구성 되어 있으므로 불가해 집니다.

오로지 테이블에 단 1개의 클러스터드 인덱스만 생성이 가능하니 주의 하셔야 합니다.

그럼 앞의 샘플쿼리를 클러스터드 인덱스로 생성하고 장난을 조금 쳐 볼까요?

 

 

 

--인덱스가존재하면지울것

DROP INDEX konan_test_table.idx

 

--클러스터드인덱스생성

CREATE CLUSTERED INDEX idx ON konan_test_table (konan_id)

GO

 

 

이렇게 클러스터드 인덱스를 생성할 수 있지요그런데 특이하게도

SQL서버는 클러스터드 인덱스에 대해서 대단히 높은 우선권을 부여 합니다.

예를들어 이럴땐.. 풀스캔을 해도 좋을것 같은데... 클러스터드 인덱스를 써서

검사할 경우가 있지요이는 말씀 드린대로 SQL 쿼리 최적화기가 판단하는데

테이블의 크기가 작거나(로우의 건수가 아닌 전체적인 크기또는 클러스터드 인덱스의

키값 컬럼이 작을 경우 종종 발생 합니다.

실제 현업에서는 범위검색에 종종 이 클러스터드 인덱스를 두게 되므로 정상적으로

잘 동작하게 되지요.

또한 클러스터드 인덱스는 비교적 넌클러스터드 인덱스보다 크기가 작습니다.

아울러 클러스터드 인덱스는 크기를 대략적으로 예측할 수 있는 인덱스이기도 하지요.

 

 

다음 넌 클러스터드 인덱스를 봐 보도록 할까요?

넌 클러스터드 인덱스

실제 테이블의 데이터가 항상 순차적으로 들어가 있는 것은 아닙니다.

관계형 데이터베이스에서 순차라는 것은 사실 의미가 없습니다관계형 데이터베이스의

순차 유지는 오로지 ORDER BY에 적절히 이용되는 컬럼을 잘 구성해야만 하는 것이지요.

예를들어 실제 진짜 SQL서버에 들어가 있는 테이블의 순서는 다음과 같을 겁니다.

13.JPG

이런 식의 데이터가 실제로 들어가 있게 되지요그렇다면 페이지 내부는 어떤 식일까요?

14.JPG

대략적으로 위의 그림과 같은 식의 데이터가 들어가 있게 됩니다.

실질적인 데이터 페이지 이지요이런 데이터페이지들의 번호에 클러스터드 인덱스를

만약 생성한다면 어떻게 될까요이럴 경우는 RID라는 녀석이 필요하게 됩니다.

간단히 RID는 로우의 구별하는 특정 값이라고 생각 하시면 됩니다.

넌 클러스터드 인덱스는 바로 이 RID를 가지고 데이터 페이지를 포인팅 하게 되지요.

RID 샘플을 보시면 다음과 같은 식입니다.

15.JPG

여기서 RID의 첫번째 1은 화일 그룸을 의미하게 됩니다.

그다음 숫자는 데이터 페이지 번호이며 마지막 세번째 숫자는 페이지 옵셋으로 정확히

페이지의 한 로우를 포인팅(Pointing)하게 되지요.

또한 이 인덱스 페이지는 다음과 같은 형식으로 분할 되겠지요.

 

16.JPG

이러한 형식이 넌클러스터드 인덱스에서 과연 어떻게 사용 될까요?

실제 구조를 그려 보도록 하지요.

17.JPG

이러한 식으로 생성이 되게 됩니다.

루트 레벨은 인덱스 페이지7이며 중간 레벨은 엔덱스 페이지 1,2,3,4 이고

실제 데이터페이지는 1,2,3,4,5 데이터 페이지가 되지요.

자 값을 네비게이션 해 보도록 합시다.

만약 제가 3번 이승용을 찾으려 한다고 생각해 보지요.

1 < 3 < 5 이므로 1페이지로 가야 겠지요같더니 3 4페이지 2번째 로우에 있다고 합니다.

바로 4페이지로 가서 두번째 로우를 컨택하는 거지요.

 

18.JPG 

또한 만약 8 차영인을 찾으려 한다면

5 < 8 < 9 이므로 인덱스페이지 2로 가서 8 차영인을 보니 1-3-2라고 되어 있습니다.

데이터 페이지 3 2번째 로우를 포인팅 하게 되지요.

이것이 넌클러스터드 인덱스 입니다.

넌클러스터드 인덱스는 이렇게 포인팅 정보를 가지게 되므로 인덱스의 크기가 커지게 

됩니다아울러 선택도가 높으면 바로 쿼리 최적화기는 이 넌클러스터드 인덱스를

사용하지 않게 되지요일반적으로 3% 이내 정도면 이 넌클러스터드 인덱스를 사용하지

않게 됩니다

넌클러스터드 인덱스는 데이터페이지를 물리적으로 재배열하지 않으므로 여러개의

인덱스를 생성할 수 있습니다최대생성 가능 갯수는 249개 입니다.

 

다음으로 클러스터드 인덱스가 있는 테이블의 넌클러스터드 인덱스를 알아 보도록 하지요.

 

물론 당연히 클러스터드 인덱스와 넌 클러스터드 인덱스가 있을 때 넌클러스터드 인덱스를

조회할 경우 겠지요?

 

감사합니다.

19.JPG

현재는 번호에 클러스터드 인덱스가 걸린 상태이며 이름에 넌클러스터드 인덱스가 설정된

상태 입니다.

이런 식으로 구성이 되게 됩니다먼저 알아 두셔야 할 것은!!

넌클러스터드 인덱스의 RID는 더이상 RID가 아닌 클러스터드 인덱스의 키값을 가지게 됩니다.

좀더 간단히 실제 조회를 해 보도록 하지요

넌클러스터드 인덱스가 걸린 이름 컬럼의 유병수라는 이름을 조회해 보도록 합시다.

박훈 < 유병수 < 이수선 이므로 넌클러스터드 중간 레벨의 2페이지로 가게 될겁니다.

여기서 유병수를 찾으니 유병수는 클러스터드 인덱스 10번 키값을 가지고 있습니다.

10이라는 값을 가지고 클러스터드 인덱스 페이지로 가니 10은 데이터페이지 4 

있다고 합니다데이터페이지 4로 가니바로 10 유병수를 찾을 수 있게 되지요.

20.JPG

네 맞습니다바로 이런 그림이 되는 것이지요.

만약 한기환을 찾으려 한다면 어떻게 될까요?

한기환 < 한기환 이므로 넌클러스터드 중간레벨의 4페이지로 가게 되겠죠?

클러스터드 인덱스의 키값 2이니. 1 < 2 < 4 이므로 1 데이터 페이지로 가게 되며 1 데이터

페이지에서 2번 한기환을 발견하게 될 겁니다.

 

어떠세요조금 감이 잡히시나요? ^_^ 내부적인 부분이라 조금 어렵기도 하시겠지만

중요한 부분이랍니다.

수고하셨습니다.

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/394701


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요. 이스트럭(강동운) 입니다.

 

오늘은 드디어 SQL Server에서 가장 중요한 인덱스에 대해서 알아볼 차례 입니다.

 

원문: http://www.sqler.com/127350

 

이번에 소개해드릴 내용은 색인 입니다.

색인이라는 주제는 사실 매우 광범위하고 성능에 지대한 영향을 줄 수 있는 주제 입니다.

아울러 SQL서버의 상당한 내부적인 구조를 알아야 하므로 대단히 많은 분들이 꺼려하고

어려워하는 부분이기도 하지요. 실제로 사이트에 나가 튜닝 작업을 할 경우 먼저 보는

부분이기도 합니다. 그럼 이제 이 색인에 대해서 찬찬히 알아 보도록 하지요. ^_^

 

색인은 무엇인가?

데이터를 담고 있는 최소 단위가 모라고 말씀 드렸죠? 네 바로 페이지라고 말씀 드렸죠.

이 페이지에 실제 로우 데이터가 들어 있다고 말씀 드렸습니다. 물론 페이지 헤더와 옵셋

정보 역시 페이지에 포함되어 있지만, 저희는 데이터만 있다는 가정을 먼저 해 보도록 하죠.

그렇다면 색인은 무엇인가? 

색인은 트리구조(계층형)로 이루어져 있는 실제 페이지의 데이터를 포인팅하는 

데이터 입니다.

많은 분들이 오해하는 부분을 말씀 드리지요.

1. 색인은 공간을 차지하지 않는다. - 아뇨. 색인의 종류에 따라 가변적으로 인덱스의 

크기가 잡힙니다. 물론 실제 데이터에 비례적인 크기가 되지요. - 종류별로 정확한 

크기 예측은 힘들죠. 중요한건 색인 역시 데이터라는 겁니다.

2. 색인을 만들면 항상 빠르다. - 벌써 드릴 말씀은 아니지만 잘 만들어야 빠릅니다. 

걱정마세요. 이번에 잘 만드는 방법을 배워 보세요.

3. 데이터가 적어도 인덱스가 유용하다. - 아닙니다. 데이터가 많을 수록 인덱스는

환상의 속도를 비례적으로 낼 수 있습니다. - 권고적으로 테이블의 크기가

대략 1M 정도보다 작으면 역시나 인덱스가 없는게 유용할 수 있습니다.

우선 위 세가지만 말씀 드리고 잘못 이해하는 부분을 또 찬찬히 말씀 드리지요.

색인의 모식도를 한번 봐 보도록 할까요?

 

우선 다음과 같은 회원 테이블 정보가 있다고 생각해 보도록 하지요.

901.JPG

이 회원 테이블은 보시는 바와 같이 번호, 이름, 생긴정도를 포함하고 있습니다.

번호와 이름은 믿을만한 정보이나 모든 정보가 믿을만한건 아닙니다. - 주의하세요.

-_-;;

여하간 이런 부분이 실제 데이터페이지에는 어떻게 기록이 되어 있을까요?

 

902.JPG

내부 데이터 페이지에는 위와 같은 방식으로 저장되어 있을 겁니다.

만약 제가 다음처럼 번호 컬럼의 값을 찾고자 한다고 생각해 보도록 하지요.

903.JPG

이렇게요. 만약 제가

1 번 번호를 찾으려 한다면? 와우~ 1번에 찾았군요. 1번 페이지에 있으니 8K Byte의 IO로

찾았습니다.

7번 번호를 찾으려 한다면? 3번째 페이지에 있네요. 3 * 8K Byte 크기의 IO로 찾았습니다.

만약 13번을 찾으려 한다면? 4페이지에 있으니 32K Byte가 소요 됩니다.

데이터가 늘어나 만약 10만번째를 찾으려 한다면? 대단한 IO가 발생하겠지요?

 

이럴때 인덱스의 구조와 속도를 찬찬히 이해해 보도록 하세요.

만약 이것이 혹시 기억나실지 모르지만.. C를 배우신 분이라면 B-Tree를 아실 겁니다.

Balanced Tree 라고 불리는 구조로 이것이 생성되어 있다면?

 

여기서 잠시만. 이것은 실제 인덱스의 그림과는 다른 구조이나 제가 몇번 강의를 하면서

이해하기 쉽도록 그린 그림입니다. 이그림은 잘 이해 하시는데 다음 장에서 설명할

그림을 잘 못 이해 하시더라구요. 인덱스 모식도를 그려 볼까요?

 

904.JPG

대략 이런 식이 될겁니다. 저게 뭐냐구요? 찬찬히 설명을 드리지요.

밸런스드 트리의 근간은 말 그대로 밸런스 입니다. 균형이 중요하다는 거지요.

여기서 이렇게 생각해 볼까요?

위와 똑 같이.

1번을 찾으려 하면? 맨위의 7을 보니  1 <> 7 그러므로 아래를 보니 4, 9 ,13이 있네요.

그후. 1 < 4 그러니 4로 가면 되겠지요? 4로 가서 딱 보니 1이 있는 겁니다.

각각의 단계를 페이지와 비교해 보죠. 7에서 1개 페이지. 4에서 1개페이지를 보니 우리의 값인

1이 보이죠? 3개의 페이지를 읽었습니다.

다음 7번을 찾으려 하면? 어라 웬일이죠? 맨 위에서 찾았어요. 

그렇죠? 땡잡았네요. 1개 페이지만에 OK

다음 13 을 보면 역시 2번에 찾을수 있겠죠?  

자 저 트리의 깊이가 한단계 두단계 늘어난다고 생각해 보세요?

지금은 비록 편균적으로 3개 정도면 읽을 수 있겠지만. 노드가 늘어갈수록..

4개 페이지를 읽어 많은걸 볼 수 있구.. 5개 노드면 더 많이.. 그런 식으로 실제 테이블의

맨위부터 차근차근 긁을 때보다. - 요걸 풀스캔이라고 하죠. - 더 적은 IO로 원하는 데이터를

읽을 수 있겠지요.

여기서 중요한 용어를 이해해 보도록 하죠.

 

905.JPG

계속적으로 이야기가 나오겠지만. 위처럼 최상위위치를 Root 레벨이라고 부릅니다.

중간 단계의 레벨, 위에서는 중간 레벨이 하나 뿐이지만 B-Tree의 데이터가 많아 질수록

중간 레벨은 계속 늘어날 수 있겠죠? 이녀석들을 Non-Leaf 레벨이라고 부릅니다. 

또는 중간레벨(Inertmediate Level) 라고 부르기도 합니다. 

레벨대신 가끔 노드라고도 하지요.

끝으로 최하위의 레벨을 부를 때 Leaf레벨 또는 Leaf 노드라고도 하지요.

한글로는 각각 뿌리수준 / 잎이아닌 수준, 또는 가지단계, 또는 중간단계 / 잎수준 

이라고 부르기도 합니다. 

 

자 이제 기본적인 인덱스의 형태에 대한 이야기는 간단히 드렸구요. 다음 장에서 실제 

인덱스들을 가지고 이야기를 풀어 보도록 하지요.


감사합니다.

 
[출처] SQLER.COM http://www.sqler.com/392661 


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?




SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

오늘은 저장 프로시저에 대해서 알아볼 차례 인데요~!

 

원문http://www.sqler.com/127313

원문http://www.sqler.com/127315

 

이번에 소개해 드릴 내용은 저장 프로시져의 사용입니다.

사실 저장 프로시져는 매우~!!!  아주 자주!!!!  그리고 조금 잘 구축된 시스템이라면?

일반 쿼리(Ad - Hoc Query)는 사용하지 않고 전부 이 저장 프로시져로 생성합니다.

"??  여태까지 일반 쿼리를 열시미 배우고 간신히 조금 쓸만한데 왜!!!!  저장 프로시져를

또 만들어 쓰는 겁니까아~~~~"  

대부분 저장 프로시져를 처음 접하시는 분들께 듣는 불만 사항입니다.

이에 대한 답변은 간단합니다. - 

 

 

 

 저장 프로시져의 장점

1. 매우 좋은 성능

2. 보안성을 높일 수 있음.

3. 다양한 처리가 가능

4. 넷웍의 부하를 줄일 수 있음.

 

 

 

언뜻 보아서는 무쟈게 좋아 보임다..

 

아울러 코난이가 생각하는 단점으로는

 

 

 

저장 프로시져의 단점

1. 접하기가 어려움

2. VB ASP에서 호출 방식이 틀려 처음 저장 프로시져를 접할경우 거부감이 생김

3. 새로운 언어를 배우는 정도의 부담이 있음.

 

 

이라고 생각 한답니다. – 저 역시 처음 배울 때 저런 생각 이었습니다. - 전부 마음가짐에

대한 단점 이지요...

사실 부끄럽지만.. SQL7 기본강좌의 저장 프로시져 부분을 봐 오신 분이라면..

얼마나 부실한지 아실 겁니다.. 사실 저역시 잘 몰랐습니다하지만 실제 업무를 접하시면

전부 저장 프로시져 입니다반드시 넘어야 할 녀석이니 우선 마음 푹 놓으시고

샘플을 많이 봐 보세요

코난이도 매일 저거랑 싸웁니다. SQLER 님덜 조금만 힘내서 보십시다요~~

 

저장프로시져란?

보통 프로시져저장 프로시져, SP 라고도 불립니다영어로는 Stored Procedure라고 함당.

코난이는 늘 그랬던 것처럼 혼용해서 쓸 겁니다. -_-;;

뷰를 보셨지요..

뷰는 특정 SELECT 구문등을 단순화가 가능합니다. - 하지만 뷰는 성능에 영향을 주지는

못합니다프로시져는 성능에 영향을 많이 줍니다

우선 샘플을 봐 봅시다.

 

 

 

USE pubs

GO

IF OBJECT_ID('up_konan1','P') IS NOT NULL

        DROP PROC up_konan1

GO

--프로시저 생성 구문

CREATE PROC dbo.up_konan1

AS

SELECT * FROM titles

GO

 

--프로시저 수행 구문(프로시저 실행 시에는 반드시 스키마 명을 붙여주세요)

EXEC dbo.up_konan1

 1.png

 

 

 

AS 라는 프로시져 생성 구문을 보니 뷰랑 비스 하지요

PROC 라는 말만 틀리지 거의 같고 아울러 눈에 많이 익은 SELECT ~~ 로 시작 됩니다.

일반 SQL구문인 SELECT, ~~

등등의 구문으로 이루어지는데 어떻게 더 빠를 수 있나요?

자 이제 프로시져의 비밀을 풀어 봅시다.

 

 

 

 

 

일반 SQL구문을 수행할 경우

처음 수행시

1. 구문 분석단계 - SQL구문의 문법을 검사합니다.

2. 표준화 - DB의 개체들(테이블 등)에 대해서 검사합니다.

3. 보안 점검 - 해당하는 DB개체들에 대한 사용자의 사용 권한을 검사합니다.

4. 최적화 - 최적의 성능을 내기위한 사항을 적용합니다.

5. 컴파일

 

 

반복 수행시

1. 처음 수행한 일반 SQL구문의 실행 계획이 캐싱되어 있는지 확인후 이를 수행합니다

2. 캐싱되어 있지 않을 경우 처음수행시의 5단계를 다시 수행함.

 

 

 

 

 

 

 

저장 프로시져를 수행할 경우

생성시

1. 구문 분석 단계 - 프로시져 생성 구문의 SQL구문들을 검사합니다.

2. 표준화 - DB의 개체들(테이블 등)에 대해서 검사합니다.

3. 보안 점검 - 프로시져에 대해서 생성이 가능한지 검사합니다.

4. 해당 프로시져의 구문과 생성 정보를 저장합니다.

 

첫 실행시

1. 보안 점검 - 해당하는 DB개체들에 대한 사용자의 사용 권한을 검사합니다.

2. 최적화 - 최적의 성능을 내기위한 사항을 적용합니다.

3. 컴파일후 수행 계획을 생성후 캐시에 저장후 실행합니다.

 

반복 수행시

1. 실행 계획이 캐싱이 된지 확인후 실행 합니다.

2. 캐시에 실행 계획이 없을 경우 처음 실행 과정을 반복 합니다.

 

 

 

자 어떠신지요프로시져 수행과 일반 쿼리 수행시 별로 다른점은 없는 듯 하지요?

하지만 해당 작업중 SQL수행시의 과정은 오로지 캐싱에만 의존해야 합니다.

따라서 이는 실행 계획의 재사용으로 인해 파라미터 스니핑이라는 문제가 발생 수 있습니다.

이는 SQL Server  CBO(Cost Based Optimazation) 기반 설계라 이런 문제가 발생합니다.

 

파라미터 스니핑은 조금 만 검색하셔도 많은 자료를 얻으실 수 있을 것이므로 여기서는 자세히 설명해드리지는 않겠습니다.

 

 

이제 저장 프로시저를 생성하는 방법에 대해서 알아보도록 하겠습니다.

 

 

 

CREATE PROC [ EDURE ] procedure_name [ ; number ]
     [ { @parameter data_type }
        
 [ VARYING ] [ = default ] [ OUTPUT ]
    
 ] [ ,...n ]

[ WITH
     { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]

[ FOR REPLICATION ]

AS sql_statement [ ...n ]

  

CREATE PROCEDURE(Transact-SQL): http://msdn.microsoft.com/en-us/library/ms187926(v=SQL.110).aspx

 

 

저장 프로시져는 위와 같은 어려워 보이는 방식으로 생성합니다.

하지만 코난이도 몇가지 방식 사용 안합니다관심 있으시거나 방바닥의 머리칼 하나

가만 두지 못하시는 분들은 온라인 도움말(북스 온라인)을 참고 하세요.. 

 

일반적인 프로시져의 생성

 

 

 

USE pubs

GO

 

--프로시져 생성구문

CREATE PROC dbo.up_konan2

AS

SELECT pub_id 저자

, type 책종류, royalty 티 ytd_sales , AVG(price) 평균값

FROM dbo.titles

GROUP BY pub_id, type, royalty, ytd_sales

WITH CUBE

GO

 

--프로시져 수행 구문

EXEC dbo.up_konan2

2.png

 

 

 

 

프로시져 수정

대부분의 수정 구문처럼 ALTER 구문을 사용 합니다.

간단히 약간 수정을 가해 보지요.

 

 

 

--프로시저 수정 구문

ALTER PROC dbo.up_konan2

AS

SELECT pub_id

FROM dbo.titles

GO

 

--프로시져 수행 구만

EXEC dbo.up_konan2

 3.png

 

 

 

약간이 아니라 많이 틀린가용 ^_^;;

ALTER 명령의 장점 간단히 언급해 드렸지용?

DROP을 할 경우 여러 묶여 있는(sysobjects 테이블의 id로 묶여 있는여러 개체들과

비호환의 문제 , 또는 유저에 대한 권한 문제가 있을 수 있으므로..

가능한 저렇게 ALTER 구문을 쓰시면 좋습니다.

물론 CREATE -> ALTER로 바낀것 뿐이니 어렵지 않으실 겁니당 ^_^

 

프로시져 삭제

저장 프로시져의 삭제 역시 만만치 않게 쉽습니다.

DROP이라는 구문 기억 나시죠?

 

--프로시저 삭제

DROP Proc dbo.up_konan2

 

 

 

어떠세요간단하지요. ^_^

 

프로시져 생성 구문 조회

저장 프로시져를 생성후 생성 구문을 추후에 조회하실 수 있습니다.

 

 

if OBJECT_ID('up_konan3','P') IS NOT NULL

        DROP PROC up_konan3

GO

--프로시져 생성 구문

CREATE PROC dbo.up_konan3

AS

SELECT pub_id, title

FROM dbo.titles

GO

 

--프로시저 수행구문

EXEC dbo.up_konan3

go

 

--생성된 프로시저의 내용 조회

sp_helptext up_konan3

GO

 

 

간단히 보실 수 있지용? ^_^

컨트롤 + T 키를 누르신후 결과를 Text모드로 보시면 더 잘 보입니다. ^_^

프로시져의 장점으로 보안성을 높일 수 있다고 말씀 드렸지요?

하지만 저렇게 프로시져 생성 구문을 아무나 볼 수 있다면 문제지용? ^_^

프로시져 생성 구문을 암호화 시켜 보지요. ^_^

 

저장 프로시져 생성구문 암호화


자 어떠신지용 - 암호화 되어서 보실 수 없을 겁니다. ^_^  어렵지 않으시죵?

 

저장 프로시져의 종류

저장 프로시져의 종류는 3가지 라고 보시면 됩니다.

1. 사용자 정의 저장 프로시져 - 여지껏 저희가 생성하고 수행해본 것을 말하지용 ^_^

2. 시스템 저장 프로시져 - sp_help, sp_helptext 와 같이 sp_로 시작하는 프로시져.

3. 확장 시스템 저장 프로시져 - xp_ 로 시작하는 프로시져를 의미 합니다.

예를 들면..


 


EXEC master..xp_cmdshell 'dir'
 


와 같은 시스템 저장 프로시져를 의미 합니다. ^_^

 

이 정도면 어느 정도 생성 방법은 설명을 드린 듯 하네요.

또한 프로시저를 생성 시에는 반드시 sp_로 만들지 마시길 바랍니다. SQL Server 내부적으로 프로시저 수행시 sp로 시작하는 단어면 우선 시스템 프로시저인지 검사를 하게 되는데.. 이는 불필요한 작업이 될 수 있습니다대부분의 많은 사람들은 user sp라고 해서.. usp_ 라고 많이들 사용하십니다참고가 되셨으면 좋겠네요 ^^;

[출처] SQLER.COM http://www.sqler.com/392656


SQL2011(코드명 Denali) 시리즈 강좌 리스트

[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?



SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?

이 내용은 2011년 6월 현재 SQL2011(코드명 Denali) Beta를 기준으로 작성 되었으며 SQL2011(코드명 Denali) 공식버전(RTM) 발표까지 꾸준히 업데이트 예정입니다.
아울러, 현재 Beta버전이지만 강좌를 따라해 보시는데 아무 문제 없으실거에요. 도움 되시길 바랍니다.
==================================================================================================



안녕하세요이스트럭(강동운입니다.

 

오늘은 뷰에 대해서 알아볼 차례 인데요~!

사실 이번 강좌 부터는.. 사이트 지기인 코난님께서 쓰셨던 강좌를 바탕으로 제가 살짝 손만 봤습니다. ^^

 

원문http://www.sqler.com/127289

원문http://www.sqler.com/127293

 

이번에 소개해 드릴 내용은 뷰 입니다.  중요한 DB의 개체 이지요뷰는 가상의 테이블입니다.

 

지난 서브쿼리 강좌에서 인라인 뷰라는 예제를 통해 저희는 뷰라는 단어를 이미 한번 쯤은 들어봤습니다.

 

뷰는 - 테이블의 거울이다

뷰는 테이블의 거울이지만 거울은 원래 모습을 다양하게 비출 수도 있지요.

뷰는 테이블의 거울이다라는 샘플을 보여 드리지요. ^_^

 

 

 

 

USE pubs

GO

 

--konan_view_test1 이라는 뷰를 생성합니다.

CREATE VIEW konan_view_test1

AS

SELECT * FROM titles

GO

 

--뷰를 조회 합니다.

SELECT * FROM konan_view_test1

GO

1.png


 

자 데이터를 조회해 보시면테이블과 같은 처리가 되지용? ^_^

 

뷰를 다르게 생성해 쓸 수 있습니다. ^_^

 

 

 

 

USE pubs

GO

--konan_view_test2 이라는 뷰를 생성합니다.

 

CREATE VIEW konan_view_test2

AS

SELECT title, type, price FROM titles

GO

--뷰를 조회 합니다.

 

SELECT * FROM konan_view_test2

GO

 2.png

 

 

이렇게 쓸 수도 있습니다. ^_^

사용자가 볼 경우를 생각해 보세요일반 사용자들이 볼 경우

title_id라는 이상한 값들이 필요 할까요?

pubs_id라는 출판사 ID의 고유 값이 의미가 있을까요아니지요?

뷰를 이용하면 사용자가 원하는 데이터에만 초점을 맞추게 할 수 있습니다.

 

또 다른 뷰의 샘플을 봐 보실까요?

 

 

 

USE pubs

GO

 

--konan_view_test3 이라는 뷰를 생성합니다.

CREATE VIEW konan_view_test3

AS

SELECT

           titles.title

,          authors.au_lname

,          publishers.pub_name

FROM              dbo.titles

INNER JOIN       dbo.titleauthor  ON titles.title_id = titleauthor.title_id

INNER JOIN       dbo.authors      ON titleauthor.au_id = authors.au_id

INNER JOIN       dbo.publishers   ON titles.pub_id = publishers.pub_id

GO

 

--뷰를 조회합니다..

SELECT * FROM konan_view_test3

GO

 

 3.png

 

 

상당히 복잡해 보이는 뷰이지요? ^_^

대강 봐도 조인을 3개의 테이블과 하는 군요이럴 경우 저렇게 조인구문을 길게~~

쓰는 것 보다는

 

뷰로 생성한후 뷰를 가지고 장난을 치는 것이 복잡한 질의를

계속 사용하는 것보다 훨씬 쉬울 겁니다. ^_^

 

 

 

 

이제 뷰를 생성하는 방법에 대해서 알아보도록 하겠습니다.

 

뷰의 생성 구문은 아래와 같습니다.

 

CREATE VIEW [ < database_name > . ] [ < owner > . ] view_name [ ( column [ ,...n ] ]
[ WITH < view_attribute > [ ,...n ] ]
AS
select_statement
[ WITH CHECK OPTION ]

< view_attribute > ::=
     { ENCRYPTION | SCHEMABINDING | VIEW_METADATA }

 

CREATE VIEW(Transact-SQL) Denali: http://msdn.microsoft.com/en-us/library/ms187956(v=SQL.110)

 

 

 

 

USE pubs

GO

 

CREATE VIEW titles_view

AS

SELECT title, type, price, pubdate

FROM titles

GO

 

--뷰를 조회합니다.

SELECT * FROM titles_view

GO

4.png

 

 

 

 

간단한 뷰의 생성 샘플 입니다.

 

아래의 쿼리를 이용해서 뷰의 생성 구문을 보실 수 있습니다. ^_^

 

 

 

 

sp_helptext titles_view

 

 

 

자 위처럼 해 보시문???

뷰 생성 구문이 보일 겁니다. ^_^

만약 정보를 숨기기 위한 뷰라면조심 하셔야 겠지요

보안상의 문제가 있을 뷰를 생성 하실 경우는 

뷰에대한 암호화 옵션을 주셔서 뷰 생성 구문을 숨기실 수 있습니다.

 

 

 

 

USE pubs

GO

 

--속성으로 price * royalty * ytd_sales 값을 amt_due

--로 줄 수 있다.

CREATE VIEW accounts (title, advance, amt_due)

WITH ENCRYPTION

AS

SELECT title, advance, price * royalty * ytd_sales

FROM titles

WHERE price > 5

GO

--뷰를 생성후 암호화된 뷰의 생성구문을 보려 하면?

SET language '한국어

go

sp_helptext accounts

 

 

개체 'accounts'의 텍스트가 암호화되었습니다.

 

 

 

개체 'accounts'의 텍스트가 암호화되었습니다.

라는 메세지와 함께 뷰 생성 구문을 보실 수 없으실 겁니다.

이때는 반드시 생성하신 분이 뷰 생성 스크립트를 백업을 안전한 곳에 해 두셔야 겠지요?

 

다음은 Check 옵션 입니다.

 

 

 

USE pubs

GO

 

CREATE VIEW CAonly

AS

SELECT au_lname, au_fname, city, state

FROM authors

WHERE state = 'CA'

GO

 

 

 

 

이런 경우를 생각해 봅시다.

위의 뷰는 뷰의 정의대로 state 'CA'인 사람의 정보만 나타날듯 하지요?

맞습니다그런데...

만약 state 'CA'인 사람의 데이터를 수정해서 'OR'이라는 곳에 거주하게 한다면?

이게 가능할까요???

 

 

 

SELECT * FROM CAonly

 

--잠시후 말할 뷰의 수정이다.

--뷰에대한 수정은 분명 가능하다.

--여기선 이 WHERE state = 'CA' 

--'CA'에서 사는 사람만 보는 것인데..

--이에 대해서 수정을 가해 OR로 바꾸는 것이다.

--질의가 될지 안될지 먼저 생각해 보자.

UPDATE CAonly SET state = 'OR' WHERE au_lname = 'White'

 

 

 

 

답을 보셨나요? ^_^ !!!  수정 됩니다.!!!!!

이런 황당할데가!!!!

그럼 어떻게 이런 수정 작업이 불가하게 해야 할까요!!!!

이럴때 사용하는것이 바로 WITH CHECK OPTION 입니다.

 

 

 

 

 

USE pubs

--인포메이션 정보 뷰에서 해당 뷰 이름이 존재하면?

--지워라 라는 구문 이다.

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS

WHERE TABLE_NAME = 'CAonly')

DROP VIEW CAonly

GO

--뷰생성

CREATE VIEW CAonly

AS

SELECT au_lname, au_fname, city, state

FROM authors

WHERE state = 'CA'

--체크 옵션을 사용한다.

WITH CHECK OPTION

GO

--CA OR로 변화 시키려 하면?

UPDATE CAonly SET state = 'OR' WHERE au_lname = 'Carson'

 

Msg 550, Level 16, State 1, Line 2

대상 뷰가 WITH CHECK OPTION을 지정하거나 WITH CHECK OPTION을 지정하는 뷰에 걸쳐 있고 해당 연산의 하나 이상의 결과 행이 CHECK OPTION 제약 조건을 충족하지 않았으므로 삽입 또는 업데이트 시도가 실패했습니다.

문이 종료되었습니다.

 

 

WITH CHECK OPTION이 걸려 있어서 수정이 불가하다는 메세지를 볼 것이다.

 

다른 뷰 생성의 옵션들은 찬찬히 설명을 드리지요. ^_^

 

아울러 뷰에 대한 정보를 보고 싶으시면???

엔터프라이즈 관리자 에서는

DB선택 -> 뷰 선택 -> 해당 뷰 선택후 등록정보 하면?

뷰에대한 정보를 보실 수 있으며...

질의 분석기에서 정보를 보시려면?

 

 

 

sp_help CAonly

 

 

 

이렇게 뷰에 대한 정보를 보실 수 있습니다.

 

다음은 뷰 수정에 대해서 보시지요. ^_^

 

 

CREATE VIEW All_authors (au_fname, au_lname, address, city, zip)

AS

SELECT au_fname, au_lname, address, city, zip

FROM pubs..authors

GO

 

--Public역할(일종의 사용자 그룹이라고 생각 하세요)

--뷰를 SELECT할 수 있는 권한 부여

--GRANT SELECT, UPDATE등의 권한을 부여하는 명령 입니다.

--추후에 배우게 되실 겁니다. ^_^GRANT SELECT ON All_authors TO public

GO

 

--이때 DROP하고 뷰를 재생성 하면?

 

 

아직 배우진 않았지만, GRANT 권한할당 명령어가 있습니다.

만약 특정 계정에 대해서 GRANT로 조회권한(SELECT)를 허용한뒤에

뷰를 DROP 후 재 생성하면특정 계정에 부여했던 조회권한(SELECT)가 사라지게 됩니다.즉 다시 권한을 부여하는 문제가 생깁니다.

 

따라서 이런 문제를 방지하기 위해 ALTER VIEW 명령어로 VIEW를 수정하는 것이 좋습니다.

 

 

 

ALTER VIEW All_authors (au_fname, au_lname, address, city, zip)

AS

SELECT au_fname, au_lname, address, city, zip

FROM pubs..authors

WHERE state = 'UT'

GO

 

 

 

 

마지막으로 뷰 삭제에 대해서 알아보도록 하겠습니다.

 

 

 

DROP VIEW 뷰명

 

 

 

감사합니다.


[출처] SQLER.COM http://www.sqler.com/392650


SQL2011(코드명 Denali) 시리즈 강좌 리스트
[SQL2011강좌] 1. 코드명 Denali 설치 방법
[SQL2011강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011강좌] 4. DDL 1탄: 테이블 생성
[SQL2011강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011강좌] 6. Primary key와 Unique 제약조건
[SQL2011강좌] 7. DML 1탄 INSERT
[SQL2011강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011강좌] 9. Sequence
[SQL2011강좌] 10. pubs, northwind Database 예제 설치
[SQL2011강좌] 11. SELECT(단일 테이블)
[SQL2011강좌] 12. SELECT(JOIN)
[SQL2011강좌] 13. UPDATE, DELETE 절
[SQL2011강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011강좌] 16. SubQuery(서브쿼리)
[SQL2011강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011강좌] 19. 인덱스에 대한 이해
[SQL2011강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011강좌] 21. 트랜잭션에 대한이해
[SQL2011강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011강좌] 23. 잠금에 대한 이해
[SQL2011강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011강좌] 25. 백업과 복구 전략
[SQL2011강좌] 26. 커서란?



SQL2011(코드명 Denali) 시리즈 동영상 강좌 리스트
[SQL2011 동영상 강좌] 1. 코드명 Denali 설치 방법
[SQL2011 동영상 강좌] 2. SSMS 접속 및 간단한 쿼리 실행
[SQL2011 동영상 강좌] 3. SQL Server 의 MDF, LDF 그리고 데이터베이스 생성하기
[SQL2011 동영상 강좌] 4. DDL 1탄: 테이블 생성
[SQL2011 동영상 강좌] 5. DDL 2탄: 쿼리를 이용한 테이블 컬럼 추가 및 삭제
[SQL2011 동영상 강좌] 6. Primary key와 Unique 제약조건
[SQL2011 동영상 강좌] 7. DML 1탄 INSERT
[SQL2011 동영상 강좌] 8. DML 1탄 INSERT(identity 속성)
[SQL2011 동영상 강좌] 9. Sequence
[SQL2011 동영상 강좌] 10. pubs, northwind Database 예제 설치
[SQL2011 동영상 강좌] 11. SELECT(단일 테이블)
[SQL2011 동영상 강좌] 12. SELECT(JOIN)
[SQL2011 동영상 강좌] 13. UPDATE, DELETE 절
[SQL2011 동영상 강좌] 14. DISTINCT, UNION, UNION ALL 키워드
[SQL2011 동영상 강좌] 15. ORDER BY, GROUP BY, HAVING
[SQL2011 동영상 강좌] 16. SubQuery(서브쿼리)
[SQL2011 동영상 강좌] 17. 뷰에 대한 이해 및 생성, 수정, 삭제
[SQL2011 동영상 강좌] 18. 저장 프로시저에 대한 이해, 생성, 수정, 삭제
[SQL2011 동영상 강좌] 19. 인덱스에 대한 이해
[SQL2011 동영상 강좌] 20. 클러스터드 인덱스와 넌 클러스터드 인덱스
[SQL2011 동영상 강좌] 21. 트랜잭션에 대한이해
[SQL2011 동영상 강좌] 22. 트랜잭션의 격리수준 4가지
[SQL2011 동영상 강좌] 23. 잠금에 대한 이해
[SQL2011 동영상 강좌] 24. 백업과 복구에 대한 이해(풀백업, 차등백업, 트랜잭션 로그 백업)
[SQL2011 동영상 강좌] 25. 백업과 복구 전략
[SQL2011 동영상 강좌] 26. 커서란?