수안이의 컴퓨터 연구실

  • Mainpage
  • About Me
  • Tags
  • Metapage
  • Notice
  • Location
  • Keywords
  • Guestbook
  • Admin
  • Write an Article
  • Total | 1620999
  • Today | 379
  • Yesterday | 482

7 Articles, Search for 'SQL Server 2005'

  1. 2007/07/23 SQL Server 2005에서 TRY/CATCH를 사용하여 교착 상태 해결
  2. 2007/05/25 SQL Server 2005에서 XML 데이터 형식을 위한 성능 최적화
  3. 2007/05/25 Microsoft SQL Server 2005의 XML 옵션
  4. 2007/05/23 VS.NET으로 개발하는 SQL 서버 2005
  5. 2007/05/22 SQL 서버 2005 관리자가 알아야 할 변화
  6. 2007/05/22 SQL 서버 2005, 그 변화 속으로
  7. 2007/05/21 SQL 서버 2005 보안
Database/MSSQL2007/07/23 09:46

SQL Server 2005에서 TRY/CATCH를 사용하여 교착 상태 해결

Ron Talmage

오늘날의 RDBMS 아키텍처에서 교착 상태는 피할 수 없으며 고용량의 OLTP 환경에서 흔히 나타납니다. 하지만 .NET 공용 언어 런타임 덕분에 SQL Server 2005는 개발자에게 새로운 오류 처리 방법을 제공하고 있습니다. 이번 달 칼럼에서 Ron Talmage는 TRY/CATCH를 사용하여 교착 상태를 해결하는 방법을 보여줍니다.

T-SQL은 메시지 전달에는 뛰어나지만 오류 차단 도구를 제공하는 데는 그다지 뛰어나지 않습니다. 제 생각에 거의 모든 DBA는 다음과 같은 1205 "deadlock victim" 오류 메시지에 익숙할 것입니다.

Transaction (Process ID 52) was deadlocked on lock 
resources with another process and has been chosen as
the deadlock victim. Rerun the transaction.
코드에서 교착 상태 상태 발생한 경우, 저장 프로시저에서 응용 프로그램이 얼마나 깊이
중첩되어 있는지는 중요하지 않습니다.
교착 상태에서 처리되지 않은 spid의 자체 일괄 처리를 중단하고 1205 오류가
클라이언트에 반환됩니다.
트랜잭션을 다시 시도하라는 오류 메시지가 나타나지만 T-SQL 코드 내에서는 그럴 수
없습니다. 이 다시 시도 동작은 호출 응용 프로그램에서 수행되어야 합니다.
이 오류는 쉽게 포착되지 않으며 @@ERROR가 소용 없습니다.
그다지 좋은 상황은 아닙니다.

교착 상태 예제SQL Server 2000 및 2005에서 교착 상태을 유발하는 예제에 대해 먼저 살펴보겠습니다. 이 기사에서 저는 SQL Server 2005의 최신 CTP(Community Technology Preview)를 사용했지만 SQL Server 2005 베타 2(지난 7월에 출시)를 사용해도 괜찮습니다. 베타 2 또는 최신 CTP 중 하나에 액세스하지 못하는 경우 최신 버전의 SQL Server 2005 Express를 다운로드하여 시험할 수 있습니다.

발생할 수 있는 교착 상태의 종류는 다양하지만 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/acdata/ac_8_con_7a_3xrf.asp (영문) 기사 및 교착 상태 기사 트리의 이어지는 기사 참조] 가장 흥미롭고도 어려운 교착 상태 중 하나는 판독기(reader)와 작성기(writer)가 서로를 차단하는 경우입니다. 다음 코드는 Pubs 데이터베이스에서의 이러한 교착 상태를 보여줍니다. (SQL Server 2000의 두 쿼리 분석기 창이나 SQL Server 2005의 두 Management Studio 쿼리에서 이 코드를 나란히 실행할 수 있습니다.) 첫 번째 창에서 코드 본문 앞에 다음 코드를 넣습니다.

-- Window 1 header
DECLARE @au_id varchar(11), @au_lname varchar(40)
SELECT @au_id = '111-11-1111', @au_lname = 'test1'

두 번째 연결이 있는 두 번째 창에서 다음 코드를 사용합니다.

-- Window 2 header
DECLARE @au_id varchar(11), @au_lname varchar(40)
SELECT @au_id = '111-11-1112', @au_lname = 'test2'

그런 다음 두 창에서 다음 코드를 코드 본문으로 사용합니다.

-- Body for both connections:
BEGIN TRANSACTION
INSERT Authors VALUES
(@au_id, @au_lname, '', '', '', '', '', '11111', 0)
WAITFOR DELAY '00:00:05'
SELECT *
FROM authors
WHERE au_lname LIKE 'Test%'
COMMIT

이 ID의 데이터가 Authors 테이블에 없는지 확인하기 위해 세 번째 창에서 다음 코드를 실행합니다.

DELETE FROM authors WHERE au_id = '111-11-1111'
DELETE FROM authors WHERE au_id = '111-11-1112'

이제 서로 5초 이내에 Window 1과 Window 2를 실행합니다. 각 연결이 INSERT를 종료합니다. 그리고 각각 5초를 기다린 후에 SELECT 문을 생성하므로 SELECT가 생성되기 전에 두 INSERT를 완료할 수 있습니다. 각 SELECT 문은 LIKE 'Test%'인 au_lname 값을 가지는 모든 데이터를 Authors 테이블에서 읽으려고 시도합니다. 따라서 각 SELECT 문은 자체 연결의 삽입된 데이터뿐만 아니라 다른 연결의 삽입된 데이터를 읽으려고 시도합니다.


READ COMMITTED 격리 수준은 SELECT 문이 커밋되지 않은 데이터를 읽지 않도록 하기 위해 공유 잠금을 생성합니다. 공유 잠금은 동일한 리소스상의 단독 잠금과 호환되지 않습니다. 그리고 요청자가 공유 잠금을 생성할 수 있으려면 단독 잠금이 해제될 때까지 기다려야 합니다. 각 연결의 삽입된 데이터에는 이미 단독 잠금이 있으므로 두 연결 간의 삽입된 데이터를 읽으려고 시도하는 SELECT 문이 공유 잠금을 획득하려고 시도하고 차단됩니다. 두 연결이 서로를 상호 차단하여 교착 상태를 유발합니다. SQL Server의 잠금 관리자는 교착 상태를 감지하고 배치 중 하나를 중단하고 트랜잭션을 롤백하여 차단 잠금을 해제하므로 다른 트랜잭션이 완료될 수 있습니다. 교착 상태 피해자의 트랜잭션이 롤백되고 다른 트랜잭션이 계속됩니다.


TRY/CATCH 사용 방법이제 코드 본문을 수정하고 TRY/CATCH를 사용해 보겠습니다. (이 예제에서는 SQL Server 2005 버전에서 코드를 실행해야 합니다.) TRY/CATCH를 사용할 경우 작업 코드와 오류 처리 코드를 분리해야 합니다. 작업 코드는 TRY 블록에 넣고 오류 처리 코드는 CATCH 블록에 넣습니다. TRY 블록의 코드가 실패하면 CATCH 블록으로 점프하여 코드가 실행됩니다. 이 동작은 전체 배치가 실행되는 것을 막는 오류(예: 개체 없음)를 제외한 모든 오류에서 유효합니다.

다음은 위와 동일한 코드를 사용하는 TRY/CATCH의 예제입니다. 동일한 헤더를 사용하고 코드 본문은 변경합니다.

BEGIN TRANSACTION
BEGIN TRY
INSERT Authors VALUES
(@au_id, @au_lname, '', '', '', '', '', '11111', 0)
WAITFOR DELAY '00:00:05'
SELECT COUNT(*) FROM Authors
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber
ROLLBACK
END CATCH;
SELECT @@TRANCOUNT AS '@@Trancount'

이제 SQL Server 2005에 나란히 연결된 창에서 이 코드를 실행하면 삽입을 막는 특정 데이터가 Authors 테이블에서 삭제되었는지 확인할 수 있습니다. 선행 DELETE 문을 사용할 수 있습니다.

두 창이 @@TRANCOUNT 수준 0을 반환합니다. 교착 상태는 여전히 발생하지만 이제 TRY/CATCH가 이 교착 상태를 격리합니다. 더 이상 피해자의 일괄 처리가 중단되지 않으며 교착 상태 피해자의 출력에 다음과 같은 오류를 볼 수 있습니다.

ErrorNumber
-----------
1205

@@Trancount
-----------
0

이제 TRY/CATCH가 제공하는 성능을 알 수 있을 것입니다. CATCH 블록에서 교착 상태 오류까지도 격리할 수 있기 때문에 더 이상 일괄 처리가 중단되지 않으며 T-SQL 코드가 계속해서 실행될 수 있습니다. 교착 상태 피해자를 위해 교착 상태 오류 1205는 T-SQL 코드를 CATCH 블록에 넣습니다. 이 블록에서 새로운 오류 처리 기능을 사용하여 코드를 탐색할 수 있습니다. 선행 코드에서는 @@ERROR 대신 ERROR_NUMBER()만을 사용하지만 ERROR_MESSAGE(), ERROR_PROCEDURE(), ERROR_SEVERITY() 및 ERROR_STATE()를 사용할 수도 있습니다. 이 기능은 쉬우면서도 이전의 기능보다 훨씬 뛰어난 성능을 제공합니다.


참고로 선행 CATCH 블록 코드에는 ROLLBACK이 포함되는데 그 이유는 교착 상태 오류가 격리되더라도 트랜잭션이 롤백되지 않기 때문입니다. 트랜잭션은 여전히 불안하지만 이제 TRY/CATCH 내에서 이 트랜잭션을 롤백하는 것이 여러분의 책임입니다. 그렇다면 무슨 차이가 있습니까? 비록 트랜잭션을 계속할 수는 없더라도 다시 시도할 수는 있다는 것입니다.


TRY/CATCH에서 다시 시도SQL Server 2000의 T-SQL에서 1205 오류는 "트랜잭션을 다시 실행"하라는 암시입니다. 문제는 트랜잭션을 다시 실행할 수 없다는 것입니다. 적어도 SQL Server 2000의 T-SQL에서는 그렇습니다. 하지만 SQL Server 2005의 TRY/CATCH를 사용하여 교착 상태 오류를 격리할 수 있으므로 이제 트랜잭션을 다시 시도할 수 있습니다.


다음 코드 본문은 다시 시도를 실행하기 위한 한 방법을 보여줍니다. 위에 나타난 동일한 헤더와 함께 이 코드를 다시 사용하십시오.

DECLARE @Tries tinyint
SET @Tries = 1
WHILE @Tries <= 3
BEGIN
BEGIN TRANSACTION
BEGIN TRY
INSERT Authors VALUES
(@au_id, @au_lname, '', '', '', '', '',
'11111', 0)
WAITFOR DELAY '00:00:05'
SELECT * FROM authors WHERE au_lname LIKE 'Test%'
COMMIT
BREAK
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ErrorNumber
ROLLBACK
SET @Tries = @Tries + 1
CONTINUE
END CATCH;
END

이 코드가 수행하는 동작은 WHILE 루프를 사용하여 다시 시도를 추가하는 것입니다. 저는 다시 시도 횟수를 세 번으로 설정했지만 변경이 가능합니다. 요컨대 이전에는 불가능했지만 이제는 T-SQL 내에서 교착 상태 피해자의 코드를 다시 시도할 수 있습니다.


하지만 전체 트랜잭션은 WHILE 루프 외부가 아니라 내부에 있다는 점에 주의하십시오. 따라서 각 루프 내에서 트랜잭션이 시작할 뿐만 아니라 COMMIT(TRY 블록이 실행되는 경우) 또는 ROLLBACK(CATCH 블록이 실행되는 경우)으로 끝납니다. TRY 블록은 BREAK 명령으로 끝나며 이 TRY 블록이 성공한 경우 WHILE 루프가 종료됩니다. CATCH 블록은 다시 시도 카운터를 증가시키며, WHILE 루프를 다시 실행하는 CONTINUE 명령으로 끝납니다. 1205 오류와 마찬가지로 실제로 트랜잭션을 다시 시도하는 코드가 있습니다. 하지만 이제 T-SQL 내에서 다시 시도가 완벽하게 수행됩니다.


SQL Server 2005에는 교착 상태를 해결하기 위한 다른 방법이 있습니다. 예를 들어, SNAPSHOT ISOLATION 수준과 READ COMMITTED용의 새로운 옵션(READ COMMITTED SNAPSHOT)이 있습니다. 하지만 이제 SQL Server 2005에서 트랜잭션을 코딩하고 교착 상태 오류를 격리한 후 트랜잭션을 다시 시도할 수 있기 때문에 훨씬 더 강력해진 도구를 마음대로 사용할 수 있습니다.

"MSSQL" 카테고리의 다른 글
  • Microsoft SQL Server 2008 출시! (0)2008/08/10
  • SQL Server Hardware Tuning and Performance Moni... (0)2007/07/25
  • SQL Server 2005에서 TRY/CATCH를 사용하여 교착... (0)2007/07/23
  • The Value of Merge-Join and Hash-Join in SQL Se... (0)2007/06/22
  • Microsoft SQL Server 2000 Distributed Queries:... (0)2007/06/22
2007/07/23 09:46 2007/07/23 09:46
Posted by webdizen
Tags SQL Server 2005, 교착상태
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3090

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/25 15:51

SQL Server 2005에서 XML 데이터 형식을 위한 성능 최적화

Shankar Pal, Babu Krishnaswamy, Vasili Zolotov, Leo Giakoumakis _ Microsoft Corporation


적용 대상:
SQL Server 2005

요약: 이 문서에서는 Microsoft SQL Server 2005에서 XML 데이터 형식의 쿼리 및 데이터 수정 성능을 향상시키기 위한 몇 가지 방법을 설명합니다. 이 문서를 최대한 활용하기 위해서는 SQL Server 2005의 XML 기능에 익숙해야 합니다. 배경 자료로 MSDN 기사 Microsoft SQL Server 2005에서 XML 지원 및 Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법을 참조하십시오.


소개

엔터프라이즈 응용 프로그램은 반구조적 데이터 및 구조화되지 않은 데이터 모델링에 XML을 점점 더 많이 사용하고 있습니다. Microsoft SQL Server 2005는 이러한 응용 프로그램 개발을 돕기 위해 XML 데이터 처리를 위한 광범위한 지원을 제공합니다. XML 데이터는 XML 데이터 형식 열에 원시적으로 저장되어, XML 스키마의 모음에 따라 형식화되거나 형식화되지 않은 상태로 남아 있을 수 있습니다. 그리고 Last Call 및 XML 데이터 조작 언어에서 현재 부상하고 있는 W3C 권장 사항인 XQuery를 통해 세분화된 데이터 조작이 지원됩니다. 쿼리 성능을 향상시키기 위해 XML 열을 인덱스할 수 있습니다. 엔터프라이즈 응용 프로그램은 반구조적 데이터 및 구조화되지 않은 데이터를 모델링하기 위해 점점 더 많이 XML을 사용하고 있으므로 SQL Server 2005의 XML 지원을 통해 이점을 얻게 될 것입니다.

이 문서에서는 XML 데이터 형식을 사용하는 응용 프로그램의 저장소, 쿼리 및 데이터 수정을 최적화하기 위한 제안을 제공합니다. 이러한 제안은 코드 샘플을 통해 설명됩니다. XML 데이터 모델링 및 사용을 위한 최상의 실행 방법에 관한 설명은 관련 MSDN 기사 Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법을 참조하십시오. 또한 매핑을 사용하는 XML 뷰 기술의 최적화에 관한 내용은 MSDN Library에서 SQLXML 성능 최적화 (영문)를 참조하십시오.

이 문서에서는 우선, 데이터베이스 설계 원리를 포함하여 XML을 사용한 데이터 모델링 지침을 살펴본 다음 응용 프로그램의 성능 최적화를 위한 쿼리 및 데이터 수정 지침을 제공합니다.


XML 데이터 형식을 이용한 데이터 모델링

XML 데이터 형식은 기업 내의 반구조적 데이터 및 구조화되지 않은 데이터에 데이터 모델링 기능을 제공합니다. XML 저장소 및 쿼리 처리의 성능은 데이터베이스 스키마 설계에 좌우되며 XML 열에서 XML 데이터 및 속성 승격의 구조 및 단위와 같은 요소를 포함합니다.

맨 처음 내려야 할 결정은 응용 프로그램에 XML 데이터 모델의 기능이 필요한지 여부입니다. 구조화된 데이터는 관계형으로 가장 잘 모델링되고 관계형 열을 가진 테이블에 저장됩니다. 문서 순서 및 포함 계층을 유지해야 하고 재귀 구조를 가진 반구조적 데이터 또는 태그 데이터를 사용하는 경우 XML 데이터 모델이 가장 적합합니다.

XML 데이터 형식 열에 구조화된 데이터를 저장하면 유용한 경우가 종종 있는데, 예를 들면 데이터가 유연한 구조를 갖거나 구조가 사전에 알려져 있지 않은 경우입니다.

이런 시나리오는 개체에 대한 메타 데이터 정보가 XML로 모델링되고 XML 데이터 형식 열에 저장되는 경우 속성 관리에서 발생합니다. 다른 구조 및 콘텐츠 모델을 사용하는 서로 다른 형식의 개체 속성이 같은 XML 열에 저장되고 서로 쿼리될 수 있습니다. 가장 자주 쿼리되는 속성은 동일한 테이블 또는 다른 테이블의 열로 승격됩니다. 승격된 속성을 인덱싱하고 쿼리할 수 있으며 쿼리 계획은 XML 열을 쿼리하는 것보다 더 단순합니다.

또는 들어오는 XML 데이터는 테이블로 분해되어 SQL 언어를 사용하여 쿼리될 수 있습니다. XML 생성이 쿼리 작업 부하의 중요한 부분인 경우 XML 데이터 형식 열에 XML 데이터의 중복된 복사본을 저장하는 것이 유용할 수 있습니다. 중복된 복사본은 XML 생성의 런타임 비용을 방지합니다.

XML 데이터 형식을 이용한 데이터 모델링에는 절대적인 규칙이 없습니다. 각 모델링 상황에서 장점과 단점을 신중하게 심사숙고해야 합니다. 그리고 형식화된 XML 열과 형식화되지 않은 XML 열 중에서의 선택 및 XML 태그가 데이터에 도입되는 방법도 마찬가지로 중요합니다. 이 섹션의 나머지 부분에 이에 대한 고려 사항과 기타 고려 사항이 논의되어 있습니다.


XML 데이터의 구조

동일한 데이터를 서로 다른 방식(예: 요소 중심, 특성 중심, 요소와 속성의 결합)으로 표시할 수 있습니다. 이 선택은 콘텐츠를 구성하는 것(요소 값) 및 메타 정보를 구성하는 것(특성 값)의 인식, 그리고 태그의 카디널리티(예: 요소의 다중 발생)에 의해 결정됩니다. 한 가지 방식으로 반구조적 데이터 및 구조화되지 않은 데이터에 XML 태그를 도입하는 것은 다른 저장 및 쿼리 처리 방법에 비해 더 효과적일 수 있습니다.


구체적인 태그 사용

일반적인 요소 이름을 사용하고 추가 특성을 이용하여 서로 다른 요소 형식들을 구별하는 것이 편리한 경우가 종종 있습니다. 하지만 이 방법을 이용하면 XML 인덱스 조회를 효율적으로 수행할 수 없기 때문에 이 방법은 쿼리에서 잘 작동하지 않습니다. (XML 인덱싱에 관한 자세한 설명은 XML 데이터 인덱싱을 참조하십시오.)

한편 의미적으로 풍부한 구체적인 요소 이름은 더 읽기 쉽고 더 효과적인 쿼리 계획을 생성하는 데 도움이 되는 태그를 제공합니다. 반면 매우 장황한 태그는 저장소 비용도 증가시킵니다. 다음 예제는 이 두 가지 측면을 보여줍니다.


예제: 일반적 태그와 구체적 태그의 비교

도서 및 DVD 정보에 XML 태그를 사용하기를 원한다고 가정해 봅시다. 한 가지 선택은, 두 가지 항목 형식을 구별하기 위해 두 개의 값 "book"과 "DVD" 중 하나를 갖는 @type 특성을 가진 <item>이라는 일반 요소를 사용하는 것입니다. 도서 및 DVD는 다음과 같이 표시될 수 있습니다.



도서 및 DVD에 대한 경로 식은 각각 /item[@type = "book"] 및 /item[@type = "DVD"]로 작성될 수 있습니다. 한편 다음과 같이 <book> 및 <DVD> 는 더 직접적인 XML 태그입니다.




이 표시는 더 간단한 경로 식 /book 및 /DVD를 제공합니다. 또한 @type 특성에서 술어가 제거되기 때문에 쿼리 계획도 더 간단하고 효과적입니다. 게다가 이 표시를 이용하면 형식화되지 않은 XML의 경우에, 주 XML 인덱스(XML 데이터 인덱싱에 관한 자세한 내용은 XML 데이터 인덱싱 참조)에 있는 행의 수가 4개( <item>, 에 한 행, @type 및 그 값에 한 행, <title> 에 한 행, 제목 값에 한 행)에서 3개( <book> 또는 <DVD>, 에 한 행, <title> 에 한 행, 제목 값에 한 행)로 줄어듭니다. 이로 인해 3개에서 2개 행으로 저장소 오버헤드가 감소되며 이는 상당한 절감입니다.



특성 중심 태그

특성의 값은 형식화된 XML 및 형식화되지 않은 XML 둘 다에 대한 주 XML 인덱스의 단일 행에 특성 태그와 함께 저장됩니다. 비교해 보면, 형식화되지 않은 XML의 단순한 값 요소의 값은 요소 태그와 별개의 행에 저장됩니다. 따라서 형식화되지 않은 XML 내의 특성 값을 사용함으로써 저장소가 더 적게 필요합니다.

더구나 특성의 값이 주 XML 인덱스에 있는 태그로서 동일한 행에서 구해지기 때문에 술어의 평가가 더 효과적이므로, 값의 또 다른 행에 액세스할 필요가 없습니다. 이 내용은 다음 예제에 예시되어 있습니다.


예제: 특성 중심 태그

위 예제에서는 다음과 같이 제목이 요소 대신 특성으로 모델링될 수 있습니다



형식화되지 않은 XML의 경우, 이 방식을 이용하면 주 XML 인덱스에 있는 행의 수를 3개(<book>, <title>에 각각 한 행씩, 제목 값에 한 행)에서 2개(<book>에 한 행, @title 특성에 한 행)로 줄일 수 있습니다. DVD의 경우에도 유사합니다.

경로 식 /DVD[title = "The Godfather"]는 제목이 제목에 대한 요소 중심 태그가 있는 "The Godfather"인 DVD를 찾습니다. 특성 중심 태그의 경우에는 동일한 쿼리가 /DVD[@title = "The Godfather"]로 작성되고 쿼리에 필요한 JOIN 수가 하나 줄어듭니다.


형식화되거나 형식화되지 않은 XML

형식화되지 않은XML(즉, XML 데이터가 XML 스키마에 의해 설명되지 않음)의 요소 및 특성 값은 내부적으로 유니코드 문자열로 저장됩니다. 형식화되지 않은XML에서 작업하는 경우에는 데이터를 적합한 형식으로 변환해야 합니다. 예를 들어, 경로 식 (/book/price)[1] > 19.99 가 평가될 때 <price> 의 문자열 값이 숫자 비교를 위해 십진수로 변환됩니다. 이와 같은 비교가 많으면 비용이 많이 들게 됩니다. XML 스키마가 제공하는 형식 정보는 여러 방식으로 데이터베이스 엔진에 의해 사용됩니다. 삽입 및 업데이트된 XML 데이터는 XML 스키마를 준수하는지 검증된 다음 이진 표시("XML blob")로 저장됩니다. 요소 및 특성 값은 XML 인스턴스 내에 형식화된 값으로 저장됩니다. 이렇게 하면 XML blob이 상응하는 텍스트 형식보다 더 효율적으로 구문 분석될 수 있습니다. 형식화된 값은 XML 인덱스에 저장되며 데이터 변환이 제거될 때마다 인덱스 사용을 허용합니다. 쿼리 컴파일은 형식 정보를 사용하여 XQuery 식 및 데이터 수정 문의 정적 형식 정확성을 검사합니다. 형식 불일치 오류는 컴파일 시에 탐지되며 명시적 형식 캐스트를 사용함으로써 피할 수 있습니다.

또한 형식 추론에 기반한 쿼리 최적화가 수행됩니다(예: <book> 의 <price> 가 xs:decimal 형식인 경우, (/book/price)[1] 의 xs:decimal로의 변환이 제거됩니다). 이는 XML 인덱스 조회에 긍정적인 효과를 줄 수 있습니다. (/book/price)[1] < 19.99와 같은 범위 술어는 VALUE 형식의 보조 XML 인덱스에 범위 스캔을 수행합니다. (XML 데이터 인덱싱에 관한 자세한 내용은 이 문서의 XML 데이터 인덱싱 XML 데이터 인덱싱을 참조하십시오.) 형식화되지 않은 XML에 필요한 데이터 변환은 이러한 범위 스캔을 방지합니다. 또한 XML 스키마가 단일 <price> 요소를 지정하고 각 XML 인스턴스에서 단일 <book> 요소만을 허용하는 경우에는(/book/price)[1]의 서수 [1]이 필요하지 않습니다. 형식화된 XML에는 XML 데이터 삽입 및 수정 동안 유효성 검사가 필요합니다. 유효성 검사의 비용은 결코 사소하지 않으며 스키마 정의의 복잡성 및 XML 데이터에서 발생하는 태그의 수와 같은 요소에 따라 다릅니다.



속성 승격

쿼리 처리 동안 문서 순서 및 포함 계층과 같은 구조 정보가 XML 인스턴스에 보존됩니다. 따라서 쿼리 계획이 복잡해지는 경향이 있습니다. 스칼라 값을 XML 열에서 같은 테이블이나 다른 테이블의 관계형 열로 승격하고 이 열에 대해 직접적으로 쿼리를 작성함으로써 일부 쿼리에 대한 계획이 단순화될 수 있습니다. 승격된 속성은 인덱스할 수 있습니다. 속성 값을 구체화하고 인덱싱하면, 미리 계산된 값이 쿼리 성능을 높이는 방식과 같은 방식으로 XML 열에서 XQuery를 사용할 때보다 성능이 더 좋아집니다.

속성 값을 검색하거나 속성 값을 필터로 사용하여 해당 XML blob을 검색하는 경우 속성 승격은 성능을 향상시킵니다. 후자의 경우 속성 값의 선택성이 중요한 요소입니다.

단일값 속성은 계산 열과 동일한 테이블의 열로 승격할 수 있습니다. 단일값 속성 및 다중 값 속성은 둘 다 다른 테이블의 열로 승격할 수 있고 트리거를 사용하여 유지 관리할 수 있습니다. 아래에 이 두 가지 속성 승격 방법이 설명되어 있습니다.



계산 열 사용

XML 데이터 형식 메서드를 사용하여 스칼라 값을 추출하기 위해 먼저 Transact-SQL 사용자 정의 함수가 생성됩니다. 그런 다음 사용자 정의 함수에서 정의한 계산 열이 테이블에 추가됩니다. 각각의 승격된 속성에 대해 이 두 단계가 반복되고 필요에 따라 관계형 인덱스가 이들 열에 생성됩니다.

XML 열에 대한 XQuery 식을 계산 열을 사용하는 SQL 문으로 다시 작성해야 하며, XML 인스턴스가 일치하는 행에서 검색됩니다. 쿼리 비용을 기준으로 쿼리 최적화 프로그램이 계산 열의 인덱스를 선택합니다. 계산 열은 미리 계산되므로, 승격된 속성은 XML 열을 직접 쿼리하는 것보다 더 빠른 성능을 낳습니다.

열이 SELECT 목록에서만 사용되고 술어 평가에 사용되지 않는 경우 계산 열의 인덱싱을 피할 수 있습니다. 이 경우 성능상의 이점을 위해 계산 열의 지속성만으로도 충분합니다. 계산 열이 인덱스될 때, 계산 열 식이 정확하지 않거나 명확하지 않은 경우 계산 열이 계속 유지되어야 합니다.

아래 예제는 속성 승격을 위한 계산 열의 사용을 보여줍니다.



예제: 속성 승격을 위한 계산 열 사용

ISBN을 계산 열로 승격하는 것이 시간과 노력을 들일 만한 일이 되도록, 지정된 ISBN에 따라 책을 조회하는 일반적인 작업 부하를 가정해 봅시다. 다음과 같이 ISBN을 검색하는 사용자 정의 함수를 정의합니다.





ISBN을 위해 계산 열을 docs 테이블에 추가합니다.





ISBN 열에 클러스터되지 않은 인덱스를 만듭니다.





아래 쿼리를



계산 열을 사용하기 위해 다음과 같이 다시 작성합니다.



ISBN 값의 추출이 미리 처리되어 있기 때문에 다시 작성한 쿼리는 더 간단한 쿼리 계획을 생성합니다.



속성 테이블 사용

별도의 속성 테이블은 유지 관리를 위해 삽입, 삭제 및 업데이트 트리거 설정이 필요합니다. 이 테이블은 속성 테이블의 각 행이 속성 값(피벗되지 않은 표시)을 포함하고 있는 경우의 다중값 속성에 적합합니다. 속성 테이블의 생성 및 유지 관리를 보여주는 예제를 관련 MSDN 기사 Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법에서 찾을 수 있습니다.

형제 항목의 관련 순서가 응용 프로그램에 중요한 경우 속성 테이블에 시퀀스 번호 열이 요구됩니다. 하지만 이로 인해, XML 하위 트리 삽입 및 제거의 경우 속성 테이블 유지 관리가 복잡해집니다.

편의상 단일값 속성 열을 테이블에 추가할 수 있습니다. 이렇게 하면 열에서 중복이 발생하지만 두 속성이 모두 필요한 경우 JOIN이 제거됩니다.

승격된 속성의 최대 카디널리티 N이 작고 사전에 알려진 경우, 별도의 속성 테이블 대신 N개의 계산 열을 생성하고 쿼리 프로세서가 이러한 열을 유지 관리하게 하는 것이 편리할 것입니다.



XML 데이터 대량 로드

SQL Server의 대량 로드 기능을 사용하여 XML 데이터를 XML 데이터 형식 열에 대량 로드할 수 있습니다. 여기에는 BCP IN, BULK INSERT 및 OPENROWSET 메서드가 포함됩니다.

BCP 입력은 가능한 경우 XML 데이터의 중간 복사본을 회피하도록 최적화되었습니다. 따라서 XML 열에 행 또는 열 제약 조건이 없는 경우 BCP가 세 개의 대체 방법들 중에서 최상의 성능을 갖습니다.



OpenRowset 사용

OPENROWSET는 파일에서 XML 데이터를 XML 열, 변수 및 매개 변수로 로드하는 편리한 방법입니다. 변수 또는 매개 변수에서 XML 데이터를 여러 번 쿼리하면 파일에서 같은 횟수만큼 데이터를 가져올 수 있습니다. 아래 예제에서와 같이 XML 데이터를 XML 변수로 한 번 읽어 들여 이를 여러 번 쿼리하는 것이 더 낫습니다.


예제: OPENROWSET의 출력 쿼리

다음 쿼리에서 XML 데이터는 파일에서 테이블 식 XmlFile의 [Contents] 열로 읽혀 들어갑니다. nodes() 메서드는 XML 인스턴스에서 <author> 요소를 찾습니다. 각 value() 메서드는 파일에서 XML 데이터를 매번 로드하는, <author> 요소에 관련된 경로 식을 평가합니다.




다시 작성된 아래 쿼리에 나타난 대로 성능 향상을 위해 파일 데이터를 한 번만 로드하면 됩니다. 즉, 파일 내용이 XML 변수 @xmlData로 한 번만 읽혀 들어 가고 SELECT 문에서 다시 사용됩니다.




XML 데이터 인덱싱


XML 인덱스

XML 열로의 세분화된 쿼리의 경우 XML 열에 주 XML 인덱스를 만드는 것이 좋습니다. 주 XML 인덱스는 형식화된 XML 열 및 형식화되지 않은 XML 열 모두에서 생성될 수 있고 전체 XML 열 내의 모든 경로 및 값을 인덱스합니다. 주 XML 인덱스는 XML 열에 XML 인스턴스의 분할된(shredded) 표시를 기준으로 B+트리를 만듭니다. XML 열에 XML blob뿐만 아니라 이 B+트리가 만들어지고 그 크기는 XML 열의 XML blob을 모두 합친 크기보다 더 큽니다. B+트리는 XML 데이터 형식 메서드를 이용하여 XML 데이터를 쿼리하는 데 사용됩니다. XML blob은 전체 XML blobSELECT * FROM docs와 같은 기본 테이블에서 검색되는 경우를 최적화하는 데 사용됩니다. 이렇게 하면 더 작은 크기와 직렬화 비용 덕분에 주 XML 인덱스에서 XML 콘텐츠를 직렬화할 때보다 더 빨라집니다.

보조 XML 인덱스는 쿼리 최적화 프로그램이 더 나은 계획을 제안하도록 추가 옵션을 제공합니다. 응용 프로그램은 PATH, PROPERTY, VALUE 형식의 보조 XML 인덱스를 사용함으로써 성능이 보다 더 향상될 수 있습니다.



PATH 인덱스는 XML 데이터 형식에서 /book[@ISBN = "0-2016-3361-2"]와 같은 경로 식이 발생하는 경우에 항상 유용합니다. 긴 경로 식일수록 그 이점은 더 큽니다. PATH 인덱스는 전반적으로 상당한 속도 증가를 제공합니다.
PROPERTY 인덱스는 XML 인스턴스의 여러 속성이 SELECT 문 내에서 검색되는 경우에 유용합니다. 각 XML 인스턴스의 속성을 함께 클러스터링하면 성능이 보다 더 향상될 수 있습니다.


VALUE 인덱스는 하위 항목 축(예: //-operator) 및 와일드카드(예: /book[@* = "novel"])를 포함하는 경로 식에 유용합니다. 하나 이상의 보조 XML 인덱스가 도움이 되는지 여부를 결정하기 위해서는 쿼리 작업 부하의 분석이 필요합니다. 또한 XML 데이터 인덱스의 전체적인 혜택을 측정하는 데 인덱스 유지 관리 비용을 고려해야 합니다.

대부분의 응용 프로그램은 예상되는 쿼리 작업 부하를 알고 있으며 쿼리에서 발생하는 경로만을 인덱싱하여 이점을 얻을 수 있습니다. 이 경로는 이 문서의 후반부 "속성 승격"에 설명된 대로 속성으로 승격될 수 있습니다.



부분적 XML 업데이트

XML 데이터 형식의 인플레이스 업데이트는 세분화된 데이터 수정 동안 상당한 성능 향상을 제공합니다. 새 상태(데이터 수정 후) 및 이전 상태(데이터 수정 전) 간의 차이점이 처리되고 XML 열 저장소를 비롯하여 주 XML 인덱스에 적용됩니다. 또한 주 XML 인덱스의 변경 사항이 보조 XML 인덱스에도 전파됩니다. 이렇게 하면 저장소에서 업데이트되는 데이터의 양이 더 적고 그에 따라 트랜잭션 로그가 절감되므로 성능 혜택을 얻을 수 있습니다. 대부분의 경우 이러한 절감은 새 상태 및 이전 상태를 비교하는 비용을 상쇄합니다.

이 경우에 가장 적합한 시나리오는 XML DML에서 명령문의 "값 대체"를 이용한 특성 또는 요소 값의 수정입니다. 이렇게 하려면 XML 열에 있는 각각의 주 XML 인덱스 및 보조 XML 인덱스에서 행을 하나씩 업데이트해야 합니다. 또한 이 업데이트는 업데이트된 특성 또는 요소를 포함하는 XML blob의 디스크에 있는 페이지에 로컬입니다. 물론 이전 값을 큰 값으로 대체하면 새 디스크 페이지가 기록됩니다. 다음은 업데이트가 매우 효율적인 경우의 예제입니다.


예제: 특성 값 업데이트

이 예제에 나타난 대로 <book> 의 <price> 수정은 XML 인스턴스 및 XML 인덱스의 인플레이스 업데이트를 수행합니다.



특성, 요소 또는 하위 트리 삽입의 경우, 새로 삽입된 노드 및 이 노드를 따르는 형제 항목이 해당 하위 트리와 함께 업데이트되거나 삽입됩니다. XML blob에서도 이와 비슷한 변경이 발생합니다. 노드 삭제의 경우에도 이와 유사하며 삭제 지점 위의 형제 항목이 업데이트됩니다.

최악의 시나리오는 노드를 XML 데이터 형식 인스턴스의 가장 왼쪽 조각으로서 삽입하거나 루트 요소의 가장 왼쪽 자식(child)을 삽입하는 동안 발생합니다. 이렇게 하면 전체 XML 인스턴스가 업데이트됩니다. 이 상황은 노드를 XML 인스턴스의 가장 오른쪽 조각 또는 루트 요소의 가장 오른쪽 자식(child)으로 삽입함으로써 피할 수 있습니다.

루트 요소의 가장 왼쪽 조각 또는 가장 왼쪽 자식(child)의 삭제에도 이와 비슷한 비용이 듭니다. 요소가 자주 삽입되고 삭제되는 경우에는 요소를 가장 오른쪽 조각 또는 루트 요소의 가장 오른쪽 자식(child)으로 삽입하는 편이 더 낫습니다. 다음 예제는 비용이 많이 드는 경우를 보여줍니다.


예제: 비용이 많이 드는 업데이트

<publisher> 요소가 <book> 요소의 가장 왼쪽 자식(child)으로 삽입되어 <book> 의 모든 하위 요소가 업데이트됩니다.



<publisher> 를 <book> 의 가장 오른쪽 자식(child)으로 삽입하면 더 효율적입니다.



XML 스키마 제약 조건은 삽입 지점을 결정할 수 있고 새 노드를 가장 오른쪽의 가능한 위치에 삽입하면 최상의 성능을 얻을 수 있습니다.



형식의 결합으로 인한 최적화 저해

암시적 캐스트를 요구하는 union 형식의 값은, 보조 XML 인덱스가 경로를 일치시키는 데 사용될 수 있는 경우에도 값에 대한 보조 XML 인덱스의 조회를 막습니다. 이와 같이 union 형식의 값은 범위 스캔이 VALUE 보조 XML 인덱스에서 발생하지 못하게 합니다. 자세한 내용은 이 문서의 "범위 제약 조건"을 참조하십시오. 같은 추론이 <xs:anyAttribute>에도 적용됩니다.

모델 그룹(<xs:choice> 및 <xs:all> ), 대체 그룹 및 와일드카드 섹션(xs:any)은 컨텐츠 모델로서 형식의 결합을 갖습니다. 정확한 형식이 쿼리 컴파일 및 최적화 동안 알려지지 않는 경우 런타임 형식 캐스트가 그 값에 대해 작업하기 위해 필요할 수 있습니다. 이렇게 하면 쿼리 속도가 느려집니다. 따라서 성능상의 이유로 가능한 경우 이러한 XML 스키마 구조 및 데이터 형식을 피해야 합니다.

요소의 단일 발생을 나타내는 스키마 구조를 사용하면 쿼리 최적화에 도움이 됩니다. 이러한 이유로 <xs:choice> 구조가 선택적 요소가 있는 <sequence> 에 비해 선호됩니다.



XML 인덱스 선택 비활성화

XML 인덱스가 제약 조건을 평가하기 전 또는 후에 수정되도록 쿼리 최적화 프로그램이 보장하지 않기 때문에 XML 인덱스 선택은 check 제약 조건에서 비활성화됩니다. 이 문서의 성능 지침을 따라 제약 조건이 XML blob 상에서 효율적으로 평가될 수 있도록 하기 위해 충분한 주의를 기울여야 합니다. 뿐만 아니라 XML 인덱스 선택은 CHECK OPTION이 있는 뷰에서 비활성화됩니다.



XML 열의 전체 텍스트 인덱스

XML 열의 XML 인덱스와는 독립적으로 이 열에 전체 텍스트 인덱스를 만들 수 있습니다. 전체 텍스트 인덱스는 요소 콘텐츠를 인덱싱하고 XML 태그 및 특성 값을 무시하며 태그를 토큰 경계로 사용합니다.

XQuery 함수 fn:contains()가 리터럴, 부분 문자열 일치의 의미론을 갖는 반면 CONTAINS()를 사용하는 전체 텍스트 검색은 형태소 분석을 이용한 토큰 일치를 사용합니다. 따라서 이들의 의미론은 상이합니다. 차이점을 예로 들어 보자면, 단어 "data"를 검색하면 XQuery에서는 단어 "database"와 일치하지만 전체 텍스트 의미론에서는 일치하지 반면, 단어 "drove"를 검색하면 전체 텍스트 의미론에서는 단어 "driving"과 일치하지만 XQuery에서는 일치하지 않습니다. 게다가 전체 텍스트 검색은 특성 값 검색에 사용할 수 없고, 한편 XQuery 식은 혼합 콘텐츠를 검색하기 위해 집계 함수 fn:string()을 사용해야 합니다.

전체 텍스트 인덱스가 XML 열에 존재하는 경우 다음 작업을 수행하는 것이 좋습니다.


전체 텍스트 검색을 사용하여 관심 있는 XML 값을 필터링합니다.
선택한 XML 인스턴스를 XML 데이터 형식 메서드를 사용하여 쿼리합니다. 이 단계 동안 XML 열의 XML 인덱스가 사용됩니다. 이렇기 때문에 전체 텍스트 인덱스 및 XML 인덱스를 모두 사용하게 됩니다. 전체 텍스트 검색에서 검색 단어 또는 구의 높은 선택성은 XQuery 검색을 위한 추가 처리 범위를 기본 테이블에 있는 비교적 적은 행의 수로 좁혀줍니다. 이로 인해 쿼리의 속도가 상당히 빨라질 수 있습니다. 이 접근 방법은 검색 구가 키워드 경계와 일치하는 어간으로 이루어진 경우에 사용할 수 있습니다.


예제: XQuery 일치와 전체 텍스트 결합

다음 쿼리는 키워드 'data'에 대한 전체 텍스트 검색을 수행하고 단어 "data"가 <book>의 <title>요소의 컨텍스트에서 나타나는지 확인합니다. 이 쿼리는 전체 텍스트 contains() 메서드를 사용하여 검색 단어를 포함하고 있는 XML 인스턴스를 찾습니다. 즉, XML 데이터 형식 메서드 exist()는 XML 인스턴스가 올바른 컨텍스트에서 부분 문자열을 포함하는지 확인합니다.




예제: 전체 텍스트에서 접두사 검색 사용

전체 텍스트 인덱스에서 접두사 검색을 수행할 수 있습니다. "database"와 같은 "data"로 시작하는 모든 키워드와 일치하는 쿼리에 대해, 위 쿼리는 다음과 같이 다시 작성될 수 있습니다. XQuery 검색은 "database"와도 일치합니다.



전체 텍스트 contains() 메서드에서 큰따옴표의 사용에 주의하십시오.



스냅샷 격리 및 XML 인덱스

XML 데이터 수정은 이전 XML 인스턴스를 새 XML 인스턴스로 업데이트합니다. 이러한 변경은 주 XML 인덱스 및 보조 XML 인덱스에 전파됩니다. 기본 테이블 및 XML 인덱스에서 수정된 행은 잠겨지고 행 및 페이지 잠금이 쿼리 분석기의 결정에 따라 테이블 잠금으로 에스컬레이션될 수 있습니다. 특히 작업 부하에서 수정이 잦은 경우에는 잠금 에스컬레이션으로 인해 동시성이 나빠집니다.

SQL Server 2005에서 스냅샷 기반 격리는 "스냅샷"이라는 새로운 격리 수준과 새로운 read-committed 격리 수준의 구현을 도입했습니다. 이에 대한 자세한 내용은 SQL Server 온라인 설명서에서 찾아볼 수 있습니다. 이들은 데이터베이스를 스냅샷 격리에 사용할 수 있는 경우 판독기와 작성기 사이의 잠금 경합을 제거하는 내부 버전 관리 메커니즘에 기반합니다. 잠금 경합이 감소되면 처리량이 더 높아질 수 있습니다.

스냅샷 기반 격리 하에서 읽기 작업은 동시 업데이트에서 차단되지 않고서 버전 관리되는 데이터에 액세스할 수 있습니다. 이렇게 차단이 감소되면 동시 작업 부하에서 트랜잭션 처리량이 잠재적으로 향상됩니다.

스냅샷 격리를 사용하면 업데이트 시 XML 열 값과 해당 주/보조 XML 인덱스 행이 버전 관리됩니다. 이렇게 하면, XML이 아닌 열의 수정으로 인해 포함하는 행이 버전 관리되는 경우 XML 열의 불필요한 버전 관리를 피할 수 있습니다. 이 최적화는 XML 처리에 있어 스냅샷 격리를 매우 유용하게 만듭니다.



쿼리 및 데이터 수정

인덱스된 XML에 대한 여러 value() 메서드 실행 병합

인덱스된 경우에 더 빠른 실행을 위해, SELECT 목록의 동일한 형식화된 XML 열에서 여러 value() 메서드의 실행을 결합할 수 있습니다. 실행을 결합할지 여부는 쿼리 분석기가 쿼리 비용을 기반으로 결정합니다. 이로 인해 속도가 현저히 향상됩니다. 아래에 예제가 나와 있습니다.


예제: 여러 value() 메서드 실행 결합

XML 스키마 모음 bookCollection에 있는 XML 스키마 이름 공간 "http://www.microsoft.com/book"에 의해 요소의 콘텐츠 모델이 정의된다고 가정합시다. 또한 이 예제에서 XML 열 xDoc이 docs 테이블에 추가되고 bookCollection을 사용하여 형식화된다고 가정합시다. XML 스키마 정의는 아래와 같습니다.




아래 쿼리에서는, value() 메서드가 동일한 XML 열에서 호출되고 <title> 및 <price> 요소의 단일 카디널리티가 XML 스키마에서 정적으로 추론되기 때문에 value() 메서드의 실행을 결합합니다.



최적화가 발생하려면 다음 조건이 유지되어야 합니다.

열을 형식화하는 XML 스키마 모음에서 노드의 단일 카디널리티를 추론할 수 있도록 XML 열을 형식화해야 합니다. 해당되는 경우 열 옵션 DOCUMENT을 사용하여 XML 열을 선언해야 합니다. 그렇지 않으면 nodes() 메서드를 사용하여 단일 노드 참조를 생성해야 합니다. 또한 nodes() 메서드가 단일 요소를 보장하는 데 사용되고 value() 메서드가 그러한 요소에서 특성 값을 추출하는 경우 형식화되지 않은 XML에 대해서도 최적화가 작동합니다.
최적화가 발생하려면 전체 경로를 지정해야 합니다. 와일드카드(*), 하위 항목 축(// operator), 상위 항목 축(..), XPath 함수 및 노드 테스트(예: node())를 포함하는 경로는 이러한 최적화의 발생을 막습니다.
value() 메서드의 경로 식은 술어 또는 서수를 포함하지 않을 수 있습니다.
nodes() 메서드에서 얻은 컨텍스트 항목과 관련된 경로 식에 대해 최적화가 발생하는데, 이러한 경우 value() 메서드의 첫 번째 인수는 위 제약과 더불어 전체 상대 경로여야 합니다.
value() 메서드 호출이 병합되려면 SELECT 목록에서 연속적으로 나타나야 합니다. 불연속적인 value() 메서드의 실행은 결합될 수 없습니다.

또한 xCol.value(…) = xCol.value(…)와 같은 술어에 대해 T-SQL WHERE 절의 value() 메서드에서 최적화가 발생할 수 있습니다. xCol.value(…) = constant의 술어에서는 최적화가 발생하지 않습니다.


존재 확인을 위해 exist() 메서드 사용

보다 나은 성능을 위해 가능한 경우 XML 데이터 형식의 value() 메서드 대신 exist() 메서드를 사용하십시오. exist() 메서드는 SQL WHERE 절에서 사용하는 경우 가장 유용하며 value() 메서드보다 XML 인덱스를 더 효과적으로 활용합니다. XQuery 식에서 sql:variable() 및 sql:column()을 사용하는 경우에도 마찬가지입니다.

예를 들어, exist() 메서드를 사용하여 "Writing Secure Code"라는 제목의 책을 검색하는 다음 쿼리를 살펴봅시다.



PATH 또는 VALUE 보조 XML 인덱스가 이들 인덱스에서의 값 조회(이 예제에서 "Writing Secure Code")를 포함하여 경로 식((/book/title/text())[.="Writing Secure Code"])을 평가하여 반환할 XML 인스턴스를 산출하기 위해 사용됩니다. 경로 및 검색 값의 선택성이 높은 경우 결과 실행이 열의 모든 XML blob에 대해 경로 식을 평가하는 것보다 훨씬 더 빠를 수 있습니다. 검색 값은 sql:variable() 또는 sql:column()을 사용하여 제공할 수 있습니다. 자세한 내용은 이 문서의 "XQuery 및 XML DML 식 매개 변수화"를 참조하십시오.

아래와 같이 value() 메서드를 사용하여 작성한 쿼리는



먼저 모든 책 제목을 평가한 다음 필터 "Writing Secure Code"를 적용합니다. 이렇게 하면 XML 인덱스 조회에서 필터 값 "Writing Secure Code"가 사용되지 않기 때문에 쿼리 실행의 효율성이 떨어집니다. SQL 변수 또는 또 다른 value() 메서드를 사용하여 지정한 필터 값도 유사한 동작(behavior)을 나타냅니다.

nodes()-value() 결합 사용
nodes() 메서드는 value() 메서드 내에서 사용할 수 있는 내부 노드 참조의 행 집합을 생성하여 이들 노드에서 스칼라 값을 추출합니다. 이들 메서드를 함께 사용하여 XML 데이터를 관계형 형식으로 표시할 수 있습니다.

아래 예제에서 보는 대로, value() 메서드에서 컨텍스트 노드의 특성을 선택하는 데 사용되는 서수 술어가 제거될 수 있도록 nodes() 메서드의 출력에서 각 행은 단일 참조를 표시합니다. 또한 nodes() 메서드가 정확히 하나의 참조를 제공할 경우 nodes() 메서드를 완전히 제거하면 쿼리가 더 빠르게 수행됩니다. 이러한 최적화는 XML 변수 및 매개 변수에 가장 유용합니다.

예제: nodes() 메서드로 서수 술어 제거

이 쿼리는 docs테이블의 xCol 열에 있는 각 책의 인스턴스에서 ISBN 특성을 추출합니다. nodes() 메서드는 각 개별 <book> 요소(컨텍스트 노드)에 대한 별도의 참조를 내보내고 컨텍스트 노드에는 최대 하나의 @ISBN 특성이 있을 수 있습니다.



각 XML 인스턴스에서 요소가 하나만 발생할 경우 다음의 다시 작성된 쿼리가 더 빠릅니다.



XML blob을 위한 최적화

XML 변수 및 매개 변수의 더 나은 확장성을 위한 여러 개의 tempDB 파일

XML 변수 및 매개 변수는 그 값이 작은 경우에는 주 메모리를 저장소로 사용합니다. 단, 큰 값은 tempdb 저장소에서 백업합니다. 다중 사용자 시나리오에서 많은 수의 대형 XML blob이 발생할 경우 tempdb 경합이 충분한 확장성을 위해 병목 상태를 일으킬 수 있습니다. 여러 개의 tempdb 파일을 만들면 저장소 경합이 감소되고 확장성이 훨씬 더 좋아집니다. 다음 예제는 여러 개의 tempdb 파일을 만들 수 있는 방법을 보여줍니다.


예제: 여러 개의 tempdb 파일 만들기

이 예제에서는 각각 처음 크기가 8MB인 두 개의 tempdb용 추가 데이터 파일과 각각 처음 크기가 1MB인 두 개의 로그 파일을 만듭니다.




이 파일은 ALTER DATABASE tempdb REMOVE FILE 명령을 사용하여 제거될 수 있습니다. 자세한 내용은 SQL Server 2005용 SQL Server 온라인 설명서를 참조하십시오.


XML 데이터 형식으로의 추가 캐스트 제거

XML 형식의 입력 인수를 가진 inlinable 함수에서 호출자는 XML 데이터 형식으로 암시적으로 변환되는 텍스트 또는 이진 값을 제공할 수 있습니다. 호출 수신자의 본문에서 XML 인수의 각 사용은 입력 값을 XML 데이터 형식으로 캐스트합니다. 이 비용은 인수를 XML 데이터 형식 변수(XML 데이터 형식으로 한 번의 인수 값 변환 유발)로 복사함으로써 피할 수 있고 XML 변수는 함수 또는 저장 프로시저의 본문에서 여러 번 사용할 수 있습니다. 다음 예제는 이러한 특징을 예시합니다.


예제: 변환 제거

책의 제목 및 ISBN을 반환하는 아래 GetTitleAndIsbnOfBook() 함수를 살펴봅시다.




함수가 문자열 값으로 호출되면 각 value() 메서드 호출에 대해 XML 데이터 형식으로의 변환이 발생합니다. 함수는 XML 데이터 형식으로의 인수 변환이 한 번만 발생하도록 다음과 같이 다시 작성될 수 있습니다. 하지만 다중 명령문 테이블 반환 함수에 필요한 테이블 변수 @retTab으로 인해 추가 비용이 발생하는데, 이 비용은 XML 데이터의 크기가 큰 경우 XML 변수에 대한 충분한 횟수의 액세스로 상쇄될 수 있습니다.




단일 요소 지정

단일 카디널리티 평가는 쿼리 및 데이터 수정 문에서 서수를 지정할 필요성을 제거합니다. 이로 인해 쿼리 계획이 간소화되고 효율적인 JOIN 작업이 생성됩니다. 일반적으로 단일 카디널리티 평가에는 중첩 루프 조인에서 내부 및 외부 루프에 대한 적절한 선택이 수반됩니다.

형식화된 XML에서 기본적으로 요소는 minOccurs 및 maxOccurs의 값을 사용하여 재정의되지 않는다면 XML 스키마 구조의 단일 카디널리티를 갖습니다. 또한 형식화된 XML 열, 변수 및 매개 변수의 DOCUMENT 제약 조건은 XML 데이터 형식 인스턴스에서 정확히 하나의 최상위 요소를 보장합니다.

형식화되지 않은 데이터의 경우 또는 스키마에 여러 형제 요소가 허용되는 경우, 아래 예제에 나타난 대로 경로 식을 만족시키는 노드를 정확하게 하나만 선택하는 서수 값을 사용하여 노드의 단일 카디널리티가 경로 식에 표시될 수 있습니다. 서수 [1]은 Transact -SQL TOP 1 오름차순을 사용하여 평가되는 반면 서수 last()는 TOP 1 내림차순으로 평가됩니다. 또한 nodes() 메서드는 결과 XML 인스턴스 각각에 대해 단일 컨텍스트 항목을 설정합니다.

단일 노드의 선택이 생략된 경우 쿼리 최적화 프로그램이 지나치게 높을 수 있는 기본 카디널리티 평가를 사용합니다. 예를 들면, 이는 술어를 처리해야 하는 경우 중첩 루프 조인에서 내부 및 외부 루프에 대해 차선책을 선택하게끔 유발할 수 있습니다. 그 효과는 XML 인덱스가 존재하지 않고 보다 효율적인 카디널리티 평가를 위해 사용할 수 있는 통계 정보가 없는 XML blob의 경우에 더욱 크게 나타납니다.



예제: 형식화되지 않은 XML의 단일 카디널리티 지정

xCol 열의 각 XML 인스턴스가 <title> 하위 요소를 하나만 갖는 최상위 요소를 하나만 포함한다고 가정합시다. 다음 쿼리를 살펴봅시다.



쿼리 최적화 프로그램은 <title> 요소에 기본 카디널리티 평가를 사용합니다. 각 <book>은 <title>이 단일 요소가 되도록 하나의 제목을 갖지만 최적화 프로그램의 평가는 그에 비해 훨씬 더 높습니다. 다시 공식화한 다음 쿼리는



올바른 카디널리티를 최적화 프로그램에 전달합니다. 비슷한 모양의 경로 식 (/a/b)[1]과 /a/b [1] 간의 의미론적 차이점이 MSDN 기사 Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법에 설명되어 있습니다.


XML 데이터 형식 메서드의 다중 실행 제거

다음 쿼리는



책의 <price>를 계산한 다음 가격이 숫자 형식인 경우 가격을 십진수(5, 2)로 변환합니다. 이 논리는 응용 프로그램에서 숫자가 아닌 가격 값이 발생할 수 있는 경우에 유용합니다.



동일한 최적화가 NULLIF()와 같은 다른 곳에서도 사용될 수 있습니다.



NULLIF()에서 value() 메서드를 사용하면 이 메서드가 비어 있지 않은 문자열을 반환할 경우 value() 메서드가 두 번 처리됩니다.


Data(),text() 및 string() 접근자

XQuery는 노드에서 형식화된 원자 값을 추출하기 위한 fn:data() 함수, 텍스트 노드를 반환하기 위한 노드 테스트 text() 및 노드의 문자열 값을 반환하기 위한 fn:string() 함수를 제공합니다. 이들의 사용은 혼동될 수 있습니다. SQL Server 2005에서 이를 올바로 사용하기 위한 지침이 XML 인스턴스 <age>12</age>를 사용하여 아래에 예시되어 있습니다.


형식화되지 않은 XML: 경로 식 /age/text()는 값이 “12”인 <age> 아래에 텍스트 노드를 반환합니다. fn:data(/age) 함수는 fn:string(/age)처럼 문자열 값 “12”를 반환합니다.

형식화된 XML: /age/text() 식은 SQL Server 2005에서 모든 단순한 형식화된 <age> 요소에 대한 정적 오류를 반환합니다. <age>가 단순한 정수 콘텐츠를 갖는 경우에는 fn:data(/age)가 정수 12를 반환하는 반면, fn:string(/age[1])은 문자열 “12”를 산출합니다. 이들 함수는 서로 다른 성능 특성을 갖습니다. Fn:string()은 컨텍스트 노드 아래의 모든 텍스트 노드를 재귀적으로 집계합니다. 컨텍스트 노드가 단일값인 경우 이 방식은 과도하며, 이 경우에는 fn:data() 및 text()로도 충분할 뿐만 아니라 더 효과적입니다.

형식화되지 않은 XML의 경우 노드의 값이 필요할 때, text()를 사용하여 텍스트 노드를 반환하는 것이 fn:data()를 사용하여 반환하는 것보다 더 빠릅니다. 경로 식 /book/text()는 <book> 요소의 텍스트 노드 자식(child)을 반환합니다. query() 메서드 내에서 이러한 텍스트 노드는 직렬화되고 텍스트 노드 값의 연결로 나타납니다. 반면, fn:data()는 <book> 요소의 하위 트리에 있는 모든 값을 집계합니다. 이 집계는 간단한 콘텐츠를 가진 요소의 경우일지라도 fn:data()의 계산이 text()의 계산보다 비용이 더 많이 소요되게 만듭니다.


형식화되지 않은 XML에서 텍스트 집계

XQuery 의미론에 따라, 형식화되지 않은 XML에서 다음과 같은 두 쿼리는 술어를 평가하기 위해 <title> 요소 아래의 모든 텍스트 노드를 집계해야 합니다. 이 때문에 검색 문자열에 대한 XML 인덱스 조회가 억제됩니다.



또는



<title> 요소에 텍스트 노드가 하나만 있는 경우 더 효율적인 쿼리 작성 방법은 아래와 같이 텍스트 노드의 술어를 평가하는 방법입니다.



이 경우에는 "Writing Secure Code" 값에 대한 XML 인덱스 조회가 발생합니다.



XQuery 및 XML DML 식 매개 변수화

XQuery 및 XML DML 식은 자동으로 매개 변수화되지 않습니다. 따라서 두 XQuery 식이 매개 변수의 값만 다른 경우, 동적 SQL 문을 사용하는 대신 sql:column() 또는 sql:variable()을 사용하여 XQuery 또는 XML DML 식에 매개 변수 값을 제공하는 것이 더 좋습니다. 이들 함수를 사용하면 쿼리가 자동으로 매개 변수화됩니다.

아래 예제는 저장 프로시저 실행을 보여줍니다. 이 기법은 쿼리, 함수/메서드 호출 또는 데이터 수정 문의 매개 변수화에 적용할 수 있습니다.

예를 들어, 아래 저장 프로시저는 입력 인수보다 낮은 가격의 책을 찾습니다.



ADO.NET 및 OLEDB에서 @Price의 입력 값을 매개 변수에 바인딩합니다. 이렇게 하면 매개 변수가 서로 다른 값에 바인딩될 때 쿼리를 다시 컴파일할 필요가 없습니다. sql:column()을 사용하면 이와 비슷한 이점을 얻을 수 있습니다.

다음 Visual Basic.NET 코드는 저장 프로시저 호출에서 매개 변수 바인딩을 보여줍니다.



자세한 내용은 Microsoft Visual Studio.NET 설명서 (영문)를 참조하십시오.


예제: 데이터 수정에서 sql:variable() 사용

ISBN이 "0-2016-3361-2"인 <book>의 <price>가 10% 할인되었다고 가정합시다. 할인과 ISBN 둘 다 XML 데이터 수정 문에 매개 변수로 전달될 수 있고 이 문은 다른 책 또는 다른 할인에 대해 똑같이 유지됩니다.




예제 : 요소 구성에서 sql:variable() 사용

아래에 나와 있는 modify() 메서드는 구성된 요소 내에서 값을 제공하기 위한 sql:variable()의 사용을 보여줍니다.



술어 및 서수의 최적화

노드 테스트 또는 분기가 없는(즉, 경로의 중간 노드에 술어 또는 서수가 없는) 전체 경로(즉, 루트 노드로부터 자식(child) 및 자신의 축만을 포함하는 선택한 노드에 이르는 절대 위치 경로)는 분기가 있는 경로 식보다 효율적으로 평가할 수 있습니다. 인덱스된 경우에 전체 경로는 인덱스 탐색에 사용될 수 있습니다. XML blob의 경우, 이러한 경로의 구문 분석은 분기 또는 와일드카드(*)가 있는 경로의 구문 분석보다 더 빠릅니다.

경로 끝부분의 노드 테스트 및 술어는 선택한 노드에서 필터로 사용됩니다. 인덱스가 사용됩니다. XML blob의 경우 구문 분석이 효율적입니다. 아래에 예제가 나와 있습니다.


예제: 전체 경로 평가

이름이 Davis인 저자가 쓴 책을 선택하는 경로 식을 생각해 봅시다.



술어가 <book> 요소에 직접 존재하지 않더라도 축소 경로 /book/author/first-name을 사용하여 위치한 <first-name> 노드는 값 "Davis"에 의해 필터링됩니다. 반환된 <book> 요소는 주어진 술어를 충족하는 것들입니다.

경로 기반 조회는 /book//first-name과 같이 술어 또는 서수가 없는 부분적으로 지정된 경로에도 효율적입니다. 쿼리 컴파일러는 XML 인덱스에서 이러한 경로를 일치시키기 위해 LIKE 연산자를 사용합니다. 그러므로 가능한 한 경로의 많은 부분을 지정하는 것이 보다 효율적인 처리에 도움이 됩니다.

/book[@ISBN = "1-8610-0157-6"]/author/first-name에서와 같이 분기(즉, 경로 식의 중간에 있는 노드 테스트 및 서술어)는 경로 식 /book[@ISBN = "1-8610-0157-6"] 및 /book/author/first-name을 평가하고 <book> 요소의 두 집합 사이의 교집합을 취합니다. 따라서 분기 없는 경로 식보다 실행이 느려집니다. 경로 식의 중간에 노드 테스트 및 술어를 사용하는 것을 가능한 한 피하는 것이 효과적입니다. 이는 “일반적 태그와 구체적 태그의 비교” 예제에 설명된 대로, 데이터 모델링 시 신중한 주의를 기울임으로써 가능한 경우가 종종 있습니다.


경로의 끝으로 서수 이동

정적 형식의 정확성을 위해 경로 식에 사용되는 서수는 경로 식의 끝부분에 넣을 수 있는 좋은 후보입니다. 경로 식 book[1]/title[1]은 (/book/title)[1]과 동일합니다. 후자는 문서 순서에서 <book> 요소 아래의 첫 번째 <title> 요소를 확인함으로써 XML 인덱스 및 XML blob 두 경우 모두에 대해 모두 더 빠르게 평가될 수 있습니다. 이와 유사하게 경로 식 (/book/@ISBN)[1]은 /book[1]/@ISBN보다 더 빠른 실행을 가져옵니다.


컨텍스트 노드를 사용한 술어 평가

술어, 서수 및 노드 테스트를 경로 식의 끝으로 이동하는 것 외에도 컨텍스트 노드를 사용하여 이러한 조건을 평가하면 한층 더 나은 성능을 얻을 수 있습니다. 아래에 이에 대한 쿼리 재작성 예제가 나와 있습니다.


예제: 컨텍스트 노드를 사용한 술어 평가

아래 쿼리는 “security”라는 제목의 책을 검색합니다. 이 쿼리에는 두 경로 식, /book 및 /book/@subject의 평가와 후자 경로에 대한 “security” 값 확인이 필요합니다.



다시 작성된 아래 쿼리는 단일 경로 /book/@subject를 평가하고 이 경로에 "security" 값이 있는지 확인합니다. 이렇게 하면 위 쿼리보다 쿼리 계획이 더 단순해지고 실행이 훨씬 더 빨라집니다.



범위 조건

범위 조건은 형식화된 XML의 사용을 통해 이점을 얻습니다. XML 열 및 XML 인덱스에 저장된 데이터는 XML 스키마에 지정된 형식 정의에 따라 형식화됩니다. 값 비교는 데이터의 런타임 변환을 피하고 VALUE 보조 XML 인덱스에 대한 범위 스캔을 허용합니다. 또한 이를 위해서는 다음 예제에 나타난 대로, 효율적인 액세스를 위해 범위 조건에 컨텍스트 노드(.)를 지정해야 합니다.


예제: 범위 조건의 컨텍스트 노드

$9.99와 $49.99 범위에 있는 가격대의 책을 찾는 쿼리를 고려해 봅시다.



경로 식 /book/price > 9.99 및 /book/price < 49.99가 각각 따로 평가됩니다. <book> 요소 아래에 여러 <price> 요소가 존재할 수 있기 때문에 쿼리 최적화 프로그램은 <price> 요소가 동일하다는 사실을 알지 못합니다. 이 때문에 VALUE 보조 XML 인덱스에 대한 범위 스캔이 억제됩니다. 아래에 다시 작성된 쿼리는 <price>에 동일한 컨텍스트 노드를 사용하고 9.99와 49.99 사이의 값에 대해 VALUE 보조 XML 인덱스의 범위 스캔이 발생하도록 보장합니다. 이로 인해 성능이 더 좋아집니다.




동적 쿼리

XQuery 식은 XML 데이터 형식 메서드 내에서 리터럴로 지정됩니다. 이들의 평가는 사용 가능한 경우 쿼리 최적화 프로그램에서 선택한 XML 인덱스를 사용합니다.

XQuery 식을 리터럴 대신 동적으로 지정할 수 있으면 응용 프로그램 개발이 편리합니다. 이는 다음 방식으로 가능합니다.

쿼리 구성
쿼리를 문자열로 작성하고 sp_executesql을 사용하여 실행합니다. EXEC와 달리, 이렇게 하면 컴파일된 쿼리 계획이 캐시되어 최적화 프로그램이 컴파일된 계획을 다시 사용할 수 있습니다. 쿼리는 문자열로 구성되므로 매개 변수화될 수 있고 포함된 매개 변수를 포함할 수 있습니다. SQL 주입 공격을 피하려면 충분한 주의를 기울여야 합니다.

XPath 함수 사용
XPath 식의 각 위치 단계를 name() 함수 또는 local-name() 및 namespace-URI() 함수로 대체합니다. 이렇게 하면 노드 이름 및 검색 값으로 전달할 수 있는 쿼리가 만들어집니다. "XQuery 또는 XML DML 식 매개 변수화" 예제에 설명된 대로 추가적으로 매개 변수화할 수 있습니다. 이와 같은 매개 변수화된 쿼리는 응용 프로그램 개발에 편리합니다. 하지만 컴파일 시에 구체적인 경로가 알려지지 않으므로, 이에 대해 생성된 쿼리 계획은 XML 인덱스를 무시합니다.

쿼리 구성 접근 방법은 경로 식 매개 변수화보다 더 능률적으로 작동하지만 런타임 쿼리 컴파일 비용이 들기 때문에, 전체 쿼리를 리터럴로 지정하는 것보다 더 느려집니다. 사용자가 전달한 실제 쿼리는 SQL 주입 공격을 피하기 위해 유효성이 검사되어야 합니다. 그렇지 않으면, 쿼리의 매개 변수화(이 문서의 “XQuery 및 XML DML 식 매개 변수화")를 위해 이 접근 방법을 사용하지 말아야 합니다. 다음 예제는 이 접근 방법을 예시합니다.

노드 이름을 사용하여 노드 테스트를 지정하는 두 번째 접근 방법은 SQL 주입 문제를 방지합니다. 하지만 쿼리 계획이 복잡해지고 원래 쿼리보다 훨씬 더 비능률적으로 수행됩니다. 이 접근 방법은 두 번째 예제에 나와 있습니다.


예제: sp_executesql를 사용한 쿼리

다음 쿼리를 동적으로 작성하여 매개 변수를 사용하여 @subject의 검색 값을 전달하기를 원한다고 가정합시다.




동적 쿼리를 아래에 나타난 대로 작성하고 실행할 수 있습니다. 쿼리 문자열은 @SQLString 변수에 만들어지고 exist() 메서드에서 사용된 포함된 변수 @bksubj를 포함합니다. @subj 변수는 매개 변수의 런타임 값을 제공합니다. @SQLString을 사용하여 전달된 동적 쿼리는 SQL 주입 공격을 피하기 위해 유효성이 검사되어야 합니다(아래에는 표시되어 있지 않습니다).



예제: local-name()을 사용한 쿼리

위 쿼리를 다음과 같이 태그 이름을 리터럴로 사용하도록 다시 작성할 수 있습니다.



다시 작성된 쿼리는 와일드카드(*)와 노드 이름을 사용하는 노드 테스트를 포함하므로 효과적으로 최적화하기가 어렵습니다. 결과적으로 원래 쿼리 및 쿼리 구성 접근 방법에 비해 훨씬 더 비능률적으로 수행됩니다.


XML 데이터에서 행 집합 생성

일부 응용 프로그램은 하나 이상의 속성을 행 집합의 열로 승격함으로써 XML 데이터에서 행 집합을 생성해야 합니다. 예를 들어, 응용 프로그램은 책의 저자를 쿼리하고 성 및 이름에 대해 두 개의 열을 포함하는 테이블로 결과를 표시할 수 있습니다. 이러한 행 집합 생성은 서로 다른 성능 특성을 지닌 서버 또는 클라이언트에서 모두 수행될 수 있습니다.


서버에서 다음 메커니즘 중 하나를 사용하십시오.
XML 데이터 형식의 nodes() 및 value() 메서드의 결합
OpenXML
CLR(공용 언어 런타임)에서 테이블 반환 함수 스트리밍
또한 XML 결과가, 클라이언트 쪽 프로그래밍(예: DataSet)을 사용하여 데이터를 행 집합으로 변환하는 클라이언트에게 반환됩니다. 클라이언트 쪽 행 집합 생성은 서버의 부하를 덜어주므로 서버에서 클라이언트로 전송된 거의 전체 데이터가 행 집합으로 매핑되는 경우에 유용합니다. 그렇지 않은 경우에는 데이터 제공 비용이 클라이언트 쪽 처리 이점보다 더 클 수 있습니다.

서버 쪽 행 집합 생성은 서버에서 들어오는 XML 데이터로부터의 행 집합 생성에 유용합니다. 이 방식은 서버에 저장된 XML 데이터의 일부분만이 행 집합의 열로 승격되는 경우에 일반적으로 더 바람직합니다. 서버 쪽 접근 방법들의 상대적 장점 및 단점에 관한 자세한 설명은 MSDN 기사 Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법에서 찾을 수 있습니다.



제공 : DB포탈사이트 DBguide.net
출처명 : 한국 마이크로소프트

"MSSQL" 카테고리의 다른 글
  • The Value of Merge-Join and Hash-Join in SQL Se... (0)2007/06/22
  • Microsoft SQL Server 2000 Distributed Queries:... (0)2007/06/22
  • SQL Server 2005에서 XML 데이터 형식을 위한 성능... (0)2007/05/25
  • Microsoft SQL Server 2005의 XML 옵션 (0)2007/05/25
  • SQL 서버에서「데이터 코드 에러」처리하기 (0)2007/05/25
2007/05/25 15:51 2007/05/25 15:51
Posted by webdizen
Tags SQL Server 2005, XML, XML 인덱스, 데이터 모델링, 최적화
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3038

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/25 15:33

Microsoft SQL Server 2005의 XML 옵션

적용 대상:
Microsoft SQL Server 2005
Microsoft Visual Studio 2005
Microsoft .NET Framework 2.0
XML 및 관계형 데이터

요약: Visual Studio 2005/SQL Server 2005 환경에서 XML 데이터 처리를 위한 세 가지 옵션을 설명하고 이 옵션들 중에서 선택하는 데 도움을 주는 사용 시나리오 및 지침을 제공합니다.



System.Xml, SQLXML 및 XML 데이터 형식 소개


섹션에서는 Microsoft SQL Server 2000에 제공된 XML 지원에 관한 간략한 배경 설명과 함께 XML 및 관계형 데이터 조작을 위해 Microsoft Visual Studio 2005/SQL Server 2005 환경에 제공된 세 가지 옵션의 개요를 제공합니다. 이 세 옵션은 1) System.Xml 이름 공간의 클래스, 2) SQLXML 클래스, 3) SQL Server 2005에 제공된 XML 데이터 형식입니다.

사용자에게 다음과 같은 기능을 제공하기 위해 XML 지원이 Microsoft SQL Server 2000에 추가되었습니다.



관계형 데이터를 XML로 노출

XML 문서를 행 집합으로 분할(Shredding)

XDR(XML-Data Reduced) 스키마를 사용하여 XML 스키마를 데이터베이스 스키마에 매핑하여 XML 뷰 생성

XPath를 사용하여 XML 뷰에서 쿼리 작성

HTTP를 통해 SQL Server에 데이터 노출

이 지원은 이후의 SQLXML 웹 릴리스에서 더욱 향상되었습니다. 향상 기능은 다음과 같습니다.


XML 뷰에 적용된 변경 내용을 유지하기 위한 Updategrams 및 XML Bulkload

매핑을 설명하기 위한 주석 달린 XML 스키마 정의 언어(XSD) 지원(여전히 XDR을 지원하지만 사용이 권장되지 않습니다.)

클라이언트 쪽 FOR XML

SQLXML 관리 클래스

웹 서비스 지원

Microsoft .NET Framework 1.0은 XML 문서 읽기, 쓰기 및 처리를 위한 포괄적인 지원을 제공합니다. 이 지원은 다양한 XML 클래스의 성능 및 유용성을 개선하기 위해 .NET Framework 2.0에서 보다 더 강화되었습니다. .NET Framework에서 제공하는 System.Xml 이름 공간의 새 클래스는 XML 데이터를 관계형 데이터에 매핑하는 데 사용될 수 있습니다.

SQLXML은 SQL Server 데이터베이스에 있는 관계형 데이터와 XML의 원활한 통합을 가능하게 하는 일련의 라이브러리 및 기술입니다. SQLXML은 중간 계층 구성 요소이며 FOR XML 및 OPENXML에서 제공하는 서버 쪽 XML 지원을 포함하지 않습니다. SQLXML은 관계형 원본 데이터에서 XML을 생성하고 다시 관계형 테이블에 관계형 정보를 나타내는 XML을 로드하기 위한 스키마 중심의 매핑 방법을 제공합니다. SQLXML 클래스는 XML 지원을 SQL Server 2000 데이터베이스 이상 버전에 제공합니다.

Microsoft SQL Server 2005에는 XML 데이터 형식의 형태로 된 XML에 대한 기본 제공 지원이 추가되었습니다. XML 데이터는 XML 데이터 형식 열에 원시적으로 저장될 수 있습니다. 그 뿐만 아니라 XML 데이터 형식 열은 XML 스키마 모음을 이 열에 연결함으로써 한층 더 제약될 수 있습니다. XML 데이터 형식 열에 저장된 XML 값은 XQuery 및 XML DML(Data Modification Language)을 통해 조작될 수 있습니다. 쿼리 성능 향상을 위해 인덱스를 XML 데이터를 기반으로 구축할 수 있습니다. 또한 FOR XML 및 OPENXML이 새로운 XML 데이터 형식을 지원하도록 향상되었습니다.

이전의 다양한 SQL Server 버전에 제공된 XML 기능과 더불어 XML 데이터를 저장 및 처리하기 위해 SQL Server 2005에 새롭게 도입된 기능은 XML 데이터를 XML 응용 프로그램에 저장하고 처리할 수 있는 여러 방법을 개발자에게 제공합니다. SQL Server 2005에서 제공하는 대체 접근 방법을 사용하여 XML 응용 프로그램을 구축할 수 있는 방법에는 여러 가지가 있으므로 올바른 선택을 할 수 있도록 다양한 기술 시나리오, 트레이드 오프 및 시너지 효과를 이해하는 것이 중요합니다. 이 문서는 SQL Server 2005에서의 XML 응용 프로그램을 개발을 위해 적합한 대안을 선택하는 데 도움이 되는 지침을 제공합니다.



XML 사용 시나리오



XML이 사용되는 영역은 크게 다음과 같이 분류될 수 있습니다.



비즈니스 통합을 위한 XML: 엔터프라이즈 응용 프로그램 통합(EAI)으로도 알려진 비즈니스 통합은 A2A(application-to-application), B2B(business-to-business) 및 B2C(business-to-consumer) 응용 프로그램을 포함합니다. 서로 다른 시스템에서 작동하는 응용 프로그램은 XML 기반 메시지를 사용하여 서로 통신합니다.
콘텐츠 관리를 위한 XML: XML에 기반한 콘텐츠 관리 시스템을 사용하여 사용자가 XML 문서를 저장, 검색, 수정 및 쿼리할 수 있습니다. 이 시스템은 XML 문서를 원시 형식으로 저장합니다.

이제 위에서 언급한 범주에 속하는 몇 가지 시나리오를 설명하겠습니다. SQL Server 2005/Visual Studio 2005 환경에서 사용할 수 있는 여러 XML 옵션 처리에 대한 자세한 설명과 함께 이 시나리오에 대한 솔루션이 다음에 이어지는 섹션에 제공되어 있습니다.



시나리오 1: 보험금 청구

인터넷 상에서 서비스를 제공하는 한 자동차 보험 회사는 보험 구매자 또는 대리인이 회사의 웹 사이트를 통해 보험금 청구를 신청할 수 있도록 합니다. 이러한 청구는 본사에 있는 중앙 집중식 시스템에서 처리됩니다. 처리가 완료되면 이 시스템은 청구에 관련된 특정 정보를 특정 XML 형식으로 저장해야 합니다. 법적인 목적으로 이러한 XML 문서의 정확한 복사본이 이 시스템에서 유지 관리되어야 합니다. 이 시나리오는 콘텐츠 관리를 위한 XML 사용을 보여줍니다.



시나리오 2: 자동차 제조업체 및 부품 공급업체 사이의 데이터 교환 I

자동차 제조업체는 회사에 필요한 부품을 조달하기 위해 여러 부품 공급업체와 상호 작용합니다. 현재 이 제조업체는 공급업체들로부터 송장을 받습니다. 그러고 나면 이 송장에 해당하는 데이터가 기존의 송장 처리 시스템에 수동으로 전달됩니다. 송장 처리 시스템은 데이터를 관계형 형식으로 저장합니다. 이제 제조업체는 기존 송장 처리 시스템으로의 송장 데이터 전달 절차를 자동화하기를 원합니다. 이 시나리오는 비즈니스 통합을 위한 XML 사용의 예입니다.



시나리오 3: 자동차 제조업체와 부품 공급업체 사이의 데이터 교환 II

이 시나리오에는 이전 시나리오에서 언급한 대로 여러 부품 공급업체와 상호 작용하는 자동차 제조업체가 관련됩니다. 제조업체의 현 시스템은 공급업체가 송장의 현황을 확인하거나 제조업체의 지불 지침 복사본을 얻기 위한 기능을 제공하지 않습니다. 현재로서는 단지 전화를 통해서만 이 정보를 공급업체가 이용할 수 있습니다. 공급업체가 이 작업을 자동으로 수행할 수 있도록 자동차 제조업체는 이 정보를 웹 상에 노출할 수 있어야 합니다. 이 시나리오는 비즈니스 통합을 위한 XML의 사용을 보여줍니다.



시나리오 4: 콘텐츠 관리 시스템

의료, 법 및 기술 분야의 정보를 웹, 책, CD-ROM 등의 다양한 채널을 통해 고객들에게 제공하는 한 회사는 고객들에게 더 빠른 시간 내에 고품질의 콘텐츠를 전달할 수 있는 콘텐츠 관리 시스템을 구축하기를 원합니다. 이 시나리오는 콘텐츠 관리를 위한 XML의 사용을 예시합니다.



시나리오 5: 고객 설문조사

인터넷에서 항공권 예약 서비스를 제공하는 한 회사는 현 시즌에 고객들에게 가장 인기 있는 여행 목적지를 확인하기 위해 각 계절마다 설문조사를 실시합니다. 각 계절에 사용되는 질문은 서로 다르며 이 질문은 나중에 변경될 수 있습니다. 회사는 정보를 분석하고 분석 결과는 최대 고객 수의 요구를 충족할 수 있는 패키지 여행 정책을 설계하는 데 사용됩니다. 이 시나리오는 콘텐츠 관리를 위한 XML의 사용으로 분류될 수 있습니다.



.NET Framework의 XML 클래스

Microsoft .NET Framework에는 XML 기반 제품 개발을 위한 탁월한 지원 기능이 있습니다. .NET Framework에서 XmlTextReader, XmlTextWriter, XmlDocument, XmlValidatingReader 등과 같은 핵심 클래스는 모든 XML 클래스의 루트 이름 공간인 System.Xml 이름 공간에서 사용할 수 있습니다. 이들 핵심 클래스는 사용자가 스트림 기반 및 DOM 기반(문서 개체 모델 기반) 탐색/액세스 모델을 모두 사용하여 XML 문서를 읽고 쓰고 확인할 수 있게 해줍니다. System.Xml 이름 공간은 다음과 같은 하위 이름 공간을 포함합니다.



System.Xml.Schema - XML 스키마 정의 언어(XSD) 스키마를 다루는 클래스를 포함합니다.
System.Xml.Serialization - XML 형식 문서 또는 스트림으로의 개체 직렬화를 위한 클래스를 제공합니다.
System.Xml.XPath - Xpath 식을 사용하여 XML 문서를 탐색하기 위한 클래스를 포함합니다.
System.Xml.Xsl - XSLT(Extensible Stylesheet Transformations) 수행을 위한 클래스를 포함합니다.



System.Xml 이름 공간의 향상 기능

Visual Studio 2005에서 XsltCommand와 같은 새로운 클래스와 XmlDocument와 같은 기존 XML 클래스의 기능 향상은 XML 문서 수정, XSL 변환 적용 등을 포함하여 XML 데이터에 대해 다양한 작업을 수행하는 데 사용될 수 있습니다.

System.Xml 이름 공간의 XML 클래스와 관련된 Visual Studio 2005의 몇 가지 향상된 기능은 다음과 같습니다.



XML 스키마 유효성 검사 지원이 XmlDocument 클래스에 추가되었습니다.
XmlReader 및 XmlWriter 클래스는 상당한 성능 개선을 제공하고 XML 스키마 형식을 지원하기 위해 향상되었습니다. 또한 생성된 형식을 구성하는 XmlReaderSettings 및 XmlWriterSettings 클래스를 사용하여 XmlReader 및 XmlWriter의 인스턴스를 만들기 위한 보다 쉬운 방법을 제공하기 위해 정적 Create 메서드가 추가되었습니다.

System.Xml의 기능 향상에 대한 자세한 내용은 Visual Studio 2005 및 .NET Framework 2.0 릴리스를 위한 System.Xml의 새로운 기능 (영문) 백서를 참조하십시오.

System.Xml 이름 공간의 클래스는 사용자 지정 XML 구문 분석, 조작 및 저장 논리를 구현하는 데 사용될 수 있습니다. SQL Server 2005의 공용 언어 런타임(CLR) 호스팅 기능을 활용하고 Visual Studio 2005의 XML 클래스를 사용하여 XML 처리를 중간 계층 또는 데이터베이스 계층에서 수행할 수 있습니다.

.NET Framework XML 클래스의 사용에는 XML 문서를 데이터베이스에 [n]varchar(max) 또는 varbinary(max) 형식의 열로 또는 파일 시스템에 파일로 저장하고, System.Xml 이름 공간의 클래스를 사용하여 중간 계층 또는 데이터베이스에서 이러한 문서를 처리하는 작업이 포함됩니다. .NET Framework의 XML 클래스는 또한 XML 데이터 형식으로 저장된 데이터에 작업하는 데 사용될 수 있습니다.

.NET Framework XML 클래스는 다음의 경우에 적합합니다.


스트리밍 파서, 문서 형식 정의(DTD) 및 XSD 유효성 검사, XSLT 처리 등과 같은 모든 .NET Framework XML 기능에 액세스할 수 있기를 원합니다.
단순히 XML 문서의 데이터 저장소로서 SQL Server를 사용하기를 원하며 데이터베이스 내부에 세분화된 액세스는 필요하지 않습니다.
.NET Framework XML 클래스를 사용하여 XML 문서의 대부분이나 전부를 처리하며 문서 수준에서 업데이트를 수행합니다.

XML을 저장하는 데 [n]varchar(max), varbinary(max) 또는 XML 데이터 형식을 사용할 수 있습니다.

[n]varchar(max) 또는 varbinary(max)를 사용할 경우 다음과 같은 이점을 얻을 수 있습니다.


공백 및 서식 지정을 포함하여 문서의 정확한 복사본으로 XML 문서의 원문 충실도를 유지합니다.
응용 프로그램은 문서 전체에 대한 삽입 및 검색 작업을 위해 가능한 가장 빠른 성능을 얻습니다.

XML 데이터 형식 사용의 이점은 후반부의 섹션에 설명되어 있습니다.



중간 계층에서 XML 처리 수행

XML 처리는 .NET Framework에서 제공하는 다양한 XML 클래스를 사용하여 중간 계층에서 수행될 수 있습니다. 앞서 언급한 대로, 이 접근 방법을 채택하면 XML 문서는 데이터베이스에 [n]varchar(max) 형식 또는 XML 형식의 열로 저장되거나 파일 시스템에 파일로 저장될 수 있습니다. 중간 계층에서는 이러한 문서를 데이터베이스에서 가져와서 다음과 같이 사용자의 요구 사항에 따라 처리할 수 있습니다.



XML 문서를 읽어야 하는 경우 XmlReader.Create() 메서드를 통해 생성된 XmlReader를 사용하여 데이터베이스에서 얻은 문서를 로드합니다. Read()를 사용하여 문서를 탐색합니다. XmlReader 클래스는 XML 문서에 대해 가장 빠른 읽기 전용, 전진 전용의 캐시되지 않은 액세스를 제공합니다.
XML 문서에 대한 쓰기 액세스 권한이 필요하고 XML 데이터에 대한 완전한 탐색 액세스 권한이 요구되는 경우, XmlDocument 클래스를 사용하여 XML 문서를 로드하고 액세스합니다. XmlDocument는 .NET Framework에서 문서 개체 모델(DOM)의 구현으로서 이는 XML 문서의 탐색 및 편집을 가능하게 하는 XML 문서의 인-메모리 트리 표시입니다.
DTD/XSD에 기반하여 XML 문서의 유효성을 검사하거나 런타임에 XSD 정보를 얻어야 하는 경우 XmlReader 클래스를 사용합니다. XmlReaderSettings 클래스에서 true로 설정된 XsdValidation 또는 DTDValidation 중 하나를 이용하여 메서드를 만듭니다. 또한 ValidationEventHandle() 이벤트 처리기는 읽는 동안 발생한 유효성 검사 오류를 처리하도록 설정할 수 있습니다.
XSL 변환을 XML 문서에 적용해야 하는 경우 XslCommand 클래스를 사용하여 XML 문서를 로드하고 변환을 적용하기 위해 XPathDocument 클래스를 사용합니다. XPathDocument 클래스는 XSLT를 사용하여 XML 문서 처리를 위한 빠른 고성능 캐시를 제공합니다.
XPath 식을 사용하여 XML 문서를 쿼리해야 하는 경우 XPathDocument(읽기 전용) 또는 XmlDocument(읽기/쓰기)를 사용하여 XML 문서를 로드합니다. CreateNavigator() 메서드를 사용하여 XPathNavigator의 인스턴스를 만들고 인수로 필요한 Xpath 식을 XPathNavigator의 Select() 메서드에 전달합니다.



데이터베이스에서 XML 처리 수행

SQL Server 2005와 CLR의 통합으로 인해 개발자들은 .NET Framework에서 제공하는 XML 클래스를 사용하여 데이터베이스 계층에서도 처리를 수행할 수 있습니다. 이 통합은 .NET Framework에서 지원하는 모든 언어에서 저장 프로시저 작성, 함수, 트리거 및 사용자 정의 형식의 기능을 제공합니다. 또한 CLR 호스팅은 완전한 .NET Framework 기반 클래스 라이브러리에 대한 액세스 권한도 제공합니다. 결과적으로 앞 섹션에서 설명한 여러 XML 처리 옵션은 데이터베이스에서도 수행될 수 있습니다.

CLR 통합 사용의 이점은 다음과 같습니다.



관리되는 코드에서 데이터베이스 개체를 만들기 위해 C# 및 Visual Basic .NET과 같은 개체 지향 언어를 사용할 수 있는 기능을 제공합니다.
관리되는 데이터베이스 개체는 이전 SQL Server 버전에서 사용할 수 있는 확장 저장 프로시저보다 안전합니다.
사용자 정의 데이터 형식 및 사용자 정의 집계를 정의할 수 있는 기능을 제공합니다.
특정 조건에서, 컴파일된 관리 데이터베이스 개체가 Transact-SQL에 대해 향상된 성능을 제공합니다.

SQL Server 2005에서 데이터베이스 개발자는 저장 프로시저, 트리거 및 사용자 정의 함수를 위한 두 가지 옵션을 가질 수 있습니다. 이 옵션은 Transact-SQL 및 .NET Framework에서 사용할 수 있는 모든 언어(C# 또는 Visual Basic .NET)입니다. 언어의 선택은 데이터에 수행하는 작업의 종류에 따라 달라집니다. Transact-SQL은 코드가 절차적 논리를 거의 또는 전혀 사용하지 않고서 데이터 액세스를 대부분 수행하는 경우에 가장 적합합니다. 관리되는 클래스는 문자열 처리, 날짜 작업, 시스템 리소스 액세스, 파일 액세스 또는 이미지 처리와 같이 계산 집중적인 함수 및 절차에 가장 적합합니다.

데이터베이스 계층에서 .NET Framework의 XML 클래스 사용에 따르는 단계는 다음과 같습니다.


관리되는 어셈블리 개발. .NET Framework에서 사용할 수 있는 모든 언어를 사용하여 처리 기능을 어셈블리로 구현하고 이 어셈블리를 DLL로 패키지로 만듭니다. 또한 어셈블리는 다른 어셈블리를 참조할 수 있습니다.
어셈블리 등록 및 사용 권한 부여. .NET Framework를 사용하여 개발한 어셈블리는 CREATE ASSEMBLY T-SQL 문을 사용하여 SQL Server에 등록될 수 있습니다. 또한 어셈블리를 등록하는 동안 어셈블리에 허용되는 코드 액세스 권한을 지정할 수 있습니다. 어셈블리는 DROP ASSEMBLY T-SQL 문을 사용하여 등록 취소할 수 있습니다.
T-SQL에 관리되는 형식 노출. 어셈블리에서 제공한 처리 기능은 스칼라 반환 사용자 정의 함수, 테이블 반환 사용자 정의 함수, 사용자 정의 절차(UDP) 또는 사용자 정의 트리거를 통해 T-SQL에 노출될 수 있습니다. 스칼라 사용자 정의 함수는 모든 스칼라 식에서 사용될 수 있습니다. 테이블 반환 사용자 정의 함수는 모든 FROM 절에서 사용될 수 있습니다. UDP는 EXEC 문에서 호출될 수 있습니다.



시나리오 분석

보험금 청구는 청구 ID, 정책 번호, 청구 중재 데이터 등과 같은 데이터 중심 정보와 사고 손해에 대한 설명과 같은 문서 중심 정보를 포함합니다. XML 문서는 데이터 중심 및 문서 중심 정보 집계에 있어 탁월합니다. 제공된 시나리오 (시나리오 1: 보험금 청구 섹션 참조)에서의 주요 요구 사항은 보험금 청구의 정확한 복사본을 XML 형식으로 유지 관리해야 한다는 점입니다. SQL Server에서는 보험금 청구를 [n]varchar(max) 또는 varbinary(max) 형식의 열로 데이터베이스에 저장하여 이 요구 사항을 쉽게 충족할 수 있습니다. 중요하지 않은 공백, 특성 순서, 이름 공간 접두사 및 XML 선언 등과 같은 정보를 보존해야 하는 경우에는 문서를 저장하는 데 XML 데이터 형식을 사용하지 않아야 한다는 점에 주의해야 합니다.



이점

저장소 매체로서 [n]varchar(max) 또는 varbinary(max)를 사용하고 XML 문서의 조작을 위해 System.Xml 이름 공간의 클래스를 사용하는 경우의 이점은 다음과 같습니다.



XML 문서의 스키마를 변경해야 하는 경우에 유연합니다. 또한 서로 다른 스키마를 사용하는 XML 문서를 동일한 열에 저장하려는 경우에도 유용합니다.
XML을 저장하는 데 [n]varchar(max) 또는 varbinary(max)를 사용하는 경우 XML 문서에 대한 원문 충실도를 제공합니다. 이는 보험금 청구와 같은 법적 문서를 다루는 응용 프로그램의 요구 사항이 될 수 있습니다.
XML 인스턴스를 파일 시스템에 파일로 저장할 때와 비교하여 트랜잭션 업데이트, 동시 액세스, 백업, 복제 등과 같은 데이터베이스 기능을 활용할 수 있습니다.
이 접근 방법은 데이터베이스에서 제공하는 XML 지원에 의존하지 않으므로 응용 프로그램이 SQL Server, Oracle 등과 같은 여러 데이터베이스 서버를 지원하도록 쉽게 확장될 수 있습니다.
클라이언트 시스템의 처리 능력을 사용할 수 있어 서버에서 로드가 감소합니다. CPU를 많이 사용하는 XML 처리를 중간 계층에서 수행함으로써 서버가 로드의 일부를 덜고 다른 중요한 작업에 사용될 수 있습니다.
문서 수준 삽입 및 검색 작업에 최상의 성능을 제공합니다.
XSL 변환과 같은 복잡한 작업을 데이터베이스에서 저장 프로시저, 트리거 또는 함수로 수행할 수 있습니다.



제한

저장을 위해 [n]varchar(max) 또는 varbinary(max) 사용 시 및 XML 인스턴스 처리를 위해 System.Xml 이름 공간의 클래스 사용 시 제한 사항은 다음과 같이 요약될 수 있습니다.



XML 데이터 형식 (SQL Server 2005의 XML 데이터 형식 섹션 참조) 또는 SQLXML 옵션(SQLXML 섹션 참조)과 비교하여 코딩이 더 복잡합니다. 데이터베이스 논리가 단순하다 하더라도 중간 계층 또는 데이터베이스 계층에서 XML의 구문 분석 및 처리를 다루는 코드의 구현이 복잡해집니다.
이 솔루션을 구현하는 데 필요한 코드의 양이 많습니다. 결과적으로 SQLXML 옵션과 비교하여 유지 관리 비용 또한 높습니다.
XML 문서가 데이터베이스에 [n]varchar(max)로 저장된 이후에는 XML 문서에서 세분화된 업데이트, 삽입 또는 삭제가 불가능합니다. 이 경우에는 쿼리 기능이 제한적입니다.
[n]varchar (max) 데이터 형식에 저장될 수 있는 XML 문서의 크기는 2GB로 제한됩니다.
이런 식으로 저장된 문서의 열을 XML 콘텐츠를 기준으로 검색하는 것은 비용이 매우 많이 소요됩니다.



.NET Framework에서 XML 클래스 사용의 예

이 문서의 앞부분에서 설명한 보험금 청구 시나리오를 생각해 봅시다(시나리오 1: 보험금 청구 섹션 참조). 보험 회사는 청구가 승인되면 법적인 목적으로 청구 정보를 저장하기를 원합니다. 청구 정보는 데이터베이스에 [n]varchar(max) 데이터 형식으로 저장될 수 있습니다.

응용 프로그램의 흐름은 다음과 같습니다.

1. 청구 처리 후 응용 프로그램은 청구를 승인하거나 거부합니다. 2. System.Xml 이름 공간의 클래스를 사용하여 청구용 XML 문서가 생성됩니다. 3. 생성한 XML 문서는 저장 프로시저로 전달됩니다. 4. 저장 프로시저는 XML 문서를 테이블에 삽입합니다. 다음 코드 예제는 시스템에서 사용할 수 있는 청구 정보를 사용하여 XML 문서를 생성하고 XML 문서를 데이터베이스에 삽입합니다.






다음은 데이터베이스 테이블을 만드는 스크립트입니다.






다음 저장 프로시저는 XML 문서를 데이터베이스에 삽입하는 데 사용됩니다.






SQLXML



SQL Server 2000에 도입된 SQLXML은 클라이언트 쪽의 XML 처리와 관련된 기능의 전 범위를 포괄합니다. SQLXML은 관계적으로 구조화된 데이터를 설명하는 XML을 사용하여 SQL Server 데이터베이스에서 관계형 데이터의 원활한 통합을 가능하게 하는 일련의 라이브러리 및 기술입니다.

SQL 2000 이전에는 개발자들이 관계형 데이터와 XML 형식의 데이터 간에 상호 작용을 위한 코드 레이어를 제공해야 했습니다. 하지만 SQLXML의 등장으로 관계형 데이터와 XML 사이의 연결이 제공되었으므로 작업이 더욱 편리해졌습니다. 이 문서에 설명된 항목은 SQLXML 관리 클래스에 제한됩니다. 이 라이브러리의 다른 기능 적용 가능성에 관한 자세한 내용은 MSDN에서 SQLXML (영문) 페이지를 참조하십시오.

SQLXML은 XML 지원을 위해 SQL Server에 도입된 많은 기능으로 구성됩니다. 이러한 기능은 다음과 같습니다.

- 클라이언트 쪽에서 쿼리 결과를 XML로 변환하는 기능

주석 달린 XSD 매핑 스키마 파일을 사용하여 관계형 데이터의 XML 뷰를 만드는 기능 - 다음을 수행할 수 있습니다.
XML 뷰에 대한 XPath 쿼리 정의
updategrams로 알려진 XML 템플릿을 사용하여 데이터베이스의 데이터에 삽입, 업데이트, 삭제 수행
XML 대량 로드 작업 수행

- HTTP를 사용하여 SQL Server에 액세스하는 기능 - 다음을 수행할 수 있습니다.


URL에 SQL 문 지정
URL에 템플릿 쿼리 지정
URL에 템플릿 파일 지정
URL에 주석 달린 XSD 매핑 스키마 파일에 대해 작성된 XPath 쿼리 지정

저장 프로시저, 사용자 정의 함수 및 템플릿 쿼리에서 제공되는 기능을 SOAP 기반 웹 서비스로 노출하는 기능 SQLXML 관리 클래스를 사용하여 SQLXML에서 제공되는 XML 기능의 이점을 활용하도록 .NET Framework에서 코드를 작성하는 기능

클라이언트 쪽 XML 서식 설정. 클라이언트 쪽에서 FOR XML 절을 지정하면 중간 계층에서 쿼리에 대한 응답으로 서버가 반환한 행 집합에 대해 FOR XML 변환을 수행합니다. 클라이언트 쪽에서 XML 서식 설정을 수행하려면:


SQLXML 관리 클래스를 사용 중인 경우 SqlXmlCommand 개체의 ClientSideXml 속성을 True로 설정합니다.
SQLXMLOLEDB 공급자를 사용 중인 경우 ClientSideXML 공급자별 속성을 True로 설정합니다.
템플릿 쿼리를 사용 중인 경우 템플릿에 client-side-xml="1"를 지정합니다.
HTTP를 사용하여 SQL Server에 액세스하는 경우 설정 탭의 가상 디렉터리에서 클라이언트에서 실행 옵션을 선택합니다.
클라이언트 쪽에서 FOR XML과 함께 사용할 수 있는 XML 서식 설정 모드는 RAW, NESTED 및 EXPLICIT입니다. RAW 모드가 사용되면, 결과 XML 문서는 쿼리 결과의 각 행에 대한 XML 요소와 행의 각 열에 해당하는 특성을 포함합니다. NESTED 모드가 지정되면, 기본 테이블 이름이 결과 XML 문서의 요소 이름으로 반환됩니다. EXPLICIT 모드는 쿼리 자체에 원하는 XML의 형식을 지정할 수 있도록 허용함으로써 모든 형태의 XML 문서를 생성합니다.
XML 뷰. XML 뷰는 관계형 데이터와 XML 데이터 간의 매핑을 정의하는 주석 달린 XSD 스키마를 사용하여 생성됩니다. 이 XML 뷰는 XPath 쿼리를 사용하여 쿼리할 수 있습니다. 또한 XML 뷰를 통해 노출된 관계형 데이터를 수정한 다음 updategrams를 사용하여 수정 사항을 데이터베이스에 제출할 수 있습니다. 뿐만 아니라 XML 뷰는 COM 기반 XML Bulk Load 개체의 도움으로 대형 XML 문서를 데이터베이스에 삽입하는 데도 유용합니다.
SQL Server에 대한 HTTP 액세스. SQLXML은 IIS Virtual Directory Management 유틸리티로 알려진 유틸리티를 제공하며 이 유틸리티를 사용하여 HTTP를 통해 SQL Server의 XML 기능을 노출하도록 IIS 가상 디렉터리를 설정할 수 있습니다. URL에서 직접 SQL 문, 저장 프로시저, 템플릿 쿼리, 템플릿 파일 및 XPath 쿼리를 지정하기 위한 지원은 SQL ISAPI 확장 기능을 통해서 제공됩니다.
SQLXML의 웹 서비스 지원. SQL Server의 기능을 SOAP 기반 웹 서비스로 노출하기 위한 지원은 SQLXML 3.0에서 추가되었습니다. 이 기능을 사용하면 SQL Server가 클라이언트로부터 SOAP HTTP 요청을 받아 저장 프로시저, 사용자 정의 함수 및 템플릿을 실행할 수 있습니다.
SQLXML 관리 클래스. .NET Framework에서의 SQLXML 기능 액세스는 SQLXML 관리 클래스를 통해 제공됩니다. SQLXML에는 세 가지의 관리되는 클래스가 있습니다.
SqlXmlCommand - 데이터베이스 연결 및 쿼리 실행 측면을 다룹니다.
SqlXmlParameter - 쿼리에 매개 변수를 지정하도록 도와줍니다.
SqlXmlAdapter - .NET Framework에서 데이터 집합과의 상호 작용을 촉진합니다.

SQLXML 관리 클래스를 사용하여 다음 작업을 수행할 수 있습니다.


FOR XML 절이 있는 SQL 쿼리 실행
매핑 스키마에 대한 XPath 쿼리 실행
템플릿 쿼리 실행
템플릿 쿼리 파일 실행
updategram 실행
DiffGram 실행

관계형 데이터를 XML 문서로 노출하기 위해 SQLXML을 사용하는 것은 다음과 같은 경우에 적합한 선택입니다.


응용 프로그램이 고도로 구조화되고 관계형 테이블에 잘 매핑되는 XML 데이터를 받습니다.
응용 프로그램이 외부 응용 프로그램에서 받은 대형 XML 문서를 데이터베이스에 로드해야 하고 이 문서를 관계형 형식으로 유지해야 합니다.
응용 프로그램이 문서 순서를 반드시 지켜야 할 필요가 없습니다.
응용 프로그램이 동일한 데이터를 여러 데이터 소비자에게 여러 다른 형식으로 제공해야 합니다.
DML 작업 성능이 응용 프로그램에 대단히 중요합니다.
응용 프로그램이 쿼리 최적화를 위한 최적기의 모든 가능성을 활용해야 할 필요가 있습니다.
응용 프로그램이 세분화된 데이터 조작을 수행합니다.
응용 프로그램이 기존의 관계형 데이터를 XML로 노출해야 합니다.



시나리오 분석

XML 사용 시나리오에 설명된 첫 번째 데이터 교환 시나리오(시나리오 2: 자동차 제조업체와 부품 공급업체 간의 데이터 교환 I 섹션 참조)에서, 자동차 제조업체와 여러 부품 공급업체 간의 상호 작용은 SQLXML 사용의 전형적인 경우를 나타냅니다. 제조업체는 송장 데이터를 교환하기 위해 여러 공급업체들과 통신해야 합니다. 제안된 솔루션은 이 문제를 해결하기 위해 웹 서비스와 SQLXML을 사용합니다. 제조업체는 공급업체가 제조업체에게 송장을 보내기 위해 사용할 수 있는 웹 서비스를 노출합니다. 웹 서비스는 송장을 공급업체 형식에서 제조업체가 사용하는 일반적인 형식으로 변환하기 위해 고객에 따라 다른 XSLT를 사용합니다. 그런 다음 웹 서비스는 송장 문서의 내용을 관계형 테이블의 열에 매핑하는 XML 뷰를 사용하여 XML 문서를 분할합니다. 기존의 송장 처리 시스템은 관계형 테이블에서 데이터를 선택하여 처리 작업을 진행할 수 있을 것입니다. 이 시나리오의 경우 XML 뷰 사용의 이점은 다음과 같습니다.



낮은 유지 관리 비용. 공급업체가 송장 스키마에 적용한 모든 변경은 공급업체에 따라 다른 XSLT 파일을 수정함으로써 쉽게 수용될 수 있습니다.
FOR XML과 비교하여 코딩이 덜 복잡합니다(관계형/XML 통합을 위한 서버 쪽 지원(FOR XML/OPENXML) 섹션 참조).
공급업체에 대해 특정 XSLT 파일을 생성함으로써 새 공급업체를 쉽게 지원할 수 있습니다.



이점

SQLXML 사용의 이점은 다음과 같이 요약될 수 있습니다.



관계형 데이터를 XML 데이터에 매핑하기 위해 주석 달린 매핑 스키마를 만드는 작업은 비교적 간단하며 서버 쪽의 FOR XML EXPLICIT보다 효과적으로 관리 가능한 솔루션입니다.
SQLXML은 FOR XML을 사용하여 만든 관계형 데이터의 읽기 전용 XML 표시와 비교하여 업데이트 가능한 양방향 XML 뷰를 만들 수 있는 기능을 제공합니다.
XSD 매핑은 주요 코드 변경 없이 변경 요청을 XML 형식으로 수용할 수 있는 기능을 제공합니다. 이로 인해 유지 관리가 쉬워집니다.
SQLXML은 클라이언트 쪽에서 XML 형식 지정을 수행할 수 있는 기능을 제공하므로 사용자가 ClientSideXML 속성을 SqlXMLCommand 클래스에 대해 true로 설정할 수 있어 서버에서 로드가 감소됩니다.



제한

부정적인 면을 들자면, SQLXML이 클라이언트 쪽에서 사용되는 경우 몇 가지 제한이 있습니다.



XML 뷰는 XML 문서의 계층이 너무 깊거나 깊이를 알 수 없을 정도로 순환하는 경우에는 적합하지 않습니다.
SQLXML은 제품 카탈로그, 뉴스 보고 등과 같은 혼합된 콘텐츠 표시 및 정렬된 데이터를 포함하는 설명 문서에는 적합하지 않습니다.
문서 순서가 유지되지 않기 때문에 원래의 XML 문서를 다시 작성하기가 어렵습니다.
XML 문서를 관계형 테이블로 세분화하면 우수한 검색 성능을 얻을 수 있지만 XML 간의 변환에는 비용이 많이 들 수 있습니다.
XSD 매핑 스키마에서 기본 매핑이 사용된 경우 데이터베이스 테이블 이름 및 열 정보가 노출될 수 있어 원하지 않은 정보 누출이 발생할 수 있습니다. 이러한 위험은 테이블 및 열에 대해 명시적인 매핑을 지정함으로써 피할 수 있습니다.
URL의 SQL 문은 신뢰할 수 있는 인트라넷에서만 사용되어야 합니다. 인터넷에서 이러한 쿼리를 사용하면 잠재적 보안 위험이 따를 수 있습니다.



SQLXML 사용의 예

이제 SQLXML의 개요 설명을 마쳤으니, 다음 단계로 SQLXML 관리 클래스가 적용될 수 있는 예제를 탐구해 봅시다. 특정 고객에 대한 판매 주문 정보를 내보내는 간단한 예제를 살펴보겠습니다. 이 예제에 사용되는 테이블은 AdventureWorks 데이터베이스에서 이용할 수 있습니다.

데이터베이스의 데이터는 프레젠테이션 계층에서 표시될 수 있는 XML 형식으로 클라이언트에서 사용할 수 있어야 합니다. 그런 다음 SQL 데이터베이스의 관계형 데이터가 어떻게 SQLXML 클래스를 사용하여 XML 데이터로 조작될 수 있는지 확인하게 될 것입니다. 매핑 XML 스키마가 XML 노드 이름을 테이블 필드에 매핑하고 조작하는 데 사용됩니다. SQLXML 관리 라이브러리를 사용한 관계형 데이터 조작에 관한 자세한 내용은 MSDN에서 SQLXML (영문) 페이지를 참조하십시오.

아래의 주석 달린 XSD 스키마는 관계형 테이블 [Sales.Customer], [Sales.SalesOrderHeader], [Sales.SalesOrderDetail]과 고객에 대한 판매 주문 정보의 대상 XML 표시 사이에 매핑을 정의합니다. 또한 아래 XSD 스키마에서 보는 바와 같이 XSD 매핑 스키마를 사용하여 XML에서의 부모(parent)-자식(child) 관계도 정의될 수 있습니다.







위에서 제공한 방법은 명령줄 인수로 지정한 Customer ID에 대한 판매 주문 정보를 응용 프로그램으로 내보냅니다. 데이터는 클라이언트 쪽에서 XML 형식으로 변환되므로 서버 쪽에서 성능 문제를 피할 수 있습니다. 위에서 제공한 주석 달린 XSD 스키마 매핑은 CustomerOrderDetails.xsd로 저장되어야 위 코드 단편이 적절하게 작동될 수 있습니다.

참고 데이터베이스에서 데이터를 XML로 가져오는 데 필요한 코드의 양은 예제에서 볼 수 있듯이 아주 적습니다.



관계형/XML 통합을 위한 서버 쪽 지원(FOR XML/OPENXML)



SELECT 문의 FOR XML 확장을 사용하여 서버 쪽에서 SQL 쿼리 결과를 XML 문서로 반환하기 위한 지원이 SQL Server에 제공되어 있습니다. 한편 OPENXML 키워드는 XML 문서에서 행 집합을 추출할 수 있는 기능을 제공합니다.



FOR XML

서버 쪽 FOR XML은 네 가지 XML 변환 모드 RAW, AUTO, EXPLICIT, PATH를 지원합니다.

기본적으로, RAW 모드는 쿼리 결과 집합의 각 행을 XML 요소에 매핑하고 행의 각 열을 특성에 매핑합니다. ELEMENTS 옵션이 ROW 모드로 지정된 경우 행의 각 열은 행에 대해 생성된 요소의 하위 요소에 매핑됩니다. 또한 XMLSCHEMA 옵션을 지정하여 생성된 XML의 인라인 스키마를 요청할 수 있습니다.

AUTO 모드는 기본적으로, SELECT 절에 최소한 하나의 열이 나열된 FROM 절의 각 테이블이 XML 요소에 매핑되고 SELECT 절에 나열된 열이 특성(또는 ELEMENTS 옵션이 지정된 경우 하위 요소)에 매핑되는 경우 중첩된 XML 요소를 생성하기 위한 지원을 제공합니다.

EXPLICIT 모드는 쿼리 결과에서 생성된 XML의 형태를 최대한 제어할 수 있게 해줍니다. 이 모드를 이용하면 쿼리 자체에 원하는 XML에 대해 형식을 지정함으로써 어떠한 형태의 XML이라도 생성할 수 있습니다.

EXPLICT 모드를 사용하여 복잡한 XML 문서를 작성하는 일은 번거롭습니다. PATH 모드를 중첩 FOR XML 쿼리를 작성하는 기능 및 XML 형식 인스턴스를 반환하는 TYPE 지시어와 함께 사용하면 복잡한 EXPLICIT 모드 쿼리 작성을 위한 대안을 얻을 수 있습니다. PATH 모드는 열 이름을 XPath형 구문으로 해석하여 SELECT 쿼리에서 반환한 행 집합의 열을 특성 및 하위 요소에 매핑합니다. SQL Server 2005의 FOR XML 기능 향상에 대한 자세한 내용은 Microsoft SQL Server 2005에서 FOR XML의 새로운 기능 (영문) 백서를 참조하십시오.



OPENXML

sp_xml_preparedocument 및 sp_xml_removedocument 시스템 저장 프로시저와 함께 OPENXML은 XML 문서의 관계형 행 집합 뷰를 제공합니다. XML 문서에서 OPENXML을 사용하려면 sp_xml_preparedocument를 인-메모리 XML 문서 표시를 만드는 데 사용해야 합니다. 이 저장 프로시저는 MSXML 파서를 사용하여 XML 문서를 구문 분석하고 OPENXML과 함께 사용할 수 있는 XML 문서에 핸들을 반환합니다. 이제 XML 문서 핸들과 같은 매개 변수, rowpattern(XML 데이터의 노드를 행에 매핑하는 XPath 식), 행 집합 스키마 및 행 집합 열과 XML 노드 간의 매핑이 OPENXML에 전달될 수 있어 행 집합을 얻을 수 있습니다. XML 문서는 더 이상 필요 없게 되면 sp_xml_removedocument 저장 프로시저를 사용하여 메모리에서 언로드되어야 합니다.



FOR XML의 향상 기능

FOR XML은 SQL Server 2005에서 다음과 같은 기능으로 향상되었습니다.



새로운 TYPE 지시어를 사용하여 FOR XML의 결과를 형 변환하는 기능
FOR XML의 결과를 XML 형식의 변수에 할당하는 기능
XML 계층을 생성하기 위해 FOR XML 쿼리를 중첩하는 기능
복잡한 XML 문서를 생성하기 위해 새로운 PATH 모드를 사용하는 기능
각각 XMLDATA 및 XMLSCHEMA 옵션을 사용하여 XDR 또는 XSD 형식으로 인라인 스키마를 생성하는 기능
요소 중심 XML을 생성하기 위해 RAW 모드와 함께 ELEMENTS 지시어를 사용하는 기능
xsi:nil="true" 특성을 가진 요소에 NULL 값을 매핑하기 위해 ELEMENT 지시어와 함께 XSINIL 옵션을 사용하는 기능



OPENXML의 향상 기능

SQL Server 2005에서 OPENXML은 다음과 같은 기능을 지원하도록 향상되었습니다.



XML 형식 데이터를 sp_xml_preparedocument에 전달하는 기능
WITH 절에서 새 데이터 형식을 사용하는 기능

XML 문서를 작성 및 분리하기 위해 FOR XML 및 OPENXML을 사용하는 것은 다음의 경우에 적합한 선택입니다.


응용 프로그램이 데이터를 관계적으로 저장하고 이 정보를 다른 응용 프로그램에 XML로 노출해야 합니다.
응용 프로그램이 XML의 순서를 지켜야 할 필요가 없습니다.
응용 프로그램이 과중한 요소 수준의 DML 작업을 수행합니다.
응용 프로그램에 세분화된 데이터 액세스 및 업데이트가 필요합니다.
응용 프로그램에서 웹 서비스를 통해 관계형 데이터를 노출해야 합니다.



시나리오 분석

시나리오 3의 요구 사항(시나리오 3: 자동차 제조업체와 부품 공급업체 간의 데이터 교환 II 섹션 참조)은 공급업체가 송장의 현황을 입수하거나 지불 지침의 복사본을 얻기 위해 이용할 수 있는 웹 서비스를 제공하는 것입니다. 웹 서비스와 함께 FOR XML은 제조업체가 인터넷에서 이러한 서비스를 노출할 수 있도록 하는 솔루션을 제공합니다. 공급업체는 웹 서비스를 이용하여 송장의 현황에 관해 문의합니다. 그러면 웹 서비스가 공급업체가 제공한 송장 ID를 이용해서 FOR XML 문을 사용하여 관계형 데이터로부터 XML 형식으로 응답을 생성합니다. 생성된 XML 문서는 공급업체에게 반환됩니다. 현재의 시나리오에서 FOR XML 문 기반 접근 방법은 다음과 같은 이점을 제공합니다.



FOR XML은 관계형 데이터에서 간단한 XML 문서를 동적으로 작성할 수 있는 손쉬운 방법을 제공합니다.
FOR XML 쿼리가 간단한 XML 문서를 작성하는 데 사용될 경우 FOR XML 쿼리의 유지 관리는 XML 뷰에 비해 쉽습니다.



이점

다음은 FOR XML/OPENXML 사용 시의 몇 가지 이점입니다.

FOR XML은 서버의 관계형 데이터로부터 XML을 생성하는 간단한 방법을 제공합니다.
FOR XML은 웹 서비스를 통해 비즈니스 정보를 노출할 수 있는 기능을 제공합니다.
OPENXML을 이용하면 행 집합을 단지 한 번의 네트워크 라운드 트립으로 대량의 INSERT, UPDATE, DELETE 작업을 수행할 수 있는 XML 형식으로 저장 프로시저에 전달할 수 있습니다.
FOR XML은 XSL과 함께 응용 프로그램 통합 또는 비즈니스 통합에 사용될 수 있습니다.



제한

XML 문서를 작성 및 분리하기 위해 FOR XML/OPENXML을 사용하는 경우의 제한 사항은 다음과 같습니다.

FOR XML을 EXPLICT 옵션과 함께 사용하여 XML 구조를 형성하는 것은 어려운 작업입니다.
FOR XML EXPLICIT를 사용하여 작성한 복잡한 쿼리를 유지 관리하기가 어렵습니다.
FOR XML AUTO에 의해 생성된 XML 문서는 데이터베이스 테이블 이름 및 열 정보를 노출할 수 있어 부주의한 정보 노출이 발생할 수 있습니다. 이 상황은 테이블 및 열에 별칭을 지정함으로써 방지할 수 있습니다.



FOR XML 및 OPENXML 사용의 예

다음 예제는 SQL Server 2005와 함께 제공되는 AdventureWorks 데이터베이스를 사용합니다. 지정된 범위의 고객에 대해 [Sales.Customer], [Sales.SalesOrderHeader], [Production.Product], [Sales.SalesOrderDetail] 테이블에서 고객, 주문 및 주문 상세 정보를 얻기 위해 FOR XML이 사용되는 예제를 살펴보도록 합시다.



예제: FOR XML 사용




쿼리 결과는 아래와 같습니다.


OrderQty="3">


다음 예제는 OPENXML 및 XPath 식을 사용하여 XML 문서에 지정된 주문 상세 정보를 추출합니다.



예제: OPENXML 사용



쿼리 결과는 아래와 같습니다.


--------------------------------------------------------
CustomerID OrderID LineNumber ProductID Quantity
--------------------------------------------------------
44 53575 2 952 2
44 53575 1 969 1
44 53575 3 972 1
44 59024 1 972 3
44 59024 2 957 2
46 48354 1 730 1
--------------------------------------------------------



SQL Server 2005의 XML 데이터 형식



XML 데이터의 계층적 특성으로 인해 데이터의 구조가 복잡해질수록(예: 계층 깊이의 증가) XML 데이터를 관계형 데이터로 모델링하기가 어려워집니다. 게다가 XML 데이터가 관계형 데이터에 매핑될 때 XML 인스턴스에 있는 요소의 순서가 유지되지 않으며 분리된 관계형 데이터에서 원래의 XML 문서를 작성하는 데 관련하여 많은 비용이 듭니다. XML 데이터를 저장하기 위한 관계형 모델의 제한 사항 때문에 XML 인스턴스를 원시적으로 저장하는 것이 가장 좋습니다. 원시 XML 인스턴스는 관계형 모델의 제한 사항에 영향을 받지 않으며 계층 구조 데이터 또는 중첩 데이터를 처리하는 기능, 요소의 순서를 유지하는 기능, XML 데이터를 저장 및 검색하는 간편한 방법, 다중 스키마를 지원하는 유연성 등과 같은 기능을 제공합니다.

Microsoft SQL Server 2005는 XML 데이터 처리를 위한 광범위한 지원을 제공합니다. SQL Server 2005에서는 XML 값이 XML 데이터 형식 열에 원시적으로 저장될 수 있어 XML 스키마의 모음에 따라 형식화되거나 혹은 형식화되지 않은 상태로 있을 수 있습니다. 세분화된 데이터 조작은 XQuery 및 XML DML을 사용하여 지원되며 후자의 경우는 데이터 수정을 위한 확장입니다. 게다가 XML 열은 쿼리 성능 향상을 위해 인덱스될 수 있습니다.



형식화된 XML

형식화된 XML은 XML 데이터를 설명하는 XML 스키마가 있는 경우에 이상적입니다. 이와 같은 경우 XML 스키마 모음을 XML 열에 연결하여 형식화된 XML을 제공할 수 있습니다. XML 형식 열에 대한 유효성 검사는 열과 연결된 XML 스키마 모음을 기준으로 수행됩니다. 또한 형식화된 XML 데이터는 노드 값의 런타임 변환이 필요하지 않으므로 형식화된 XML 데이터를 포함하는 쿼리의 성능은 형식화되지 않은 XML 데이터와 비교하여 더 우수합니다.



형식화되지 않은 XML

형식화되지 않은 XML의 사용은 스키마가 있지만 서버에서 데이터 유효성을 검사하기를 원하지 않는 경우 또는 사용할 수 있는 스키마가 없는 경우에 적합합니다. 다음과 같은 경우에는 스키마가 제공되어 있어도 형식화되지 않은 XML을 저장할 수 있습니다.

응용 프로그램에 고정 스키마가 없습니다.
서버에서 데이터를 저장하기 전에 응용 프로그램이 클라이언트 쪽에서 유효성 검사를 수행합니다.
응용 프로그램이 스키마에 준하여 유효하지 않은 XML 데이터를 일시적으로 저장합니다.
응용 프로그램이 서버에서 지원되지 않는 스키마 구성 요소(예: key/keyref)를 사용합니다.

형식화되지 않은 XML 문서는 어떤 스키마와도 연결되지 않은 경우에라도 제대로 형성될 수 있도록 검사됩니다. 형식화되지 않은 XML은 노드 값의 런타임 변환으로 인해(노드 값이 내부적으로 유니코드 문자열로 저장되기 때문), 성능 손실을 초래한다는 점에 주의하십시오.



XML 데이터 형식의 사용 시나리오

SQL Server 2005의 새로운 XML 데이터 형식을 사용하면 이제 다음과 같은 작업을 할 수 있습니다.



관계형 열뿐 아니라 XML 형식의 열이 하나 이상인 테이블을 만듭니다.
XML 열을 XML 스키마 모음에 연결하여 형식화된 XML 열 형식을 만듭니다.
업무 규칙을 유지하기 위해 다른 XML을 포함하는 XML 열 또는 비 XML 형식 열에 제약 조건을 만듭니다.
XML 데이터 형식의 인스턴스를 저장하는 데 사용할 수 있는 XML 형식의 변수를 만듭니다.
저장 프로시저 또는 사용자 정의 함수에 XML 형식의 매개 변수를 만듭니다.
사용자 정의 함수에서 XML 형식 값을 반환합니다.
새로운 TYPE 지시어를 사용하여 얻은 FOR XML 쿼리 결과를 XML 형식의 변수에 할당합니다.
XQuery의 하위 집합을 실행하여 XML 구조로 쿼리하고 XML 데이터를 변환합니다.
XML 형식의 열을 기반으로 계산 열을 만듭니다.
쿼리 성능을 향상시키기 위해 XML 형식의 열에 XML 인덱스를 만듭니다.
XML DML을 사용하여 XML 인스턴스에서 요소 수준의 삽입, 삭제, 업데이트 작업을 수행합니다.
XML 형식 데이터의 인스턴스를 sp_xml_preparedocument로 전달하여 인-메모리 XML 문서 표시를 준비합니다.
XQuery 및 XML DML을 사용하여 관계형 열 및 XML 열을 모두 포함하는 도메인 간 쿼리를 작성합니다.
각각 CAST 및 CONVERT를 사용하여 XML 형식을 varchar 또는 nvarchar 형식으로 캐스팅하거나 변환합니다.
CAST 또는 CONVERT를 사용하여 [n]varchar, [n]text, varbinary, image와 같은 문자열 데이터 형식을 XML 형식으로 변환하거나 캐스팅합니다.



XML 데이터 형식 메서드 및 XML DML

XML 데이터 형식 열에 대한 쿼리 및 조작은 다섯 가지 메서드를 통해 지원됩니다. XML 문서의 조각은 XML 데이터 형식의 query() 메서드를 사용하여 추출될 수 있습니다. query() 메서드는 XQuery 식을 인수로 받아들여 형식화되지 않은 XML 인스턴스를 반환합니다. 스칼라 값은 XQuery 식과 반환되기를 원하는 SQL 형식을 지정하여 value() 메서드를 사용하여 XML 인스턴스에서 추출될 수 있습니다. XML 인스턴스에 대한 존재 확인은 exist() 메서드를 사용하여 수행될 수 있습니다. XML 문서를 관계형 데이터로 분해하는 작업이 nodes() 메서드를 통해 용이해집니다.

데이터 조작 작업은 modify() 메서드를 사용하여 XML 인스턴스에서 수행될 수 있습니다. XML DML 지원은 XQuery에 추가된 삽입, 삭제, 업데이트 키워드를 통해 제공됩니다. 삽입, 삭제, 업데이트 키워드를 각각 사용하여 하나 이상의 노드가 삽입, 삭제 및 업데이트될 수 있습니다.



XML 인덱싱

XML 데이터 형식 열에서 쿼리 처리 작업에 포함되는 구문 분석 및 분할은 XML 인스턴스의 크기가 매우 큰 경우 엄청나게 긴 시간이 소비될 수 있습니다. XML 데이터 형식의 쿼리 성능은 이러한 열에 인덱스를 생성함으로써 향상될 수 있습니다. XML 데이터의 크기 및 사용 시나리오는 필요한 인덱스의 종류를 지정하는 데 중요한 역할을 수행합니다. SQL Server는 두 가지 종류의 인덱스, 즉 주 XML 인덱스와 보조 XML 인덱스를 지원하며 후자는 전자 없이는 존재할 수 없습니다.

XML 열에서 주 XML 인덱스의 생성은 XML BLOB를 분할하고 이 값을 내부 테이블에 저장합니다. 이로 인해 런타임에 수반되는 분할 작업이 없어져 쿼리 실행 시간 동안 성능이 향상되었습니다. 사용 시나리오에 따라 보조 XML 인덱스를 생성함으로써 쿼리 성능을 한층 더 향상시킬 수 있습니다. 각각 경로, 속성, 값을 기준으로 쿼리 성능을 향상시키기 위해 보조 XML 인덱스의 세 가지 유형인 PATH, PROPERTY, VALUE를 만들 수 있습니다. XML 형식 열에 적합한 보조 인덱스 선택에 관한 자세한 내용은 “XML 데이터 형식을 위한 성능 최적화” 백서에서 볼 수 있습니다.


XML 문서를 XML 데이터 형식으로 저장하는 것은 다음의 경우에 적합한 선택입니다.


응용 프로그램이 XML 인스턴스의 Infoset 콘텐츠를 보존하도록 요구됩니다. XML 문서의 Infoset 콘텐츠는 문서 계층, 요소 순서, 요소 및 특성 값 등을 포함합니다. 특성 순서, 이름 공간 접두사, 중요하지 않은 공백 및 XML 선언과 같은 정보는 보존되지 않습니다.
응용 프로그램이 XML 문서에 대한 요소 수준의 수정 및 쿼리 작업을 필요로 합니다.
응용 프로그램이 쿼리 처리 속도를 높이기 위해 XML 데이터 형식 열에 대한 인덱스를 필요로 합니다.
XML 데이터에 스키마가 있을 수도 있고 없을 수도 있습니다.
응용 프로그램이 다양한 구조의 XML 문서 또는 관계형 구조에 매핑하기에 너무 어려운 서로 다르거나 복잡한 스키마를 따르는 XML 문서를 사용합니다.



시나리오 분석: 콘텐츠 관리 시스템

이제 XML 사용 시나리오(시나리오 4: 콘텐츠 관리 시스템 섹션 참조)에서 설명한 콘텐츠 관리 시스템을 분석해 봅시다. 출판 회사는 텍스트, 이미지, 오디오, 비디오 등 다양한 형식의 정보를 처리합니다. 독립적으로 사용될 수 있는 정보 블록은 다양한 소스에서 수집되고 데이터베이스에서 유지 관리됩니다. 이러한 정보 블록은 구성 요소로 알려져 있습니다. 개별 구성 요소를 조합하여 문서가 만들어집니다. 문서에 어떤 구성 요소가 포함되는지는 사용자의 요구에 따라 다릅니다. 이러한 문서는 다양한 채널을 통해 가입한 사용자들에게 제공됩니다. 콘텐츠 관리 시스템은 일반적으로 높은 성능과 확장성을 갖추고 콘텐츠를 저장, 조회, 검색 및 업데이트할 수 있는 능력이 있어야 합니다.

통합 데이터 모델인 XML은 동일한 문서에 XML 데이터 및 XML 콘텐츠를 모두 저장할 수 있는 뛰어난 옵션을 제공합니다. XML은 또한 데이터에서 표시를 분리하는 기능을 제공하는데, 이 기능은 동일한 정보가 각 사용자마다 서로 다르게 표시될 수 있기 때문에 중요합니다. SQL Server 2005에서 제공하는 원시 XML 데이터 형식을 사용하여 이러한 콘텐츠 관리 시스템의 요구 사항을 맞출 수 있습니다. XML 데이터 형식을 사용하면 XML 문서를 저장하고, XML DML을 사용하여 요소 수준에서 XML 문서를 수정하고 XQuery를 사용하여 XML 문서에서 쿼리를 수행할 수 있습니다.



시나리오 분석: 고객 설문조사

고객 설문조사 XML 사용 시나리오(시나리오 5: 고객 설문조사 섹션 참조)에서 주요 요구 사항은 여러 스키마를 사용하는 설문조사 정보를 저장할 수 있는 능력입니다. 고정 스키마가 없는 데이터는 관계형 테이블을 하나만 사용하여 모델링될 수 없습니다. XML 열이 있는 관계형 테이블은 이러한 정보를 저장할 수 있는 우수한 옵션을 제공합니다. 설문조사의 형식을 저장하기 위해 추가 열을 관계형 테이블에 추가할 수 있습니다. 설문조사 형식 열을 사용하여 설문조사 형식의 모든 레코드를 반입함으로써 설문조사의 특정 형식에 해당하는 정보를 분석할 수 있습니다. 일반적인 설문조사에서 고객은 대개 모든 질문에 대해 대답하지는 않습니다. 따라서 몇 개의 열을 만들고(설문조사에서 각 질문마다 하나씩) 대답하지 않은 질문에 대해 데이터베이스에 NULL 값을 저장하는 대신, 하나의 열에 고객 한 명에 대한 설문조사 정보를 XML로 저장하는 것이 유용할 수 있습니다. 이 시나리오의 경우에는 다음과 같은 이유 때문에 고객 설문조사 정보를 XML 형식 열로 저장하는 것이 더 적절합니다.



XML 형식 열을 사용하면 서로 다른 스키마를 사용하는 설문조사 정보를 단일 XML 형식 열에 저장할 수 있습니다. XML 형식 열을 XML 스키마 모음에 연결하면 사용자가 여러 설문조사 형식의 데이터를 저장할 수 있습니다.
설문조사 정보의 유효성 검사를 사용자 인터페이스에서 수행할 수 있으며 데이터베이스 수준에서 유효성 검사를 실시하기 위해 이 정보를 형식화된 XML 데이터 형식 열로 저장할 필요가 없습니다.
XQuery를 사용하여 데이터를 분석할 수 있습니다.



이점

XML 데이터를 XML 데이터 형식 열에 저장할 경우의 이점은 다음과 같이 요약될 수 있습니다.



XML 데이터 형식은 문서 순서 및 문서 구조를 유지하면서 서버에서 XML 데이터를 저장하는 간단하고 손쉬운 방법을 제공합니다. 이는 문서 순서 및 문서 구조가 매우 중요한 문서의 경우에 특히 그렇습니다. 응용 프로그램이 일부 데이터 원본에서 XML 문서를 가져와서 그 문서를 저장하도록 작동하는 간단한 시나리오를 가정해 봅시다. 문서를 nvarchar 또는 text 열에 저장하면 XML이 잘 구성되도록 보장되지 않으며 문서 내용에 쉽게 액세스할 수 없습니다. 이와 같은 경우에는 들어오는 XML 문서를 XML 열에 원시적으로 저장하는 것이 적절합니다.
XML 데이터 형식은 XML 데이터에서 세분화된 쿼리를 수행하고 작업을 수정할 수 있는 능력을 제공합니다. SQL Server 2005 이전에는 XML을 데이터베이스에 원시적으로 저장하는 방법이 없었습니다. 따라서 XML 데이터를 수정하거나 쿼리하려면, nvarchar 또는 text 열에서 데이터를 로드해서 문자열을 이용하여 XML 문서를 만든 다음 수정해야 했습니다. 데이터베이스에 다시 데이터를 기록하고 수정하기 위해서도 이와 비슷한 단계를 거쳐야 했습니다. 이제 XML 데이터 형식을 사용하면 이러한 작업이 훨씬 쉬워집니다.
XML 데이터 형식을 사용하면 더 빠른 쿼리 처리를 위해 XML 데이터 형식 열에 인덱스를 만들 수 있습니다.
XML 데이터 형식을 사용하는 경우 XML 스키마 모음과 XML 데이터에 대한 제약 조건을 사용하여 업무 규칙을 유지할 수 있습니다. XML 스키마는 데이터 유효성을 검사하고, 형식 기반 작업 상의 의미론을 추가하고, 쿼리 및 데이터 수정 문의 컴파일 동안 형식화되지 않은 XML보다 더 정확한 형식 검사를 수행하고 저장 및 쿼리 처리를 최적화합니다.
XML 형식 데이터는 데이터베이스에 저장되므로 백업 및 복원, SQL Server 보안, 트랜잭션, 로깅 등과 같은 다양한 데이터베이스 작업에 포함됩니다.



제한

다음은 새로운 XML 데이터 형식으로 작업할 경우에 알아두어야 할 제한 사항들 중 일부입니다.



데이터의 정확한 복사본이 저장되지 않습니다. 중요하지 않은 공백, 이름 공간 접두사, 특성 순서 및 XML 선언이 보존되지 않습니다.
XML 문서에서 최대 계층 깊이는 128입니다.
XML 문서의 내부 이진 표시의 최대 크기는 2GB입니다.
XML 인스턴스를 비교할 수 없습니다. 따라서
XML 열이 기본 키 또는 외부 키 제약 조건의 일부가 될 수 없습니다.
XML 열을 GROUP BY 문에서 그룹화 값으로 사용할 수 없습니다.
text, ntext, image 데이터 형식은 SQL Server 2005에서 사용이 지양되므로 XML은 이러한 형식으로 캐스팅될 수 없습니다. 하지만 XML 데이터 형식은 [n]varchar 및 [n]varbinary 형식으로 캐스팅될 수 있습니다.



XML 데이터 형식 사용의 예

예제 응용 프로그램은 AdventureWorks 데이터베이스에서 Sales.Store 테이블을 사용합니다. Sales.Store 테이블은 기본 키로 CustomerID를, XML 열로 Demographics를 포함합니다. Demographics 열은 Store Survey 정보를 포함합니다. Store Survey의 일부로 저장된 정보는 선택적입니다. 이는 Demographics 열이 모든 요소를 포함할 수도 있고 그렇지 않을 수도 있음을 의미합니다. 동일한 정보가 관계형 형식으로 저장된 경우에는 이들 요소를 테이블의 열로 만들어야 합니다. Store Survey 정보의 대부분은 선택적이기 때문에 이 열은 데이터의 대부분에 대해 NULL 값을 포함할 것입니다. 이러한 낭비를 피하기 위해 Demographics 열에 있는 Store Survey 정보는 XML 형식으로 저장됩니다. Demographics 열은 판매 정보 즉, 각 고객에 대한 연간 판매, 연간 수익, 은행 이름 등을 포함합니다. 이들 필드는 데이터의 XML 요소로 저장됩니다.

예제 응용 프로그램은 다음 기능을 수행합니다.



모든 고객의 목록을 인구 통계학적 정보와 함께 표시합니다.
특정 고객에 대한 인구 통계학적 정보를 표시합니다.
Sales.Store 테이블에 새 고객을 인구 통계학적 정보와 함께 삽입합니다.
해당 고객에 대한 인구 통계학적 정보의 일부 요소(예: Annual Sales, Annual Revenue 등)를 수정합니다.
해당 고객에 대한 인구 통계학적 정보를 삭제합니다.

응용 프로그램이 System.Data.SqlTypes.SqlXml 클래스를 사용하여 XML 열에서 데이터를 검색합니다. SQLXML 클래스는 XML 열에 대한 직접적인 매핑입니다.

SQLXML 클래스를 사용하면 어떤 매핑이나 변환 없이도 XML 열에서 데이터를 직접 검색할 수 있습니다.

여기에서 customer ID 12에 대한 Annual Revenue 요소를 검색하는 방법의 예를 살펴보도록 합시다. 다음 코드 예제는 위에서 언급한 두 번째 기능을 보여줍니다.





위 메서드에서는 AdventureWorks 데이터베이스에 SqlConnection 개체의 인스턴스를 만듭니다. 명령 텍스트 속성은 customer ID 12에 대한 Annual Revenue 필드의 값을 검색하는 쿼리를 포함합니다.

이 코드는 XML 열에서 직접적으로 실행되는 XQuery 입니다. 쿼리의 반환 값은 XML 조각으로서 SQLXML 클래스에 매핑됩니다. 그러고 나서 XML 조각은 SQLXML 클래스의 Value 속성을 사용하여 검색될 수 있습니다.

그런 다음 검색된 XML 조각은 XML 웹 서버 컨트롤을 사용하여 클라이언트 응용 프로그램에 표시됩니다.



다양한 접근 방법 비교

기능 .NET Framework의 XML 클래스 FOR XML / OPENXML SQLXML XML 데이터 형식
코드 복잡도 높음. XML 데이터와 관계형 데이터 사이를 직접적으로 매핑하는 클래스가 없습니다. 보통. FOR XML EXPLICIT를 사용한 쿼리 작성이 어렵습니다. 낮음. 클래스가 관계형 데이터를 XML 데이터로 조작하는 메커니즘을 제공하고 또한updategrams가 레코드를 업데이트하는 기능을 제공합니다. 낮음. XML 데이터가 그 자체로서 열에 저장되므로 복잡도가 줄어듭니다. 뿐만 아니라 Visual Studio 2005는 XML 데이터 형식을 조작하기 위한 클래스를 제공합니다. XML DML은 XML 데이터를 수정하는 데 사용할 수 있습니다.
유지 관리성 복잡함. 테이블의 필드 또는 XML을 변경하는 데 코드 변경이 필요합니다. 어려움. 테이블의 필드 또는 XML을 변경하는 데 쿼리 변경이 필요합니다. 쉬움. 대부분의 경우 매핑 XSD 파일을 수정하면 변경 사항이 적용될 수 있습니다. 쉬움. XQuery는 데이터베이스의 XML 열 쿼리를 위한 쉬운 구문을 제공합니다.
설치 .NET Framework 이외의 다른 특별한 설치가 필요하지 않습니다. 특별한 설치가 필요하지 않습니다. SQLXML 라이브러리가 클라이언트 시스템에 설치되어 있어야 합니다. 특별한 설치가 필요하지 않습니다.
보안 정상적인 경우에는 데이터 유형 및 형식이 클라이언트 쪽에 노출되지 않기 때문에 상당히 안전합니다. 테이블 이름 및 열 이름의 노출을 방지하도록 적절한 주의를 기울인다면 안전합니다. 매핑 XSD 파일이 중간 계층 대신 클라이언트 쪽에 저장된 경우 매핑 XSD 파일의 보안을 유지하도록 설계해야 합니다. 보안됨
.NET Compact Framework에 대한 지원 제한된 지원. Microsoft .NET Compact Framework에서 XmlDataDocument는 지원되지 않습니다. 지원됨 지원되지 않음 지원되지 않음. SQL Server의 XML 데이터 형식 열이 SQL Server 모바일에 동기화되면 ntext로 변환됩니다.
데이터 유효성 검사 클라이언트 및 서버에 의해 실행될 수 있습니다. 서버에 의해 실행될 수 있습니다. 클라이언트에 의해 수행될 수 있습니다. XML 스키마를 사용하여 서버에 의해 실행될 수 있습니다.
데이터 저장소 [n]varchar(max), XML, or varbinary(max) 관계형 테이블(XML을 필드로 사용할 수 있음) 관계형 테이블(XML을 필드로 사용할 수 있음) XML 데이터 형식
충실도 원문 충실도(바이트 수준에서 XML 데이터를 보존함) 관계 충실도(데이터의 계층 구조는 보존하지만 요소 간의 순서는 무시함) 관계 충실도 InfoSet 충실도(XML 데이터의 InfoSet 콘텐츠를 보존함)
저장소에서의 데이터 액세스 및 업데이트 문서 수준에서 업데이트를 지원합니다. 세분화된 데이터 액세스 및 업데이트를 지원합니다. 세분화된 데이터 액세스 및 업데이트를 지원합니다. 세분화된 데이터 액세스 및 업데이트를 지원합니다.


결론

이 문서에서는 SQL Server 2005에서 XML을 처리하기 위한 여러 옵션에 대해 알아보았습니다. System.Xml 이름 공간, SQLXML 및 XML 데이터 형식을 각각의 관련 이점 및 제한과 함께 예제 시나리오를 들어 설명했습니다. 이상적인 시나리오에서 나타난 성과를 통해 사용자는 자신의 응용 프로그램에 맞는 적절한 XML 옵션을 선택할 수 있습니다.


추가 정보

- Microsoft SQL Server 2005 웹 사이트
- Microsoft SQL Server 2005에서의 XML 지원
- Microsoft SQL Server 2005를 위한 최상의 XML 사용 방법
- Microsoft SQL Server 2005에서 FOR XML의 새로운 기능
- XML 데이터 형식을 위한 성능 최적화


제공 : DB포탈사이트 DBguide.net
출처명 : 한국 마이크로소프트

"MSSQL" 카테고리의 다른 글
  • Microsoft SQL Server 2000 Distributed Queries:... (0)2007/06/22
  • SQL Server 2005에서 XML 데이터 형식을 위한 성능... (0)2007/05/25
  • Microsoft SQL Server 2005의 XML 옵션 (0)2007/05/25
  • SQL 서버에서「데이터 코드 에러」처리하기 (0)2007/05/25
  • SQL 성능을 높이는 5가지 방법 (1)2007/05/25
2007/05/25 15:33 2007/05/25 15:33
Posted by webdizen
Tags FOR XML, OPENXML, SQL Server 2005, SQLXML, XML, XML 인덱싱
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3037

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/23 09:15

VS.NET으로 개발하는 SQL 서버 2005

한용희 | 롯데정보통신 칠성IS 사업팀

운영체제 │ 윈도우 2000, 윈도우 2003, 윈도우 XP
개발도구 │ MS SQL 서버 2005 베타 2, 비주얼 스튜디오 2005 베타 1
기초지식 │ MS SQL 서버 2000, C#
응용분야 │ MS SQL 서버 2005 관리와 개발

SQL 서버 2005의 가장 큰 변화라고 한다면 아마도 닷넷 프레임워크와의 통합일 것이다. 이제는 쿼리문을 C#을 이용해서 개발할 수 있을 뿐만 아니라 C#을 통해서 T-SQL이 하지 못하는 기능을 마음껏 확장할 수도 있다. 이번 호에서는 CLR에 통합된 SQL 서버 2005의 새로운 모습을 살펴본다.

지난 시간에서는 T-SQL의 새로운 모습에 대하여 살펴봤다. T-SQL은 언어 자체가 집합적 언어이기 때문에 여전히 데이터를 조작하고 접근하는 데 있어서는 닷넷 언어보다 더 좋은 성능을 나타낸다. 하지만 T-SQL은 절차적 언어이기 때문에 객체지향적 프로그래밍을 할 수 없다는 단점이 있다. 그러나 닷넷을 이용하면 더 이상 이 문제로 고민하지 않아도 된다. C#, VB.NET, Managed C++를 이용해서 얼마든지 객체지향적 프로그래밍이 가능하다. 또한 복잡한 로직이나 계산, 외부 자원 연동, 코드 재사용 등에 있어서는 T-SQL보다 더 좋은 접근성과 성능을 보여준다. 한 마디로 닷넷 프레임워크와의 통합은 T-SQL을 교체하는 개념이 아니라 더욱 확장하고 강화하기 위하여 도입된 것이라고 보면 된다.

SQL 서버 2005는 닷넷 프레임워크와 통합되면서 안정성이 대폭 향상되었다. 이전 SQL 서버 2000에서 확장 저장 프로시저를 C++를 이용해서 작성하는 경우 간혹 잘못된 코드로 인하여 SQL 서버 전체가 다운되는 경우가 있었다. 그래서 확장 저장 프로시저를 매우 신중하게 만들어야 했으며 만드는 과정 자체도 간단하지가 않았다.

하지만 SQL 서버 2005에서는 기본적으로 닷넷 프레임워크의 호스팅 모델을 따라간다. SQL 서버 2005와 각각의 닷넷 코드로 만들어진 확장 저장 프로시저는 서로의 독립성을 보장한다. 서로 메모리를 직접적으로 침범할 수 없으며, 서로의 실행 환경을 침해할 수도 없다. 각각 별도로 운영된다는 것이다. <그림 1>을 보면 닷넷 프레임워크의 호스팅 모델이 나와 있다. SQL 서버와 외부 어셈블리는 서로 다른 도메인을 가지고 있어 자신의 독립적인 실행 환경을 보호한다. 그래서 이제는 확장 저장 프로시저 때문에 더 이상 SQL 서버가 다운되는 일은 없다.

SQL 서버는 자기 자신만의 특별한 쓰레드 스케쥴링, 동기화, 잠금, 메모리 할당 정책을 가지고 있다. SQL 서버 자체가 워낙 메모리를 많이 사용하고 성능이 중요한 기업용 애플리케이션이기 때문에 보통의 CLR(Common Language Runtime)에서 제공하는 정책을 따르지 않고 자기 자신만의 특별한 방식을 적용해서 운영을 한다. 만약 외부 어셈블리가 CPU나 메모리를 과도하게 많이 써서 SQL 서버를 운영하는데 지장을 준다면, SQL 서버는 이를 즉시 탐지해내고 해당 사용권을 외부 어셈블리로부터 뺏어온다. 이렇게 함으로써 SQL 서버는 더 이상 외부의 간섭에 영향을 받지 않고 자기 자신을 스스로 안정적으로 운영할 수 있는 능력을 가지게 되었다.

사용자 삽입 이미지
<그림 1> .NET 프레임윅 호스팅


사용자 삽입 이미지
<화면 1> SQL 서버용 템플릿


사용자 삽입 이미지
<화면 2> IsValidZipCode 초기 생성 화면



간단한 사용자 정의 함수 만들기

먼저 간단한 사용자 정의 함수를 C#으로 만들어 볼 것이다. 복잡한 표현식이나 계산을 요하는 작업의 경우 C#으로 만드는 것이 더 효율적이므로 이번 예제에서는 우편번호를 체크하는 간단한 정규식 표현 함수를 만들어 보자. 먼저 VS.NET을 시작하고 새로운 프로젝트로 SQL 서버 프로젝트를 선택한다. CLREx이라는 새로운 프로젝트를 만들고 AdventureWorks DB 서버에 연결한 후 새로운 아이템으로 IsValidZipCode라는 사용자 정의 함수를 추가한다.
그러면 <화면 2>와 같은 템플릿 코드가 들어 있다. 여기에서 주의해서 봐야 할 것은 함수 위에 있는 속성 [SqlFunction]이다. 이 속성은 다음의 함수가 SQL에서 사용하는 사용자 정의 함수임을 컴파일러에게 알려주는 지시자이다. 이제 기본 코드는 지우고 다음과 같이 코딩을 하자.



간단하게 해당 문자열이 우편번호식인지 검사하여 결과를 리턴해 주고 있다. 이제 이 코드를 컴파일하여 배포까지 하자. 그러면 자동으로 SQL 서버에 이 어셈블리가 등록된다. 배포를 성공적으로 끝내면 다음과 같이 테스트해 보자.



-----
1

(1 row(s) affected)
-----
0
(1 row(s) affected)
잘 작동하는 것을 볼 수 있을 것이다. 사용자 정의 함수를 만들어서 사용해 보았는데 함수를 만들고 배포하는 것이 간단하다는 것을 느꼈을 것이다. 그럼 SQL 서버 내부에는 어떻게 등록되어 있는 것일까?

SELECT * FROM sys.assemblies;

sys.assemblies라는 뷰를 보면 해당 CLREx이라는 어셈블리가 등록되어 있는 것을 확인할 수 있을 것이다.

SELECT * FROM sys.assembly_files;

sys.assembly_files에는 실제 어셈블리의 내용이 들어 있다. 즉, DLL 바이너리 자체를 SQL 서버안에 등록한 것이다. 그러므로 한번 어셈블리를 SQL 서버 안에 배포하면 해당 DLL 파일은 없어도 무방하다. 앞에서는 배포를 VS.NET을 이용해서 자동으로 배포하였지만, 수동으로 배포하는 방법도 있다.

CREATE ASSEMBLY UDF1
FROM ‘\\localhost\Projects\CLREx\CLREx\bin\Debug\CLREx.dll’;

CREATE FUNCTION IsValidZipCode(@ZipCode nvarchar(10))
RETURNS bit
EXTERNAL NAME
CLREx.UserDefinedFunctions.IsValidZipCode;

이와 같이 먼저 어셈블리를 등록하고 해당 함수를 만들어 주면 수동으로도 등록할 수 있다.

저장 프로시저를 C#으로 만든다?

이번에는 저장 프로시저를 만들어 보자. 저장 프로시저를 만들려면 먼저 SQL 문장을 실행해서 결과를 리턴해야 한다. 그러기 위해서는 어셈블리가 DB에 접속을 해서 SQL 문장을 보내줘야 한다. 일반적으로 ADO.NET을 이용해서 DB에 접속을 하지만 기존의 연결 방법을 사용할 경우에는 외부에서 접속해 들어오는 것이므로 성능 상에 문제가 있다. 따라서 내부 접속을 위한 별도의 데이터 프로바이더(Data Provider)가 필요한데 그것이 바로 SQL Server Managed Provider이다. 이 프로바이더는 SQL 서버 내에서 실행되므로 별도의 접속을 맺을 필요 없이 빠르게 수행을 한다. 따라서 open, close와 같은 절차가 필요 없는 데이터 프로바이더이다. 사용 방법은 다음과 같이 선언하면 된다.

using System.Data.SqlServer;

SQL Server Managed Provider에는 효과적인 작업을 위하여 Sql Command, SqlPipe, SqlResultSet, SqlTransaction, SqlTrigger Context와 같은 몇 가지 타입을 제공한다. 이중 대부분은 SqlClient에 있는 것과 동일하고 SqlPipe와 SqlTiggerContext가 이번에 새로 등장한 타입이다. SqlTiggerContext는 트리거 작성을 위한 타입이고, SqlPipe는 테이블과 같은 데이터를 호출하는 쪽에 보내줄 때 사용하는 타입이다. 그러면 SqlResultSet과 뭐가 다르냐고 할 수도 있다. SqlResultSet은 성능 문제로 인하여 사용을 권하지 않는 타입이고(이제는 없어질지도 모른다) SqlPipe가 성능상 더 좋은 타입이다. SqlPipe는 말 그대로 호출자에게 파이프로 물을 보내듯이 데이터를 받는 즉시 바로 보낸다. 성능면에서도 T-SQL의 저장 프로시저와 거의 비슷한 성능을 보여준다. 그러므로 앞으로 테이블 데이터를 리턴받는 경우에는 SqlPipe를 써야 한다. 또한 닷넷 저장 프로시저는 리턴 값으로 int형과 void형만을 리턴할 수 있으므로 어차피 SqlResultSet 형식으로 리턴하지도 못한다.

이번에는 직접 저장 프로시저를 만들어 보자. 이전에 만든 프로젝트에 저장 프로시저를 하나 추가하고 다음과 같이 코딩을 한다.



이번 예제는 사용자 테이블에서 특정 부서의 사람들을 추출하는 저장 프로시저이다. 이를 컴파일하고 배포한 후 다음과 같은 SQL 문장으로 테스트해 보면 결과를 볼 수 있을 것이다.

EXEC dbo.SelectEmp 4;

나만의 데이터 타입을 만들자

SQL 서버에는 기본적으로 char, int와 같은 기본 데이터 타입을 지원한다. 여기에 더 확장하여 우리가 원하는 데이터 타입을 스스로 만들어서 추가할 수도 있다. 예를 들면 위도, 경도, 포인트를 나타내는 데이터 타입이라든지 이메일 주소를 나타내는 데이터 타입을 새로 만들어서 추가할 수 있다. 포인트를 보면 10:30과 같은 표현식을 수용하는 하나의 컬럼을 만들 수도 있다. 그런데 사실 이러한 표현은 기존의 컬럼을 두 개로 나누어서 x, y좌표 값을 저장해도 된다. 굳이 사용자 정의 데이터 타입(User-Defined Data Types, UDT)을 안 만들어도 할 수는 있다. 하지만 의미상 하나로 표현하는 것이 더 타당하고, 그 자료형과 관련된 많은 메쏘드나 행위가 필요할 때에는 하나의 데이터형으로 만드는 것이 바람직하다.

예를 들면 날짜 같은 데이터 타입을 년, 월, 일로 나누어서 3개의 컬럼에 저장하는 것보다는 년월일 하나로 만들어서 하나의 컬럼에 저장하는 것이 더 의미상 더 타당하다는 것은 누구나 알고 있다. 또한 날짜와 관련된 많은 메쏘드와 제약사항들이 있기 때문에 이를 3개의 컬럼으로 나누어서 처리하는 것은 많은 불필요한 코드들을 필요로 한다. 예를 들면 월에 1월을 더하거나 빼는 연산과 같은 것들을 하나의 데이터 타입에 같이 넣어 두면 어디서나 손쉽게 끌어다 쓸 수 있다. SQL 서버의 UDT는 데이터 자체뿐만 아니라 메쏘드도 같이 포함할 수 있으므로(사실 UDT는 클래스나 구조체로 정의한다) 이러한 구현이 가능하다.

그럼 여기서 이런 생각까지 하는 독자가 있을 수도 있다. “UDT를 클래스의 개념으로 볼 수 있으니 이제는 객체를 그대로 DB에 저장할 수 있다는 얘기군. 그럼 아예 사원(Employee) 객체를 통째로 DB에 저장해 볼까?” 여기까지 생각을 하면 “그동안 미들티어에서 했던 OR 맵핑(Object Relational Mapping)이 더 이상 필요 없는 진정한 객체지향의 DB가 탄생했군!”이라고 생각할 수도 있다. 틀린 얘기는 아니다. 하지만 성능과 용량이 문제가 된다. UDT는 8KB라는 크기 제한이 있고, 인덱싱 처리의 제약, 그리고 데이터 업데이트 시 부하가 있다. 그러므로 UDT는 그러한 복잡한 객체를 저장하는 데에는 적절하지 않다. 처음에 예를 들었던 위도, 경도, 포인트와 같이 가벼운 객체를 저장할 때에만 이 UDT를 사용해야 한다.

UDT는 결국 클래스를 하드디스크에 저장하는 것이기 때문에 직렬화를 해야 한다. 직렬화를 위해서는 데이터의 크기가 중요하다. 기본적으로 닷넷 환경에서는 값 타입(Value Type)과 참조 타입(Re ference Type)이라는 두 가지 타입이 있다. 값 타입은 int, char과 같이 실제 데이터가 직접 있는 타입이고, 참조 타입은 string과 같이 실제 데이터가 아닌 데이터의 주소가 들어 있는 타입을 말한다. 따라서 이들 데이터 타입에 따라 저장하는 방법도 달라진다. 값 타입은 대부분 고정된 길이를 가지고 있으므로 컴파일러가 알아서 그 크기를 계산할 수 있지만, 참조 타입의 경우 그 크기가 얼마나 될지 모른다. 그래서 하드디스크에 얼마 정도의 공간을 할당해야 하는지 모르는 것이다. 그래서 참조 타입을 직렬화하는 경우에는 사용자가 직접 그 방법을 정의해줘야 한다. 직렬화 방법을 정리해 보면 다음과 같이 3가지 방법이 있다.

◆ SerializedDataWithMetadata
값 타입이나 참조 타입에 관계없이 어떤 데이터 타입도 저장 가능. 하지만 성능 면에서는 가장 느리다. 아마 베타 3에서는 없어질 포맷이다. 한 마디로 사용하면 안 되는 포맷이다.

◆ Native
크기가 고정된 값 타입의 데이터 형만 저장 가능. 가장 빠르다.

◆ UserDefined
값 타입, 참조 타입 모두 사용가능. 하지만 사용자가 데이터를 읽는 방법과 쓰는 방법을 정의해줘야 한다.

앞의 세 가지 포맷 중 사용자 정의 포맷에서 읽기와 쓰기를 직접 구현하는 것은 간단하지가 않다. 약간 복잡하다. 이번 예제는 UDT를 소개하는 것이 목적이므로 Native 포맷을 이용하는 간단한 포인트 예제를 보여주려고 한다. 기존 CLREx 프로젝트에 새로운 아이템으로 Point라는 사용자 정의 데이터 타입을 추가해 보자. 그러면 기본적인 코드들이 생성되어 있을 것이다. 모두 지우자. 현재 템플릿에서 생성된 코드는 옛날 방식의 코드이다. 기본 구조는 다음과 같다.



이 메쏘드들을 채워주면 포인트 UDT가 완성된다. 앞의 가상코드를 보면 직렬화를 지원하고 Native 포맷으로 정의되어 있는 것을 볼 수 있을 것이다. 그리고 class가 아닌 struct로 선언한 것이 보일 것이다. 굳이 class가 아닌 struct를 쓴 이유는 전통적으로 사용자 정의 데이터 타입은 구조체를 썼기 때문이다. 그 이유는 클래스는 힙에 데이터가 저장되지만 구조체는 그렇지가 않다. 따라서 클래스는 가비지 콜렉터가 쉽게 수거해 갈 수 있지만 구조체는 그렇지 않다. 성능 면에서 구조체가 약간 더 빠르다는 것이다. 또한 NULL 값을 구현하는데 있어 구조체는 별도의 초기화 없이 기본적으로 모든 값을 기본 값으로 초기화해 준다.

예를 들면 숫자형은 모두 0으로 자동 초기화를 해준다. 그래서 데이터 형을 다루는 데에는 아무래도 클래스보다는 구조체가 약간 더 편하다고 할 수 있다. SQL 서버에서는 NULL이라는 값이 존재한다. 따라서 UDT를 만들 때에는 NULL이라는 의미를 부여해줘야 한다. 그래서 INullable 인터페이스를 상속받아서 NULL을 구현하고 있다.

포인트를 저장하기 위해서 x, y값을 위한 공간을 마련하고 널 값 체크를 위한 공간도 마련하였다. 그런데 사실 널 값 체크를 위해서 이와 같이 별도의 저장공간을 사용하는 것은 하드디스크 낭비가 될 수 있다. 그래서 어떤 사람들은 이와 같은 경우 Int32.MinValue를 널 값 대신으로 사용하기도 한다. 즉 Int32의 최소 값을 널 값으로 대신하는 것이다.

만약 포인트의 데이터형이 string형이면 이러한 불편이 없다. string형은 참조 타입이기 때문에 null이라는 값을 수용할 수 있기 때문이다. Int32라는 데이터형은 값 타입이기 때문에 NULL을 수용할 수가 없어 이와 같은 방법을 사용하였다. 어떤 방법을 사용하든 그것은 개발자의 몫이니 상황에 따라 적절한 방법을 사용하면 된다. 이번 예제에서는 하드디스크의 공간을 걱정 안 해도 되므로 그냥 따로 널 값 체크를 위한 데이터형을 따로 만들었다. 기본적인 메쏘드의 설명은 <표 1>과 같다.

실제 완성된 코드는 ‘이달의 디스켓’으로 제공하니 참고하기 바란다. 이제 이 UDT를 컴파일하고 배포하면 다음과 같이 테스트할 수 있다.


-----------------------------------------------------------------
null
10:20
100:110
127
SUM, MAX와 같은 집합 함수만으로는 더 이상 충분하지 않다

이번에 SQL 서버의 CLR 통합 기능 중에서 제일 반가운 것이 바로 이 기능이다. 기존에 MIN, MAX, SUM, COUNT, AVG 같은 집합 함수를 쓰다 보면 부족함을 느끼는 경우가 많다. 이러한 집합 함수가 있으면 좋을 것이라고 많은 사람들이 원했던 것이 사실이다. 이제는 이러한 집합 함수를 직접 만들어 쓸 수 있다. 만드는 방법은 UDT와 상당히 유사하다. 이번 예제에서는 최대 변이 값을 구하는 함수를 만들 것이다. 즉, 최대 값-최소 값을 구하는 MaxVariance라는 함수이다. 기존 프로젝트에 새로운 아이템으로 Aggregate를 추가하고 이미 있는 템플릿 코드는 역시 옛날 방식이므로 지운다. 기본 구조는 다음과 같다.



데이터 형이 값 타입 밖에 없으므로 Native 포맷으로 했으며, 최대 값과 최소 값을 저장하는 별도의 변수를 만들었다. 각 메쏘드별 설명은 <표 2>와 같다.

자세한 코드는 ‘이달의 디스켓’에 있으니 참고하기 바란다. 앞의 사용자 정의 집합(User-Defined Aggregate, UDA)을 컴파일하고 배포한 후 다음과 같은 코드로 테스트해 보자. 다음 코드는 전체 사원 중에서 휴가 시간이 가장 많은 사람과 가장 적은 사람의 차이를 나타낸 것이다.


-----------
99
(1 row(s) affected)
99
(1 row(s) affected)
앞뒤의 쿼리문을 대조해 보면 제대로 된 결과가 나왔음을 확인해 볼 수 있다.

클라이언트 ADO.NET의 개선점

이번에 ADO.NET 2.0으로 나오면서 SQL 서버와 관련해서 크게 주목할 부분은 두 가지가 있다. 하나는 비동기 호출기능과 하나의 연결로 다수의 커맨드를 실행하는 기능(Multiple Active Result Sets, MARS)이다. 지난 호에서 ADO.NET에서도 페이징 처리가 가능하다고 했는데, 그 기능이 이젠 없어질 예정이라서 이번에 제외했다.

더 이상 기다릴 필요 없는 비동기 호출

비동기 호출 기능은 기존에 쿼리 문장을 수행시키고 결과가 올 때까지 기다려야 했단 불편을 없애고 클라이언트는 결과가 올 때까지 나름대로의 작업을 할 수 있다. 그러므로 사용자는 쿼리 문장을 날리고 모래시계의 아이콘을 기다릴 필요 없이 다른 작업을 수행할 수도 있다. 이때 처음 DB에 연결을 맺을 때 비동기 호출을 쓴다는 표시를 “Asynchronous Processing=true”와 같이 해줘야 한다. 간단한 예제를 보자.




-----------------------------------------------------------------------------
작업 시작
******************
작업 끝
앞의 예제는 고객 데이터를 조회하는데 있어 비동기 호출을 이용하고 있다. 먼저 비동기 호출의 장점을 보려면 DB에서 시간이 오래 걸리는 작업을 돌려봐야 그 효과를 확실히 볼 수 있다. 그래서 2초간 딜레이를 주는 문장을 삽입하여 강제로 시간이 오래 걸리도록 하였다. 그리고 클라이언트는 결과가 올 때까지 계속 별을 찍다가 결과가 오면 끝내는 예제이다. 그런데 이번 예제에서는 간단히 하기 위해서 끝났는지 안 끝났는지를 알아보기 위하여 WHILE문에서 계속 체크를 하였지만, 실제 사용할 때에는 이렇게 할 필요 없이 비동기 콜백 함수를 만들어서 다 끝나면 저절로 그 함수가 호출되게 하는 것이 더 좋은 방법이 될 것이다.

하나의 연결로 다수의 쿼리 실행

기존 ADO.NET에서는 하나의 연결을 맺으면 하나의 커맨드만 실행 가능하였다. 그래서 다른 커맨드를 실행하려면 별도의 연결을 다시 맺어야만 했다. 하지만 이제는 하나의 연결로 다수의 커맨드를 실행할 수 있다. 이렇게 함으로써 매번 새로운 연결을 맺지 않아도 되므로 성능 향상이 있는 것이다. 구현하는 방법은 어렵지 않다. 그냥 쓰면 된다. 다음 예제를 보자.



-----------------------------------------------------------------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
.......
cmd1과 cmd2가 하나의 cnn이라는 연결을 공유해서 쓰고 있다. 전체 예제는 ‘이달의 디스켓’에 있다.

SQL 서버의 변신은 무죄?

처음에 SQL 서버가 닷넷 프레임워크(CLR)에 통합된다고 하였을 때 많은 사람들이 궁금증을 가지고 지켜보았다. 이제는 C#을 공부해야 하는가 하고 걱정하는 사람들도 있었다. 하지만 막상 뚜껑을 열어보니 CLR 통합이라는 기능은 T-SQL을 대체하는 기능이 아닌 좀 더 확장하고 보강하기 위한 기능으로 보는 것이 좋다는 결과가 나왔다. SQL 서버를 개발하는 데 있어 기본은 T-SQL이다. 하지만 거기서 멈추지 않고 더욱 새로운 기능을 추가하고 확장하고 싶다면 닷넷을 이용하면 된다. 다음 시간에서는 DB 관리 툴과 보안에 대해 소개하겠다.


제공 : DB포탈사이트 DBguide.net

출처 : 마이크로소프트웨어 [2005년 3월]
"MSSQL" 카테고리의 다른 글
  • 개발자를 위한 튜닝 가이드 (0)2007/05/25
  • DB 보호와 복구를 위한 새로운 모델 (0)2007/05/23
  • VS.NET으로 개발하는 SQL 서버 2005 (0)2007/05/23
  • SQL 서버 2005 관리자가 알아야 할 변화 (0)2007/05/22
  • SQL 서버 암호화 (0)2007/05/22
2007/05/23 09:15 2007/05/23 09:15
Posted by webdizen
Tags SQL Server 2005, VS.NET, 저장 프로시저
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3029

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/22 17:58

SQL 서버 2005 관리자가 알아야 할 변화

한용희│롯데정보통신 칠성IS 사업팀

SQL 서버 2005는 5년 만에 나온 제품인 만큼 엔진, 관리 툴, 보안에 많은 변화가 있다. 이번 호에서는 SQL 서버 2005 엔진의 새로운 변화, 그리고 대폭 바뀌고 개선된 관리 툴에 대한 소개와 향상된 보안 기능에 대해 알아볼 것이다.

운영체제 │ 윈도우 2000, 윈도우 2003, 윈도우 XP
개발도구 │ MS SQL 서버 2005 베타 2, 비주얼 스튜디오 2005 베타 1
기초지식 │ MS SQL 서버 2000, C#
응용분야 │ MS SQL 서버 2005 관리와 개발

앞서 두 달 동안 개발자 관점에서의 SQL 서버 2005의 모습을 살펴보았다. 이번 호부터는 관리자의 관점에서 바뀐 SQL 서버 2005의 새로운 모습을 소개할 것이다. 원래는 이 내용을 첫 회에 연재하려고 하였으나 지루할 것 같아 일단 당장 눈에 보이는 변화인 개발자 부문을 먼저 다뤘다. 이번 호에서는 SQL 서버 2005의 시스템에 대한 전반적인 부분부터 관리 툴에 대한 소개하고 보안 관련된 변화까지 알아볼 것이다.

4GB 메모리의 한계를 넘는 64비트 컴퓨팅 지원

현재 대부분 쓰이고 있는 32비트 프로세서는 기본적으로 메모리를 최대 4G(232)까지 지원한다. 그런데 DB 서버에서는 프로세서의 속도보다도 더 중요한 것이 바로 메모리 용량이다. 그래서 SQL 서버에서는 AWE(Address Windowing Extensions)를 이용하여 최대 32G까지 지원하고 있다. AWE는 가상의 메모리 공간을 마련하여 실제 물리적 메모리와 맵핑하는 방식으로 4G 이상의 메모리에 접근한다. 하지만 이는 가상 메모리와 물리적 메모리 사이에 변환이 필요하므로 오버헤드를 유발하기 때문에 직접 접근하는 것보다는 느리다.
64비트 프로세서를 사용하게 되면 이런 제약은 없어진다. 현재 SQL 서버 2005는 인텔 아이태니엄/제온(EMT64), AMD 옵테론/애슬론64와 같은 64비트 프로세서를 지원하기 때문에 이들을 이용하면 현재 상태에서는 512GB까지 메모리 확장이 가능하다. 따라서 CPU를 64비트 프로세서로 바꾸기만 해도 성능 개선 효과를 볼 수 있을 것이다.

사용자 삽입 이미지
<그림 1> 32비트와 64비트 메모리 어드레싱의 차이


최근에 2001OUTLET에서 SQL 서버 2000을 32비트에서 64비트로 마이그레이션한 뒤 성능 향상에 대한 사례 발표를 한 적이 있다. 관심 있는 독자는 참고 사이트(참고자료 ?)에서 확인해 볼 수 있다. 이 발표 내용 중 성능 향상에 대해 한 가지만 소개하면, 110GB의 테이블의 인덱스를 재생성하는 데 있어 기존에는 10시간 이상 걸리던 작업이 64비트 환경에서는 1시간 45분 만에 끝났다고 한다. 이러한 성능 향상에는 CPU를 교체한 것 이외에도 메모리, 스토리지를 업그레이드한 효과도 포함된 것이므로 단순 비교에는 무리가 있다.

효율적인 멀티프로세서 활용을 위한 NUMA 지원

일반적인 멀티프로세서 환경인 SMP(Symmetric MultiProcessing) 환경에서는 CPU와 메모리가 버스라는 통로를 통해 접근하므로 프로세서를 많이 달수록 버스 통로는 바빠지게 된다. 그러므로 프로세스를 많이 장착한다고 해서 반드시 프로세스를 정착한 개수만큼의 성능 개선 효과를 볼 수 없다. 그러나 NUMA(Non-Uniform Memory Access) 방식을 사용하면 이런 문제를 해결할 수 있다. NUMA는 윈도우 서버 2003에서 지원하는데, 이는 메모리와 CPU를 하나의 노드로 묶어서 전용의 로컬 메모리 공간을 확보하는 방식을 말한다. 따라서 각각의 노드들은 각각의 로컬 메모리를 가지고 있어서 로컬 메모리 내에서는 빠른 속도로 메모리 접근을 할 수 있다. 하지만 이 방식의 단점이라면 서로 다른 노드 사이에 메모리 접근을 하는 것은 외부 버스를 통해 접근해야 하므로 느릴 수밖에 없다. 그러므로 성능을 향상시키기 위한 핵심은 바로 이 노드들 사이의 메모리 접근을 줄이는 것이다. 그러기 위해서는 운영체제와 응용 프로그램간의 긴밀한 협조가 있어야만 한다. SQL 서버 2005는 이러한 NUMA를 적극 지원하여 크로스 노드 문제를 완화하고 있다.

사용자 삽입 이미지
<그림 2> SMP(Symmetric MultiProcessing)


사용자 삽입 이미지
<그림 3> NUMA(Non-Uniform Memory Access)



하나로 두 개의 CPU 성능을 구현하는 하이퍼쓰레딩 지원


하이퍼쓰레딩(hyper-threading)을 지원하는 인텔 CPU의 경우 하나의 CPU로 마치 두 개의 CPU가 동작하는 것처럼 흉내 낼 수 있다. 이를 이용하면 멀티쓰레드 애플리케이션이나 멀티 애플리케이션을 수행할 때 성능이 개선된다고 알려져 있다. 이를 이용하면 금전적인 면에서 절약을 할 수 있다. SQL 서버 라이선스 1-CPU를 구매하고 하이퍼쓰레딩을 이용하여 마치 두 개의 CPU를 돌리는 것과 같은 흉내를 낼 수 있다. 하지만 리얼 2-CPU보다는 성능이 떨어지므로 그리 권장할 만한 방법은 아니다.

향상된 멀티플 인스턴스 지원

기존에는 최대 16개까지 인스턴스를 지원했지만, SQL 서버 2005에서는 최대 50개까지 인스턴스를 지원한다.

멈추지 않는 운영을 위한 데이터베이스 미러링

데이터베이스의 안정적인 운영을 위해 기존에는 대부분 클러스터링을 구현해 사용했다. 하지만 클러스터링은 데이터베이스 자체 내에서 지원되는 기능이 아닌 외부에서 지원되는 기능이다. 그래서 SQL 서버 2005에서는 자체 내에서 이러한 기능을 지원하기 위해 미러링이라는 기능을 추가했다. 미러링은 클러스터링과 다르게 별도의 하드웨어가 필요 없으며, 별도의 공유 스토리지도 필요 없다. 또한 길이 제한도 없어서 멀리 떨어진 곳에서도 설치가 가능하다. 이는 primary 서버와 mirroring 서버 두 대를 구축하여 서로 트랜잭션 로그 정보를 주고받기 때문에 가능한 것이다. 이 가운데 watch 서버가 추가되어 primary 서버의 동작을 감시하다가 primary 서버가 다운되면 즉시 mirroring 서버로 교체시켜주는 방식으로 동작한다. 자세한 내용은 다음 호에서 다룰 예정이다.

간편한 이력 관리를 위한 데이터베이스 스냅샷

데이터베이스를 운영하다 보면 특정 시점의 데이터를 저장하고 싶을 때가 있다. 백업을 이용하면 되지만 시간이 오래 걸리고 대용량의 저장 공간이 필요하다는 단점이 있다. SQL 서버 2005에서는 이런 불편을 해소하기 위하여 데이터베이스 스냅샷 기능을 지원한다. 이는 특정 시점의 데이터를 쉽게 보관하고 복구하는 기능을 제공한다. 이 때 실제 전체 데이터를 모두 보관하는 것이 아니라 메타 데이터만 보관하기 때문에 부담이 없다. 이 역시 자세한 내용은 다음 호에서 다룰 예정이다.

IIS 없이 HTTP 지원

SQL 서버 2005에서는 웹 서비스와 같은 HTTP 요청을 IIS 없이도 스스로 할 수 있는 기능을 제공한다. 따라서 웹과 연동된 프로그래밍을 할 때 더욱 쉽게 개발할 수 있게 되었다. 이 점은 비주얼 스튜디오 2005에서도 지원하는 기능이기도 하다. 비주얼 스튜디오 2005에서도 ASP.NET 프로그램을 개발하는 데 있어 더 이상 IIS가 없어도 가능하기 때문이다.

근무시간에도 가능한 인덱스 재생성

기존 SQL 서버 2000의 경우 인덱스를 재생성하게 되면 재생성하는 동안에는 데이터를 갱신하지 못했다. 그래서 인덱스를 다시 만드는 경우 대부분 야근을 하는 것이 보통이었다. 하지만 이제는 그러지 않아도 된다. 실시간으로 인덱스를 재생성하면서도 데이터 갱신 작업이 가능하다. 어떻게 이 기능이 가능할까? 그것은 바로 두 개의 인덱스를 SQL 서버가 유지하기 때문이다. 즉, 하나는 기존의 인덱스를 그대로 유지하면서 온라인 작업이 가능하게 하고, 다른 하나의 인덱스는 재생성 작업을 하는 데 이용한다. 그러다가 인덱스 재생성 작업이 끝나면 기존 인덱스는 삭제하고 재생성된 인덱스를 붙이는 방식이다. 그런데 이 방법에는 두 개의 인덱스를 유지하는 데 따른 오버헤드가 있다. 그러므로 사용자는 온라인/오프라인을 선택해서 인덱싱 작업을 할 수 있다.
또한 기존에 클러스터드 인덱스를 재생성하는 경우, 넌클러스터드 인덱스까지 같이 재생성되는 문제점이 있었다. 이는 넌클러스터드 인덱스가 클러스터드 인덱스를 참조하기 때문에 어쩔 수 없는 현상이었다. 그래서 클러스터드 인덱스 한 번 바꾸려면 시간이 많이 걸려서 대용량 테이블의 경우 만만한 작업이 아니었다. 하지만 이제는 클러스터드 인덱스를 재생성한다고 해서 넌클러스터드 인덱스까지 영향을 주지 않는다.
그럼 온라인 인덱싱 기능을 직접 시험해 보자. 다음은 adventureworks 데이터베이스의 SalesOrderDetail 테이블의 인덱스를 재생성하는 구문이다. 이 테이블이 12만행이나 되기 때문에 이러한 작업을 테스트하기에 안성맞춤이다.

SELECT GETDATE();
ALTER INDEX ALL ON Sales.SalesOrderDetail REBUILD
WITH (ONLINE = ON);
SELECT GETDATE();

-----------------------
2005-03-12 16:06:35.110
(1 row(s) affected)

-----------------------
2005-03-12 16:06:43.913
(1 row(s) affected)
이 결과를 보면 SalesOrderDetail 테이블의 인덱스를 재생성하는 데 있어 WITH 옵션에 ON을 주어서 온라인으로 하고 시간은 35초에서 43초까지 약 8초가 걸렸다. 이 작업을 돌리는 것과 동시에 다음 데이터 갱신 작업을 하자.

UPDATE Sales.SalesOrderDetail
SET OrderQty = 10000
WHERE SalesOrderID = 43659;
SELECT GETDATE();

12 row(s) affected)
-----------------------
2005-03-12 16:06:39.677
(1 row(s) affected)
결과를 보면 39초에 갱신 작업이 끝났음을 알 수 있을 것이다. 인덱스를 재생성하는 동안에도 데이터 갱신 작업을 성공한 것이다. 그런데 만약 여기에서 ONLINE을 OFF로 했을 때의 시간은 얼마나 걸릴까? 실제 2~3초 밖에 걸리지 않는다. 즉, 인덱스를 두 개 만들지 않아도 되므로 그만큼 빠른 것이다.

온라인 복구 기능 지원

SQL 서버 2000에서는 데이터베이스가 복구되는 동안 사용자는 데이터베이스를 사용하지 못했다. 하지만 SQL 서버 2005에서는 부분 복구 기능을 지원한다. 한 예로 데이터베이스의 primary 파일 그룹이 복구되면 primary를 사용하는 데이터베이스는 사용이 가능하다. 나머지는 사용하면서 복구를 한다.

백업 미러링 지원

데이터를 백업할 때 하나의 테이프에만 백업을 했는데 만약 그 테이프에 오류가 생긴다면 난감할 수밖에 없다. 그럴 때에는 두 개의 테이프에 동시에 백업받는 것이 안전하다. SQL 서버 2005에서는 이러한 경우를 위해 백업 미러링을 지원한다. 즉, 테이프 1에 데이터를 백업하면서 동시에 테이프 2에도 백업을 하는 것이다. 그렇다고 시간이 두 배가 걸리는 것은 아니다. 미러링을 하기 때문에 더 추가하더라도 성능에 영향을 미치지 않는다. 단, 이 때 백업 장치는 동일한 장치이어야만 미러링이 가능하다. 다음은 미러링 백업 예제이다.

BACKUP DATABASE AdventureWorks
TO TAPE = '\\.\tape1'
MIRROR TO TAPE = '\\.\tape2'
WITH
FORMAT,
MEDIANAME = 'AdventureWorksSet1'
동시에 하는 데이터베이스 백업과 로그 백업

SQL 서버 2000에서의 로그 백업은 데이터베이스 백업이 끝난 후에나 가능했다. 하지만 SQL 서버 2005에서는 데이터베이스와 로그를 동시에 백업할 수 있다.

다운돼도 접속할 수 있는 관리자 전용 연결 기능

SQL 서버를 운영하다가 가끔 잘못되면 CPU 사용률이 거의 100%가 되는 경우가 발생할 수 있다. 이럴 경우에는 마우스도 움직이기 어렵다. 어떤 조치를 취하고 싶어도 마우스가 움직이지 않으니 어떻게 해 보지도 못하고 발만 동동 구르는 경우가 있다. SQL 서버 2005에서는 이런 경우, 관리자 전용 연결 기능(dedicated administrator connection) 기능을 이용하여 SQL 서버에 접속해 들어가서 문제를 해결할 수 있다. 이는 커맨드라인 유틸리티를 이용하는 것인데, 과거 OSQL을 대체하는 SQLCMD를 이용하면 된다. SQLCMD를 사용할 때 ‘-A’ 옵션을 주면 관리자 전용 연결로 들어 갈 수 있다. 명령 프롬프트에서 다음과 같이 실행해 보자.

C:\Documents and Settings\Administrator>sqlcmd -S localhost -E -A
1> USE adventureworks
2> go
Changed database context to 'AdventureWorks'.
1> select Name from Person.AddressType
2> go
Name
--------------------------------------------------
Archive
Billing
Home
Main Office
Primary
Shipping

(6 rows affected)
1>
이 예제는 로컬 SQL 서버(-S localhost)에 관리자 전용 연결(-A)을 신뢰된 연결(-E)로 접근하여 쿼리를 수행하는 모습이다.

익스체인지나 아웃룩이 필요 없는 메일링 기능

기존 SQLMail의 경우, 사용하려면 익스체인지와 아웃룩이 필요했다. 설치 또한 계정 문제가 얽혀 있어서 간단하지 않았다. 그래서 이번 SQL 서버 2005에서는 좀 더 편리한 SQLiMail을 지원한다. 이는 익스체인지나 아웃룩 없이도 SMTP 서버만 있으면 사용 가능한 메일링 기능이다. 이 기능은 현재는 기본적으로 설치되지 않고 관리자가 추가로 설치해야 한다. 방법은 두 가지가 있는데, 마법사를 이용하는 방법과 쿼리를 직접 이용해서 설치하는 방법이 있다. 쿼리를 이용하려면 다음과 같은 폴더에 스크립트가 있으니 이를 실행해서 설치하고 프로파일과 계정을 만들어서 연결시켜 주면 된다.

C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Install\Install_SQLiMail.sql
마법사를 이용하는 방법은 매니지먼트 스튜디오에서 매니지먼트에 부분에 보면 SQLiMail이라는 아이콘이 있다. 그 아이콘을 더블클릭하면 마법사가 실행된다.

사용자 삽입 이미지
<화면 1> SQLiMail 마법사


사용 방법은 기존과 비슷하다.

EXEC dbo.sendimail_sp
@profile_name = 'AdventureWorks Administrator',
@recipients = 'danw@Adventure-Works.com',
@body = '잘 도착했나요?',
@subject = '테스트 메일입니다.' ;
이와 같이 받을 사람을 지정하고 메일을 보내면 된다.

시스템 트레이에서 사라진 SQL 서버 서비스 관리자

SQL 서버 2000에서는 서비스 관리자가 시스템 트레이 아이콘으로 있어서 거기에서 관리했다. 하지만 이는 다른 MS 제품 대부분이 MMC(Microsoft Management Console)를 이용하여 관리하는 것과는 차이점이 있었다. 그래서 MS는 그런 트레이 아이콘을 없애고 MMC에 포함시켰다. 이제는 MMC 내에서 서비스를 시작하고 중지할 수가 있다. [제어판]-[관리도구]-[컴퓨터관리]에 가보면 SQL 컴퓨터 매니저가 있다.

사용자 삽입 이미지
<화면 2> SQL 서버 2000의 서비스 관리자


사용자 삽입 이미지
<화면 3> SQL 서버 2005의 SQL 컴퓨터 매니저


SQL 컴퓨터 매니저에서는 다음과 같은 서비스를 관리한다.

• SQL 서버
• SQL 서버 Agent
• SQL 서버 Analysis Services
• Report Server
• Microsoft Search
• Distributed Transaction Coordinator(DTC)
• Full Text Search

엔터프라이즈 관리자+쿼리 분석기 = SQL 서버 매니지먼트 스튜디오

맨 처음 SQL 서버 2005를 설치하면 쿼리 분석기를 찾지 못해 약간 당황할 수도 있다. SQL 서버 2005에서는 기존 DB 관리를 위한 엔터프라이즈 관리자와 스크립트 수행을 위한 쿼리 분석기가 SQL 서버 매니지먼트 스튜디오라는 이름으로 하나의 도구로 합쳐졌다.

사용자 삽입 이미지
<화면 4> SQL 서버 매니지먼트 스튜디오


<화면 4>를 보면 다양한 구성이 추가된 것을 볼 수 있다. 마치 비주얼 스튜디오를 연상하게 하는 구조처럼 변했다. 이 매니지먼트 스튜디오는 SQL 서버 2005 뿐만 아니라 SQL 서버 2000, SQL 서버 7까지 붙여서 관리할 수 있다. 이 매니지먼트 스튜디오의 가장 큰 변화라면 아마도 non-modal 기능일 것이다. 기존에는 EM(Enterprise Manager)에서 어떤 작업을 하기 위해서 창을 띄우면 그 창은 modal 창으로 떠서 그 작업이 다 끝날 때까지 기다려야만 했다. 하지만 매니지먼트 스튜디오에서는 non-modal 형식으로 창이 뜨기 때문에 동시에 다른 작업을 수행하는 것이 가능하다.
또 다른 변화로는 매니지먼트 스튜디오에서는 많은 수의 오브젝트를 다를 수 있다는 것이다. 기존 EM에서는 DB에 접속할 때 항상 모든 오브젝트를 한꺼번에 열거하기 때문에 오브젝트가 많을 경우에는 시간이 오래 걸렸다. 하지만 매니지먼트 스튜디오에서는 그 오브젝트를 브라우저에서 열기 전까지는 나열하지 않는다. 즉, 현재 필요한 정보만 읽어보고 필요에 따라 그때그때 정보를 읽어 오기 때문에 DB에 많은 오브젝트가 있더라도 접속하는 데 시간이 오래 걸리지 않는다.
<화면 4>를 보면 가운데 있는 것이 쿼리 편집기(query editor)이다. 쿼리 편집기가 기존 쿼리 분석기와는 달리 다수의 창을 열 경우 상단에 탭으로 표시된다. 기본에 별도의 창이 열려서 관리하기 불편했는데, 상단에 탭으로 표시되니 창을 관리하기가 쉬워졌다. 약간 불편한 점이라면 상단 탭의 제목이 너무 길어서 잘 보이지 않는다는 것이다. 이 쿼리 에디터에서는 T-SQL 뿐만 아니라 MDX, DMX, XMLA 등도 같이 실행이 가능하다.
<화면 4>의 우측에 보면 솔루션 탐색기(solution explorer)가 있는데, 이는 비주얼 스튜디오처럼 프로젝트를 관리할 수 있는 기능을 말한다. 다수의 SQL문을 하나의 프로젝트로 묶어서 관리가 가능하다. 또한 소스세이프도 지원하기 때문에 다수의 개발자가 동시 개발을 해도 소스 관리가 되며, 버전 컨트롤도 되기 때문에 앞으로 쿼리문 관리도 더욱 쉬워질 전망이다.
쿼리문을 이용해서 개발하다 보면 주로 반복되는 패턴들이 있다. 그래서 숙련된 개발자나 관리자들은 이러한 스크립트들을 별도로 모아서 관리하고 있다. 하지만 이제는 매니지먼트 스튜디오의 템플릿 탐색기(template explorer)와 보조 편집기(assisted editor)를 이용하면 이러한 반복되는 패턴들을 쉽게 이용할 수가 있다. 템플릿 탐색기는 자기만의 템플릿을 등록하거나 기존에 등록된 템플릿을 이용할 수 있으며, 보조 편집기는 SP, 트리거, 함수 같은 것들을 만들기 쉽게 도와주는 편집기이다.

사용자 삽입 이미지
<화면 5> 템플릿 탐색기 [View]-[Templete Explorer]


사용자 삽입 이미지
<화면 6> 보조 편집기 [SQL Instance]-[Databases]-[Programmability]-[Stored Procedures]-마우스 오른쪽 버튼-[New Stored Procedure]


튜닝의 조언자, 데이터베이스 튜닝 어드바이저

기존 인덱스 튜닝 마법사는 인덱스만을 튜닝하는데 도움을 주었다. 하지만 튜닝 어드바이저는 인덱스뿐만 아니라 파티셔닝과 같은 전반적인 데이터베이스 튜닝에 대한 조언을 해준다. 먼저 프로필러로 해당 DB를 추적한 다음에 이를 trc 파일로 저장을 한다. 이를 튜닝 어드바이저에서 불러와서 튜닝을 하면 어떻게 하라는 권고 사항을 알려준다. <화면 7>의 예제를 보면, 튜닝 어드바이저가 해당 테이블의 현재 인덱스를 삭제하라고 조언하고 있다.

사용자 삽입 이미지
<화면 7> Database Tuning Advisor


소유자와 사용자를 분리하는 스키마

SQL 서버 2000에서는 데이터베이스 오브젝트의 소유자가 사용자였다. 예를 들면 SQL 서버 2000에서 Northwind DB의 Products 테이블의 소유자는 dbo이다. Northwind뿐만 아니라 아마 대부분의 테이블 소유자는 모두 dbo로 되어 있을 것이다. 그 이유는 테이블의 소유자를 어떤 한 사용자로 두었다가 만약 그 사용자를 교체해야 한다면, 모든 데이터베이스 오브젝트의 소유자를 다 바꿔줘야 하는 불편이 있기 때문이다. 이는 애플리케이션 프로그램의 변경에도 영향을 미치는데 애플리케이션에서 해당 오브젝트를 사용하는 코드를 기술할 때 대부분 소유자를 명시하기 때문이다. 예를 들어

pubs.dbo.MyProc
이런 식으로 저장 프로시저를 호출해야 하기 때문에 소유자의 변경은 프로그램 전체를 다 변경해야 한다는 심각한 문제점이 발생한다. 그래서 대부분 그냥 소유자는 dbo로 통일해서 쓰는 경우가 많았다. SQL 서버 2005에서는 이러한 문제점을 개선하고자 스키마라는 개념을 확장했다. 데이터베이스의 오브젝트들을 묶어서 스키마라고 하고 사용자는 이 스키마를 소유할 수 있는 것이다.

사용자 삽입 이미지
<그림 4> 스키마 사용자 분리


그러므로 이제는 소유자가 바뀌더라도 해당 오브젝트들의 소유자를 모두 바꾸어 줄 필요가 없다. 단지 스키마의 소유자를 바꾸어 주면 되는 것이다. 직접 실습을 해보자. 먼저 3명의 로그인을 생성한다.

CREATE LOGIN LoginA WITH PASSWORD = '123';
CREATE LOGIN LoginB WITH PASSWORD = '123';
CREATE LOGIN LoginC WITH PASSWORD = '123';
그 다음 각각의 로그인에 맞는 사용자를 생성한다.

USE AdventureWorks;
CREATE USER UserA FOR LOGIN LoginA WITH DEFAULT_SCHEMA = Schema1;
CREATE USER UserB FOR LOGIN LoginB;
CREATE USER UserC FOR LOGIN LoginC;
이 때 UserA에만 기본 스키마로 Schema1이라는 것을 할당했다. 나머지는 명시를 하지 않았는데, 그러면 기본 스키마로 dbo가 할당된다. 이제 UserA에는 테이블 생성 권한을 주고, UserB에는 Schema1 스키마의 조회 권한을 주자.

GRANT CREATE TABLE to UserA;
GRANT SELECT on Schema::Schema1 TO UserB;
Schema1 스키마의 소유자를 UserA로 정하자.

CREATE SCHEMA Schema1 AUTHORIZATION UserA;
사용자 UserA로 변환한 다음 테이블을 생성한다.

SETUSER 'UserA';
CREATE TABLE Schema1.TestTable(id integer);
사용자 UserB로 변환한 다음 조회를 해보자. 잘된다.

SETUSER 'UserB';
SELECT * FROM Schema1.TestTable;
이제 Schema1의 소유자를 바꿔보자.

SETUSER;
ALTER AUTHORIZATION ON SCHEMA::[Schema1] TO [UserC];
다시 UserB에 조회 권한을 주고 조회해 보면 잘된다. 즉, 스키마의 소유자가 변하더라도 다른 곳을 수정하지 않아도 되는 것이다.

끊어진 소유권 체인도 연결 가능?

SQL 서버 2000에서 테이블과 저장 프로시저의 소유자가 같은 경우에는 전혀 권한 체크를 하지 않는다. 예를 들어 Table1과 저장 프로시저 Proc1(Proc1에서 Table1을 참조)의 소유자가 UserC라면 누구든 Proc1을 실행할 수 있는 사람이면 비록 Table1에 권한이 없더라도 Proc1을 통해 실행이 가능하다. 이를 소유권 체인(ownership chain)이라고 부른다.

사용자 삽입 이미지
<그림 5> SQL 서버 2000의 소유권 체인


하지만 저장 프로시저와 테이블의 소유자가 다른 경우 권한 체크를 하게 되며 권한이 없을 경우 에러를 발생시킨다. 예를 들면 Table2의 소유자가 UserD이고 Proc2(Proc2에서 Table2를 참조)의 소유자가 UserB라면 UserA가 UserB에 실행 권한이 있다고 하더라도 테이블과 저장 프로시저간의 소유자가 다르므로 권한 체크를 한다. 그러므로 Table2에 대해 UserA가 권한이 없다면 에러를 발생시킨다. 이를 끊어진 소유권 체인(broken ownership chain)이라고 한다. 이를 해결하기 위해 SQL 서버 2005에서는 WITH EXECUTE 구문을 제공한다.

사용자 삽입 이미지
<그림 6> SQL 서버 2005의 execution context



ALTER PROC UserB.Proc2 WITH EXECUTE AS 'UserZ'
이와 같이 실행을 하면 UserB.Proc2는 마치 UserZ가 실행하는 것처럼 가장하게 된다. 따라서 UserZ가 Table2에 대해 권한만 있다면 이 구문은 실행이 잘된다.

데이터를 보호하기 위한 암호화 메커니즘 제공

만약 데이터 중에 사용자 패스워드가 있다면 대부분 암호화하여 저장할 것이다. SQL 서버 2005에서는 이를 위해 인증(certificate), 대칭키(symmetric keys), 비대칭키(asymmetric keys) 등 세 가지 방식의 암호화 메커니즘을 제공한다. 사용자는 이 세 가지 중 한 가지를 선택하여 데이터를 암호화하여 보호할 수 있다.

CREATE CERTIFICATE Cert1
WITH SUBJECT = 'Test',
ENCRYPTION_PASSWORD = '123',
EXPIRY_DATE = '2010/12/31';

DECLARE @n nvarchar(100);
SET @n = EncryptByCert ( Cert_ID('Cert1'), N'ABC');

SELECT @n;

SELECT CAST ( DecryptByCert( Cert_ID('Cert1'), @n, N'123') as nvarchar);

------------------------------------------------------------------------------
붴?O????使?′졵???啣??얏??돻???손?蚓恩????듊???쟅?????쀁녥??艅?
(1 row(s) affected)

-----------------------------
ABC
(1 row(s) affected)
이 예제를 보면 인증 방식으로 암호화하는데 비밀번호는 123으로 했다. 암호화를 하니 그냥 조회해보면 알아볼 수 없는 값들이 나온다. 하지만 비밀번호를 이용하여 제대로 풀면 원래의 값을 조회할 수 있다.

SQL 서버 2005 관리자가 봐야 할 것들

이번 호에서는 SQL 서버 2005의 관리자라면 한 번쯤 봐야할 만한 내용들을 전체적으로 알아보고, 추가로 보안에 대한 내용을 소개했다. 마지막인 다음 호에서는 대용량 데이터를 다루기 위한 테이블 파티셔닝과 가용성(availability)을 높이기 위한 미러링과 스냅샷에 대해 소개할 예정이다.

익스체인지, 아웃룩 없이 SQL 서버 2000에서도 메일 보내기

사실 기존 SQL 서버 2000에서도 SQLMail을 사용하지 않고도 단순히 SMTP 서버와 CDOSYS 오브젝트만으로 메일을 보낼 수 있다. 다음 링크를 보면 자세한 내용이 나와 있다.

http://support.microsoft.com/default.as ··· 3B312839

저장 프로시저 소유자를 명시하지 않아 블로킹이 걸리는 경우

이전의 SQL 서버에서는 자신의 소유가 아닌 저장 프로시저를 호출할 때 소유자를 명시하지 않고 호출하는 것이 가능하다. 예를 들면 다음처럼 하는 것이다.

exec MyProc

그런데 이럴 경우 간혹 프로필러로 추적해 보면 캐시 부적중(cache miss)이 발생한다. 즉, 바로 재사용 가능한 실행 계획을 찾지 못하고 한 번 실패를 한 후에 컴파일 잠금을 하고 기존 실행 계획 중 재사용할 수 있는 것이 있는지 찾아본다. 그러다가 기존에 재사용 가능한 실행 계획이 있다는 것을 발견하고 재컴파일을 하지 않고 기존 실행 계획을 재사용하는 것이다. 이런 일련의 과정에서 문제가 되는 것은 바로 컴파일 잠금이 발생한다는 것이다. 대규모 사용자가 동시에 이 SP를 호출한다면 블로킹이 걸릴 수도 있는 것이다. 그러므로 소유자를 명시하는 것이 바람직한 방법이다. 자세한 내용은 다음을 참조하기 바란다.

http://support.microsoft.com/default.as ··· 3B263889
• 『고급 SQL 서버 개발자 가이드』 64쪽~65쪽(켄 헨더슨 저/ 하성희 역)

동의어 기능

SQL 서버 2005에서는 스키마명을 꼭 명시해 주어야 하기 때문에 이름이 길어져서 코딩하는데 약간 불편함이 있을 수 있다. 그럴 때에는 동의어 기능을 이용하면 코딩에 드는 노력을 줄일 수 있다.

CREATE SYNONYM Orders FOR Sales.SalesOrderHeader

이와 같이 지정을 하면 다음부터는 Sales.SalesOrderHeader라고 길게 치지 않아도 Orders라고 치면 된다. 하지만 이 방식은 코딩 노력을 줄여준다는 의미에서는 좋은 반면 가독성 측면에서는 좋지 않은 방법이 될 수도 있다. 왜냐하면 소스코드라는 것은 한군데 있으면 판독하기 쉽지만 여러 군데에 소스코드가 나누어져 있다면 판독하기가 쉽지 않기 때문이다.

참고자료

• http://member.microsoft.co.kr/technet/s ··· page%3D1
• SQL SERVER 2005 FOR DEVELOPERS - Microsoft Press
• A first Look at SQL Server 2005 for developers - Addison Wesley
• SQL Server 2005 New Features - McGrawHill Osborne

제공 : DB포탈사이트 DBguide.net
"MSSQL" 카테고리의 다른 글
  • DB 보호와 복구를 위한 새로운 모델 (0)2007/05/23
  • VS.NET으로 개발하는 SQL 서버 2005 (0)2007/05/23
  • SQL 서버 2005 관리자가 알아야 할 변화 (0)2007/05/22
  • SQL 서버 암호화 (0)2007/05/22
  • SQL 서버 2005, 그 변화 속으로 (0)2007/05/22
2007/05/22 17:58 2007/05/22 17:58
Posted by webdizen
Tags 64비트 컴퓨팅, NUMA, SQL Server 2005, 동의어, 미러링, 스냅샷, 암호화 매커니즘, 온라인 복구, 인덱스 재생성
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3027

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/22 16:55

SQL 서버 2005, 그 변화 속으로

정수현 | 동명정보대학교 정보기술원

마이크로소프트의 차세대 DBMS인 SQL 서버 2005가 그 모습을 드러내고 있다. SQL 서버 2000이 출시된 지로부터 5년이 지난 후에 출시되는 SQL 서버 2005. 닷넷과 통합된 모습을 보면 IT 엔지니어들도 개발과 관리를 아우르는 컨버전스를 해야 하는 시대란 생각이 든다. IT 컨버전스 시대에 우리도 해야 할 게 갈수록 늘어나고 있다는 것은 기뻐해야 할 일인지 슬퍼해야 할 일인지 모르지만, 이번 기사를 본 독자들은 하나는 느낄 수 있을 것이다. “닷넷을 해야 되겠군” 필수는 아니지만 SQL 서버 2005를 파워풀하게 사용하기 위해서는 어쩔 수 없는 일이 되었다. 누구의 말처럼 SQL 서버 2005를 스포츠카에 비유한다면 닷넷을 사용하지 않으면 스포츠카를 타고 시속 60km로 달리는 것과 마찬가지이기 때문이다.

코드명 ‘유콘(Yucon)’으로 명명됐던 마이크로소프트의 SQL 서버 2000의 차기 버전인 SQL 서버 2005에 대해 어떠한 개선이 이루어졌는지 또한 어떤 기능이 새로 추가되었는지 궁금하게 여기는 사람들이 많다. 현재 SQL 서버 2005는 베타2 이후 Commutiy Technology Preview까지 나와 있으며 필자도 CTP 버전을 가지고 이 기사를 작성하고 있다.
SQL 서버 2005는 CLR(Common Language Runtime) 통합, 새로운 통합 관리도구, 새로운 비즈니스 인텔리전스(이하 BI) 지원도구 등의 기능이 포함된 DBMS이다. 이것은 갈수록 높아지는 기업의 데이터베이스 활용 방향, 즉 데이터웨어하우스와 BI에 대응하기 위함이라고 볼 수 있다. 과연 SQL 서버 2005가 SQL 서버 2000까지 일부 개발자나 DBA에게 인식되던 한계점, 아직까지 대용량의 민감한 기업 환경에서 사용되기에는 약간 부족하다는 인식을 불식시킬 수 있을 것인지 이번 기사를 통하여 조금이나마 알아보기로 한다. 우선 SQL 서버 2005에 대한 설명은 개발적 측면, 관리적 측면 그리고 더욱 강화된 BI 기능으로 분류해서 진행하도록 하겠다.

SQL 서버 매니지먼트 스튜디오

SQL 서버 2005의 새로운 관리도구인 ‘SQL 서버 매니지먼트 스튜디오’는 이전 버전의 관리도구인 엔터프라이즈 매니저, Analysis Services를 통합하였다. 따라서 SQL 서버 매니지먼트 스튜디오는 자연히 많은 도구들의 종합세트처럼 되었는데 먼저 객체 익스플로러(Object Explorer)의 사용을 알아보자.
객체 익스플로러는 OLAP와 DTS, 리포팅 서비스(Reporting services), Notification Service와 보안관리, SQL 서버 에이전트, SQL 메일 등을 사용하게 하는 도구이다. 그리고 이전에 있던 데이터베이스 Maintenance Plan을 더욱 발전시켜 원래 있던 백업, 인덱스 관리 기능뿐만 아니라 DTS 디자이너를 데이터베이스 유지관리에도 포함시켰다.
또한 SQL 서버 매니지먼트 스튜디오 솔루션이라는 새로운 쿼리 실행도구가 추가되었다. 여기서는 마치 비주얼 스튜디오 닷넷을 사용할 때처럼 프로젝트 생성을 통하여 SQL 서버 스크립트나 MDX, DMX, XMLA 등을 생성하고 저장하게 하는 Analysis 스크립트, 그리고 모바일과 연동되는 SQL 쿼리를 생성하는 SQL 모바일 스크립트를 작성할 수 있다.

사용자 삽입 이미지
<화면 1> SQL 서버 매니지먼트 스튜디오에서 객체 브라우저를 사용하는 모습

사용자 삽입 이미지
<화면 2> SQL 서버 매니지먼트 스튜디오 솔루션 생성 장면


개발 측면의 개선사항

SQL 서버 2005에서는 개발자를 위한 지원으로 닷넷을 포함시켰다. 또한 SQL의 핵심인 Transact-SQL(이하 T-SQL)의 기능도 개선시켜 개발자들이 더욱 쉽게 데이터베이스 애플리케이션을 개발할 수 있게 하고 있다. 다음은 SQL 서버 2005에서 개선이 이루어지거나 새로이 추가된 개발자적 측면의 기능이다.

◆ SQL 서버 2005의 개선 사항과 개발자 측면의 추가된 기능

1. 닷넷 프레임워크 호스팅 : SQL 서버 2005에서 개발자는 비주얼 C# 닷넷이나 비주얼 베이직 닷넷(이하 VB.NET)과 같은 언어를 통하여 저장 프로시저, 사용자 정의 데이터 유형, 사용자정의 함수와 같은 데이터베이스 객체를 개발할 수 있다.

2. XML 기술 : XML(eXtensible Markup Language)은 네트워크나 인터넷을 통하여 이기종 데이터를 통합할 수 있는 언어이다. SQL 서버 2005는 XML 쿼리와 저장을 지원한다.

3. ADO.NET 버전 2.0 : ADO.NET은 SQL 서버 2005에 데이터세트를 액세스하고 조작하는 기능을 부여해준다.

4. 보안 개선 : SQL 서버 2005는 사용자와 객체를 분리하여 사용할 수 있게 한다. 이를 통하여 개발자는 객체에 대한 보안 관리를 보다 쉽게 할 수 있다.

5. 보안 개선 : SQL 서버 2005는 사용자와 객첼르ㅡ 분리하여 사용할 수 있게 한다. 이를 통하여 개발자는 객체에 대한 보안 관리를 보다 쉽게 할 수 있다.

6. T-SQL 개선 : SQL 서버의 핵심인 T-SQL도 개선이 이루어졌다. 에러 핸들링과 재귀 쿼리, 피봇(Pivot), APPLY, ROW_NUMBER 등의 개선이 이루어졌다.

7. 서비스 브로커 : 서비스 브로커(Service Broker)는 분산되고 비동기화된 애플리케이션간의 메시지 전달을 제공하는 새로운 기능이다.

8. 리포팅 서비스 : SQL 서버 2005의 리포팅 서비스는 비주얼 스튜디오 2005(코드명 Whidvey)와 함께 사용되는 리포팅 솔루션이다.

닷넷과 SQL 서버 2005

SQL 서버 2005에서 가장 중점을 둔 부분은 바로 VB.NET이나 C#과 같은 CLR 기반 언어를 이용하여 T-SQL이 취약했던 프로그램 객체 형성을 통한 복잡한 처리를 할 수 있게 해준다는 점이다. 이는 예전부터 여러 프로그래머들이 계속 요구해왔던 점으로서 SQL 서버 2005에서 이러한 요구를 수용하고 T-SQL을 더욱 발전시켰다고 볼 수 있다. SQL 서버 2005는 CLR과 통합되어서 어떤 데이터베이스 객체, 예를 들어 트리거, 프로시저, 사용자정의 함수, 사용자정의 형식 등을 닷넷 언어로서 정의하고 실행할 수 있다.
간단하게 CLR을 이용하는 닷넷 코드의 배포를 설명한다면 우선 개발자가 VB.NET이나 C#과 같은 언어를 이용하여 코드를 작성하고 나서 닷넷 컴파일러를 통하여 어셈블리를 만들고, 그 후에 Create Assembly와 같은 T-SQL 문장을 이용하여 SQL 서버에 등록하면 되는 것이다.
그러면 지금부터 간단하게 저장 프로시저를 C# 코드를 이용하여 생성하고 이를 적용하는 장면을 보자. 필자는 이를 위하여 SQL 서버 2005 Community Preview 버전과 비주얼 스튜디오 닷넷 2005 Community Preview를 사용했다.

사용자 삽입 이미지
<화면 3> VS.NET 2005에서 C#으로 저장 프로시저 작성




예를 들어 특정 데이터베이스의 쿼리 결과를 XML 형태로 파일에 저장하게 하는 저장 프로시저를 작성해보자. 이를 위해서는 우선 <화면 3>처럼 비주얼 스튜디오 닷넷 2005를 이용하여 저장 프로시저를 작성하는 프로젝트를 작성하기로 한다. C# 코드로서 데이터를 XML에 저장하는 코드를 작성한다.




이렇게 작성한 다음 이것을 빌드한다. 다음은 SQL 서버 매니지먼트 스튜디오에서 작성하는 것이다. 여기서는 AdventureWorks라는 데이터베이스를 이용하는 것으로 한다. 참고로 AdventureWorks는 SQL 서버 2005를 설치하면 기본으로 생성되는 예제 데이터베이스이다.




앞의 코드에서 보는 바와 같이 Create Assembly를 이용하여 VS.NET에서 생성한 어셈블리를 등록하고 이를 프로시저에서 사용하도록 지정해 주면 된다. SaveXML 프로시저를 이용하면 다음과 같이 테스트할 수 있다. 특히 SQL 서버에서 CLR을 사용할 수 있게 하려면 다음과 같이 SQL 서버 옵션을 정해주면 된다.



사용자 삽입 이미지
<화면 4> 저장 프로시저의 결과물인 XML파일

T-SQL 개선

T-SQL 부분에서는 피봇과 언피봇(Unpivot) 기능 지원, CTE(Common Table Expression), 재귀 쿼리 기능 등이 추가되었다. 이 기사에서 이런 기능들의 상세 부분을 알아볼 수는 없고, 피봇과 언피봇 정도만 살펴보기로 하겠다.

사용자 삽입 이미지
<그림 1> T-SQL의 피봇, 언피봇 연산


SQL 서버 2005에서는 피봇 연산자를 사용하여 행을 컬럼으로 변환하거나 이에 따른 집계도 할 수 있다. 예를 들어 주문 테이블에서 고객이 주문한 생산자와 주문한 수량을 알고 싶으면 피봇 연산자를 사용하여 원하는 생산자를 지정하면 된다.




만약 반대로 컬럼들을 행으로 변환시키려면 언피봇을 수행하면 된다.



이전 버전에서는 이러한 결과를 얻기 위해서는 좀 더 복잡한 연산을 해야만 했지만 이제는 한결 간편해졌다는 것을 알 수 있다.

SQL 서버 2005의 관리적 측면

지금부터는 SQL 서버 2005에서 관리 측면에서의 이루어진 개선점과 새로운 기능을 간략히 설명하겠다. 관리적 측면에서는 우선 데이터베이스 미러링과 온라인 복구 기능이 눈에 띈다. 이 기능으로 SQL 서버 2005에서는 한층 가용성이 높아지게 되었다. 또한 SQL 서버 매니지먼트 스튜디오라는 도구를 제공하여 Query Analyzer, 엔터프라이즈 매니저 등으로 분산 사용되던 관리도구를 통합하여 관리자가 더욱 쉽게 데이터베이스 시스템을 관리할 수 있게 하고 있다. 다음은 SQL 서버의 관리적 측면에서의 개선되거나 추가된 기능이다.

◆ SQL 서버 2005의 관리적 측면

1. 데이터 미러링 : SQL 서버 2000의 로그 전달 기능을 더욱 개선시킨 데이터베이스 미러링 기능을 추가했다. 미러링 기능으로 대기 서버의 자동 복구 기능을 활용할 수 있다.

2. 온라인 복구 : SQL 서버 2005에서는 데이터베이스가 온라인 상태에서도 복구 가능하다. SQL 서버 2000에서는 온라인 상태에서의 데이터베이스 복구는 가능하지 않았다.

3. 온라인 인덱싱 작업 : 인덱싱 작업 중에도 업데이트, 삭제, 삽입과 같은 데이터 수정 작업이 가능하다. 예를 들어 클러스터 인덱스를 작성하거나, 재작성하는 중에 데이터의 업데이트가 가능하다는 말이다.

4. 개선된 보안 : SQL 서버 2005는 보안에서의 개선점을 이루어냈다. 예를 들어 로그인 암호정책 사용이나 소유주와 스키마 분리 등의 기능이 추가되었다.

5. SQL 서버 매니지먼트 스튜디오 : SQL 서버 매니지먼트 스튜디오라는 통합 관리 도구가 등장했다. 이 도구를 통해 개발자와 관리자는 T-SQL 작성, 백업, 프로필러 사용, 각종 마법사 사용 등을 할 수 있다.

6. 관리자 전용 연결(Dedicated Administrator Connection) : SQL 서버 2005에서는 관리자에게 전용 관리 연결을 제공한다. 이것은 데이터베이스가 어떤 이유에서 잠겨 있더라도 관리자의 관리 활동을 위해 전용 연결 접속을 계속할 수 있게 하는 기능이다.

7. 스냅샷 격리 : 스냅샷 격리는 데이터베이스 레벨에서 제공하는 새로운 트랜잭션 격리 수준이다. 스냅샷 격리를 통하여 사용자는 쓰기 중인 데이터에도 접근하여 조회할 수 있다.

8. 데이터 파티셔닝 : 데이터 파티셔닝을 통하여 대용량의 테이블이나 인덱스를 효율적으로 관리할 수 있게 한다.

9. 복제 개선 : 분산 데이터를 위한 기능으로 SQL 서버에서는 오라클에서 SQL 서버로 복제하는 데이터를 https를 통하여 가능하게 했다. 추가적으로 일대일 트랜잭션 복제 기능을 더욱 개선시켰다.

데이터베이스 미러링

SQL 서버 2005의 관리적 측면에서 가장 강조하는 개선점은 데이터베이스 미러링 기능이다. 데이터베이스 미러링 기능은 이전 버전에서의 로그 전달 기능을 더욱 개선시킨 것이다. 데이터베이스 미러링을 이용하여 원본 서버의 트랜잭션 로그를 스트리밍으로 대상 서버에 전달하고, 이를 대상 서버에서 적용시켜 원본 서버 장애시 신속한 대체를 할 수 있게 한다. 데이터베이스 미러링을 구현하려면 3대의 SQL 서버가 필요한데, 각 서버는 ‘Principal’, ‘’Mirror’, ‘witness’라는 각각의 역할을 구성하게 된다.

사용자 삽입 이미지
<그림 2> 데이터베이스 미러링 개요도


우선 원본(Principal) 서버는 트랜잭션이 수행되는 서버를 말하며, 미러링 서버는 트랜잭션 로그가 동기화되어 적용될 대상 서버를 말한다. 미러링 서버에서 사용자는 바로 데이터를 읽을 수는 없다. 트랜잭션 로그는 원본 서버에서 생성되어 미러링 서버로 지속적으로 전달되어 적용된다. 이렇게 하면 결과적으로 거의 동시에 서버는 복제되는 데이터를 갖게 되는 것이다. 목격자(Witness) 서버는 원본 서버와 미러링 서버 사이에서 감시 역할을 수행하고 있는 서버라고 보면 된다. 만약에 원본 서버에 장애가 발행한다면 목격자 서버는 자동으로 미러링 서버로 하여금 장애복구를 수행하게 한다. 무엇보다 데이터베이스 미러링의 장점은 지연시간이 거의 없이 서버의 장애복구를 수행하게 하는 점이라고 할 수 있다.

스냅샷 격리

스냅샷 격리(Snapshot Isolation)는 SQL 서버 2005에서 새롭게 추가된 트랜잭션 격리 레벨이다. 스냅샷 격리를 이용하면 데이터에 쓰기 작업을 하고 있더라도 데이터를 읽을 수 있게 된다. SQL 서버 2000에서는 쓰기 작업 중인 데이터에는 자동적으로 Exclusive Lock이 걸리게 되어 해당 데이터를 다른 사용자가 읽을 수 없게 되어 있었다. SQL 서버 2005에서는 스냅샷 격리가 시행되고 있는 데이터의 쓰기 작업이 된 데이터를 tempd에 위치시키고 이를 읽게 하는 방식으로 스냅샷 격리를 수행한다.
물론 기본으로 스냅샷 격리가 해당 서버에서 실행되는 것은 아니다. 이것은 데이터베이스 옵션을 바꾸어서 실행하게 할 수 있다. 예를 들어 Adventure Works라는 데이터베이스에서 스냅샷 격리를 사용하게 하려면 다음과 같이 데이터베이스 옵션을 바꾸면 된다.




앞의 문장처럼 하면 데이터베이스 레벨에 적용되는 것이지만 이것을 해당 연결 세션에만 적용하고 싶으면 다음과 같이 해서 적용한다.



SQL 서버를 조금만 공부해본 사용자라면 앞의 두 문장의 형태가 눈에 익을 것이다.

SQL 서버 2005 보안

SQL 서버 2005에서 가장 큰 보안상의 변화는 사용자 스키마 분리 기능이다. 데이터베이스에서 하나의 스키마에 두 개의 테이블 이름이 같다면 이것은 절대 같이 있을 수 없다. 하나의 스키마에서 객체는 반드시 이름이 구분되어야만 한다. 예를 들어 SQL 서버에서 테이블을 만들게 되면 자연히 만들 때의 사용자가 소유주가 된다. 대부분 우리는 DBO 사용자 권한으로 테이블을 만들게 되고, 이렇게 되면 dbo가 소유주인 테이블, 즉 dbo.tablename으로 이루어지고 이를 좀 더 구체적으로 서술하면 servername.dbname.dbo.tablename이라는 형태로 구성된다. 이렇게 하면 데이터베이스를 액세스하는 사용자들은 모두 쿼리를 할 때 dbo 스키마를 기본으로 사용한다.

사용자 삽입 이미지
<그림 3> SQL 서버 보안 아키텍처


예를 들어 <그림 4>를 보자. 일반적인 사용자들은 dbo 스키마를 기본 스키마로 하기 때문에 Select * From orders라고 질의했을 경우에 자연적으로 Select * From servername.dbname.dbo.table라는 문맥으로 실행된다. 항상 dbo를 기본 스키마로 사용하는 것이다.

사용자 삽입 이미지
<그림 4> 사용자 스키마 분석



그렇지만 Ted라는 사용자를 생성하여 그 사용자에게 디폴트 스키마로 sales를 정해주면 Ted가 조회하는 스키마는 기본적으로 Select * From orders라고 하면 Select * From servername.dbname. dbo.orders가 된다. 우선은 sales라는 스키마를 만들어서 이 스키마에 테이블을 만들어 주게 된다.



다음은 Ted의 기본 스키마로 sales를 지정하는 구문이다.



이렇게 하면 Ted의 기본 스키마는 sales가 되고 Ted는 특별하게 dbo.orders라고 명시하지 않는 이상은 sales.orders를 조회하게 된다.
그리고 SQL 서버 2005에서는 로그인 계정을 생성할 때 윈도우의 계정 정책을 적용할 수 있게 되었다. 이는 이전버전까지의 SQL 로그인이 특별한 계정 암호에 대한 제한이 없어 비교적 간단한 암호를 설정할 수도 있었기 때문에 추가된 기능이다. 예를 들어 Tom이라는 새로운 로그인을 만들어 보자.



앞의 구문을 실행하면 Tom이라는 로그인이 만들어지고, 기본 데이터베이스로 AdventureWorks가 지정된다. 그런 후 만들어진 계정에 암호를 주고, 윈도우에서 사용하는 암호정책을 적용하는 구문을 실행할 수 있다.



이와 같이 실행하면 Tom에게는 윈도우의 암호 만료 기간과 암호정책이 적용되어 사용된다.

비즈니스 인텔리전스 측면

갈수록 요구사항이 증가되는 기업의 BI 솔루션에 대하여 SQL 서버 2000에서는 Analysis 서비스와 리포팅 서비스를 통하여 이에 대한 솔루션을 제공하고 있다. 다음은 SQL 서버 2005에서 제공하는 주요 BI 솔루션 기능이다.

◆ SQL 서버 2005에서 제공하는 주요 BI 솔루션 기능

1. Analysis Services : SQL 서버 2005에서 Anaysis 서비스는 BI 솔루션 개발을 위한 확장된 기능을 제공하고 있다.

2. Business Intelligence development Studio : 새로이 추가된 도구이다. 이 도구를 사용하여 개발자는 큐브, 차원, 마이닝 구조 등의 Analysis 구성요소를 개발할 수 있다.

3. DTS(Data Transformation Services) : 네이티브 코드와 관리되는 코드에 대한 지원이 추가되어 더욱 용이하게 DTS를 디자인할 수 있다.

4. 데이터 마이닝 : 4개의 새로운 마이닝 알고리즘이 추가되어 대용량의 데이터에서 더욱 쉽게 데이터를 마이닝할 수 있게 되었다.

5. 리포팅 서비스 : 리포팅 서비스를 이용하여 OLAP 등의 데이터를 사용자에게 용이하게 리포팅할 수 있는 기능이 추가되었다. 리포팅 서비스는 원래 SQL 서버 2005에 처음 탑재될 예정이었으나 앞당겨서 SQL 서버 2000에서도 사용할 수 있게 출시된 상태다.

6. Clustering Support : Analysis 서비스에서도 장애 복구 클러스터링을 이용하여 고가용성을 보장하게 되었다.

사용자 삽입 이미지
<화면 5> Business Intelligence Development Studio 를 통하여 BI 솔루션을 생성하는 장면


BI 측면에서 SQL 서버 2005의 눈에 띄는 사항을 보면 ‘Business Intelligence Development Studio’라는 새로운 통합 개발 환경을 제공한다는 점이다. 이 도구를 이용하여 BI 개발자는 큐브를 생성하거나 데이터 원본에 대한 뷰, 리포트, 변환 패키지 등을 생성할 수 있게 되었다. 이전 버전에서는 ‘Analysis Services manager’라는 도구에서 단순히 큐브나 차원 등을 생성하고 이를 DTS 등과 통합해서 사용해야만 했었다.
BI Development Studio는 4개의 윈도우를 사용하는데, 먼저 솔루션 탐색기에서 객체에 대한 뷰나 디자인을 볼 수 있게 한다. Tool Box Window는 사용 가능한 BI 프로젝트의 각종 컨트롤 목록을 보게 한다.
그리고 Business Intelligence Development Studio에서는 Analysis 서비스, Data Transformation 서비스, 그리고 리포팅 서비스 등의 3개의 프로젝트를 생성할 수 있게 한다.

“개발과 관리도 컨버전스로 간다”

SQL 서버 2005를 보면 갈수록 개발자와 DBA가 통합되어 가고 있다는 점을 느낄 수 있다. 예를 들면 Business Intellience Studio라든지 SQL 서버 매니지먼트 스튜디오라는 통합도구만 봐도 그렇다. 마치 2002 월드컵 당시에 히딩크가 중시했던 멀티플레이어의 존재가 SQL 서버에서도 중시된다는 생각이 든다. 개발자와 관리자가 따로 담당하던 영역이 갈수록 융합되고 개발과 관리를 다 전문적인 지식으로 무장해야 SQL 서버를 제대로 다룰 수 있기 때문이다.
이는 필자가 생각하기에 요즘의 IT 흐름과 일맥상통한다. 가전제품에서만 디지털 컨버전스가 이루어지고 있는 것이 아니라, IT 엔지니어들도 개발과 관리를 아우르는 컨버전스를 해야 하는 시대이기 때문이다. IT 컨버전스 시대에 우리도 해야 할 게 갈수록 늘어나고 있다는 것은 기뻐해야 할 일인지 슬퍼해야 할 일인지 모르지만, 이번 기사를 본 독자들은 하나는 느낄 수 있을 것이다. “닷넷을 해야 되겠군”
필수는 아니지만 SQL 서버 2005를 파워풀하게 사용하기 위해서는 어쩔 수 없는 일이 되었다. 누구의 말처럼 SQL 서버 2005를 스포츠카에 비유한다면 닷넷을 사용하지 않으면 스포츠카를 타고 시속 60km로 달리는 것과 마찬가지이기 때문이다.


제공 : DB포탈사이트 DBguide.net

출처 : 마이크로소프트웨어 [2004년 12월호]
"MSSQL" 카테고리의 다른 글
  • SQL 서버 2005 관리자가 알아야 할 변화 (0)2007/05/22
  • SQL 서버 암호화 (0)2007/05/22
  • SQL 서버 2005, 그 변화 속으로 (0)2007/05/22
  • SQL Server를 실행하는 컴퓨터 간에 데이터베이스... (0)2007/05/22
  • 데이터베이스 아키텍처: 저장소 엔진 (0)2007/05/22
2007/05/22 16:55 2007/05/22 16:55
Posted by webdizen
Tags SQL Server 2005, T-SQL, 미러링, 스냅샷 격리
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3025

Leave your greetings.

[로그인][오픈아이디란?]

Database/MSSQL2007/05/21 09:37

SQL 서버 2005 보안

사용자 스키마 분리를 통한 보다 쉬운 관리

Kalen Delaney

최근에 필자는 SQL 서버 2000의 보안에 대해 다루어왔다. 지난3월호 기사, “선을 넘기: 소유권 체인” 에서 데이터베이스간 소유권 체인의 상속에 대한 추가적인 보안과 그 한계에 대해 이야기 한 바 있다. 또 5월호 기사 “개체 소유권과 보안” 에서는 SQL 서버 2000의 모델, 즉 사용자와 스키마의 개념을 분리하지 못한 모델을 둘러싼 한계와 혼란에 대해 다루었다. 이 달에는, SQL 서버 2005, 즉 코드명 유콘에서 이런 문제를 해결하는 향상된 보안에 대해 살펴보도록 하자.
마이크로소프트는 SQL 서버 2005의 주요 초점을 보안에 맞추었고, 이전 버전에서 취약했거나 불완전했던 보안의 측면들을 많이 향상시켰다. SQL 서버 2005에서 가장 중요한 보안의 변화는 박스에서 바로 꺼낸 상태에서도 안전하다는 것이다. 즉, SQL 서버를 디폴트 옵션 그대로 설치한다고 하더라도 말이다. 뿐만 아니라 지난 달 필자가 언급했던 스키마라는 용어가 새로 생겼는데 이에 대해서 지난달 보안 기사에서 인증과 허가(authentication and authorization) 의 개념에 대해 다루었다. 이런 새로운 개념들은 SQL 서버 2005의 보안 모델에 대한 기반을 제공 한다.
스키마라는 것은 개발자들이 데이터베이스 개체를 만들 때 담아두는 그릇으로 생각할 수 있다. SQL 서버 2005 에서 개체라는 것을 언급할 때는 개체를 담고 있는 스키마에 대해 언급하게 되지, 개체의 소유자에 대해 언급하는 것이 아니다. 인증(authentication)이란 SQL 서버 에 의해 주어진 정체(identity)가 접근하고자 하는 자원에 타당하거나 타당치 않다고 인정 받는 과정이다.

프로그래밍 가능한 모듈의 수행 문맥(context)

소유권 체인은 한 사용자(예를 들어 user1)가 다른 사용자(예: user2)의 개체에 대해 접근할 때 SQL 서버 가 자동으로 이를 인증해 주는 것이다. 예를 들어, user1이 user2가 소유한 프로그래밍 가능한 모듈, 즉 함수나 저장 프로시저에 대해 수행하고자 할 때 나타난다. 그러나, 소유권 체인의 메커니즘을 떠나서, SQL 서버 2000은 의존하는 개체에 액세스 하는 동안 사용자 인증을 제어할 수 있는 방법이 없었다. 사용자는 모듈을 항상 그 자신으로서만 수행하고, 의존하는 모듈에 대해 다음 두 조건 중 하나가 참일 때 만 접근할 수 있었다.

1. 의존 하는 모듈이 그 모듈의 소유자와 동일한 소유자를 가질 때
2. 그 모듈을 실행하는 사용자가 명백하게 접근하려는 모듈에 대해 권한을 가질 때

SQL 서버 2005 는 저장 프로시저와 사용자 정의 함수(인라인 테이블 함수를 제외한)를 실행하는 문맥(context)를 정의할 능력을 EXECUTE AS 절을 통해 제공해 주며, EXECUTE AS 절은 해당 모듈의 제일 머리에 두면 된다. 이 능력은 응용프로그램 개발자에게 보다 나은 제어를 할 수 있게 해주는데, 이를 통해 개발자들은 어떤 사용자가 다른 사용자의 인증으로 인증되었더라도 하나의 모듈에서 작업을 할 수 있게 해 줄 수 있다.
EXECUTE AS 는 모듈이 동적 SQL 을 사용할 때 유용할 수 있다. SQL 서버 2000은 항상 실행하는 모든 동적 문장에 대해 권한을 점검하는데, 앞서의 첫 번째 조건을 무시하게 된다.(즉 소유권 체인이 전혀 적용되지 않는다.) 만약 프로시저 호출자가 동적 SQL문장에서 참조하는 개체에 대해 권한을 가지고 있지 못하다면, 그 동적 SQL문은 실행되지 못한다. 그러나, SQL 서버 2005에서는, 사용자가 동적 SQL 문을 포함하는 프로시저를 만들었을 때도 실행된다. SQL 서버 2005베타2에서는 EXECUTE AS 절은 인증에 대해 세가지 가능한 옵션을 가진다: CALLER (디폴트), USER = user_name, SELF 가 그 것이다.
EXECUTE AS CALLER. EXECUTE AS CALLER는 디폴트 동작인데, SQL 서버 2000과 호환성을 보장한다. 모듈 안의 문장이 수행될 때는, 호출자의 문맥에서 수행된다. 그러므로, 해당 루틴을 수행하는 사용자는 반드시 해당 루틴(모듈)에 대한 권한 뿐만 아니라 참조하는 데이터베이스 개체에 대해 권한을 가지고 있어야 한다. 권한은 명백하게 해당 개체에 대해 주어져 있거나, 아니면 소유권 체인에 의해 내재될 수도 있다. 후자의 경우, SQL 서버 2005는 호출하는 개체와 참조되는 개체의 소유권 체인을 조사함으로써, 참조되는 개체의 권한을 평가하며 이것은 마치 이전의 SQL 서버 2000이 하는 방식과 같다. 그러나 SQL 서버 2005에서 개체는 소유자를 가지지 않는다는 것을 명심하자. 스키마가 소유자와 개체를 가지고 있다.
EXECUTE AS USER = user_name. EXECUTE AS USER = user_name을 지정하면 지정된 user_name의 문맥에서 루틴이 수행된다. SQL 서버 는 먼저 사용자가 수행하고자 하는 루틴에 대해 EXECUTE 권한이 있는지 검사하고 해당 user_name이 참조하는 모듈에 대해 권한이 있는지 검사한다. 하지만 모듈을 수행할 때 사용할 사람을 아무나 제멋대로 선택할 수는 없다. 특정 이름을 지정하기 위해서는 특별한 권한(예를 들어 IMPERSONATE)이 필요하거나 특별한 역할(sysadmin 또는 db_owner)의 구성원이 되어야 한다.
사용자 Susan이 자신이 소유한 자신의 기본 스키마에 프로시저를 만들었고 그것이 그녀가 소유하지 않은 다른 스키마(JoeSchema) 의 테이블을 참조한다고 해 보자. (Susan은 JoeSchema가 그녀가 소유하지 않은 스키마라면 JoeSchema에 대해 프로시저를 만들 권한이 있어야만 한다.) 하지만 JoeSchema의 테이블에 대해 Mary 가 SELECT 권한을 가질 수 있다고 하자. 이럴 때 Susan은 EXECUTE AS USER = Mary 라는 절을 CREATE PROCEDURE 문에 다음과 같이 추가할 수 있다:



이렇게 하면 Susan은 그 프로시저에 대한 EXECUTE 권한을 사용자 Scott에게 줄 수 있다. Scott이 이 프로시저를 실행할 때 SQL 서버 는 그가 프로시저를 실행 할 권한이 있는 지 검사하지만 참조하는 테이블에 대해서는 Mary의 권한을 검사한다. 이 시나리오에서는 Scott 이 테이블에 대한 SELECT 권한을 직접 가지지는 못했지만 프로시저를 통해 테이블에 접근할 수 있는데, 프로시저는 Mary의 문맥에서 수행되며 Mary 는 테이블에 대해 접근 가능하기 때문이다.
EXECUTE AS SELF. EXECUTE AS SELF 는 "이 모듈을 만들거나 변경하는 사용자로서 수행” 한다는 의미이다. EXECUTE AS SELF 는 지정된 사용자가 그 루틴을 만들거나 변경하는 사용자와 동일하다면 EXECUTE AS USER = user_name과 동일하다. 카탈로그에는 SELF 라는 값이 아니라 그 사용자의 user ID (UID)가 저장된다.
사용자 SELF 가 개체의 소유자일 필요는 없다는 것을 명심하자. SQL 서버 2005에서 개체는 실제로 소유자라는 것을 갖지 않지만 스키마 소유자가 그 스키마의 모든 개체의 소유자라고 생각할 수 있다. 사용자들은 그들이 소유하지 않은 스키마에서 개체를 생성할 권한을 가질 수 있다. 예를 들어 Susan이 Joe 가 소유한 스키마에서 ALTER SCHEMA 권한을 가질 수도 있다. 만약 Susan 이 Joe의 스키마에서 테이블 생성 권한을 가진다면 Joe 는 소유자이고 Susan 은 생성자가 된다. Susan 이 만든 어떤 프로시저든 EXECUTE AS SELF 는 Susan의 문맥에서 수행된다.

어떤 옵션을 선택할까?

이런 새로운 사양은 이해하는데 약간의 시간이 걸릴지 모르기 때문에 여기서는 어떤 EXECUTE AS 옵션을 어떤 상황에서 써야 하는지에 대한 약간의 가이드 라인을 제시하고자 한다. EXECUTE AS CALLER 는 다음과 같은 상황에서 사용하자:

* 루틴에서 수행하고자 하는 문장이 호출자의 문맥에서 수행되기를 원할 때
* SQL 서버 가 루틴의 해당 문장에 대한 권한 점검을 의존하는 개체의 권한 검사를 통과하는(하지 않는) 소유권 체인에 근거하여 수행되기 원할 때
* 같은 소유자가 가진 스키마에 있는 개체만 참조하기 때문에 의존하는 개체에 대한 접근을 소유권 체인에 근거하여 판단되기 원할 때
EXECUTE AS USER = user_name 은 다음과 같은 상황에서 사용하자.
* 특정한 사용자의 문맥에서 해당 문장이 수행되기 원할 때
* 기초가 되는 스키마를 숨기기 위해 소유권 체인을 사용할 수 없고(예를 들어 개체를 액세스하는 루틴이 다른 소유자의 것일 때), 참조하는 개체에 대해 권한 부여를 하고 싶지 않을 때
* 내가 임의로 권한 집합을 만들고 싶을 때

많은 경우에 줄(grant) 수 없는 권한(예를 들어 TRUNCATE TABLE)을 주어야 할 때가 있다. SQL 서버 2005에서 조차도 이런 권한은 줄 수 없다. 하지만 데이터베이스 소유자는 테이블을 truncate하는 프로시저를 만들 수 있다. 테이블의 소유자와 데이터베이스의 소유자가 동일 하다면 깨어지지 않은 소유권 체인을 가진 것이다. 소유권 체인의 장점은 소유권 체인이 DML(Data Manipulation Language)문장 (SELECT, INSERT, UPDATE, DELETE)에만 적용되고 따라서 프로시저를 수행하는 사용자는 테이블을 truncate하려는 시도에 대해 권한 위반을 만나게 된다. 그러나 EXECUTE AS 를 사용하여 프로시저를 만들면 프로시저를 수행하는 사용자는 수행하는 동안 다른 사용자의 정체성으로 프로시저를 수행하게 되며 따라서 TRUNCATE TABLE 문장은 수행될 수 있다.
EXECUTE AS SELF 는 응용프로그램이 호출한 사용자를 위해 루틴을 만들고 그 루틴이 생성자의 문맥에서 수행되기를 원할 때 사용하면 좋다. 예를 들어 디자인 단계에서 어떤 사용자가 그 응용프로그램을 호출할 지 모르는 경우다.

사용자 스키마 분리

SQL 서버 2005 에서 크게 눈에 띄는 보안상의 또 다른 변화는, 사용자와 개체의 관계를 단순화 시켰고, 이로 인해 사용자가 소유한 개체에 대해 염려하지 않고 사용자를 삭제 할 수 있다는 것이다. ANSI 호환성을 위해서, SQL 서버 2005 는 사용자와 스키마를 구분하고 있다.
ANSI SQL-92 표준은 스키마를 사용자가 소유한 데이터베이스 개체와 하나의 네임 스페이스를 구성하는(즉 중복된 이름을 가질 수 없는 개체의 집합) 데이터베이스 개체의 집합으로 정의한다. 예를 들어, 두 테이블은 오직 서로 다른 스키마에 있을 때에만 같은 이름을 지닐 수 있다. 두 테이블은 같은 스키마에 있다면 절대 같은 이름을 가질 수 없다. 따라서 스키마를 개체를 담고 있는 그릇으로 생각할 수 있다. (데이터베이스 도구에서는 스키마란 한 스키마 혹은 데이터베이스에 있는 개체를 서술하는 카탈로그 정보를 언급한다. 분석 서비스에서 스키마란, 큐브나 차원 같은 다차원 개체를 의미 한다.)
SQL 서버 2005 는 사용자의 스키마에 대한 연결고리를 끊었다. 기본 principal이나 보조 principal이 같은 스키마를 가질 수 있다. 여기서 principal 이라는 용어는 안전한(안전하게 할 수 있는) 개체를 액세스 할 수 있는 엔터티를 의미 한다. 기본 principal은 단일 사용자(예를 들어 SQL 서버 로그인이나 윈도우 로그인)를 의미한다. 보조 principal은 다수 사용자(예를 들어 역할이나 윈도우 그룹)을 의미 한다. SQL 서버 2005에서의 또 다른 변화는, 개체는 소유자를 갖지 않는 다는 것이다. 누가 스키마의 소유자가 되건, 그 스키마의 소유자가 개체를 “소유”한다. 스키마란 개체를 담고 있는 그릇이지 소유자가 아니라는 것을 다시 한번 기억하자. SQL 서버 2005에서 만들어지는 모든 새로운 데이터베이스는 몇 개의 스키마를 포함하고 있다. SQL 서버 2000의 dbo, INFORMATION_SCHEMA, guest 사용자에 상응하는 것으로 모든 SQL 서버 2005의 데이터베이스는 sys라는 스키마를 가지고 있는데 이것은 모든 시스템 테이블과 뷰에 대한 사용자들의 접근을 허락해 준다. 마지막으로 SQL 서버 2000의 시스템 역할(미리 정의된 역할)에 상응하기 위해 SQL 서버 2005는 동일한 이름의 스키마를 가지고 있다.
사용자를 만들 때 실제로 존재하지 않는 스키마를 사용자의 디폴트 스키마로 지정할 수도 있다. 사용자의 디폴트 스카마란 개체 생성과 삭제 시에 참조하게 된다. “개체 소유권과 보안”에서 언급한 것처럼 사용자를 위한 디폴트 스키마를 지정하지 않으면 사용자의 디폴트 스키마는 dbo 스키마가 된다. SQL 서버 2005는 개체 접근을 위해 그 사용자의 디폴트 스키마가 무엇이든 상관 없이 sys 스키마를 항상 제일 먼저 점검해 본다. 예를 들어 사용자 Sue가 쿼리 SELECT * FROM table1 을 수행하고 Sue 의 디폴트 스키마는 SueSchema 라고 한다면 이름 해결(name resolution)은 다음과 같은 단계를 따르게 된다.

1. sys.table1 을 찾는다.
2. SueSchema.table1 을 찾는다.
3. dbo.table1 을 찾는다.

이런 조회 메커니즘은 ALTER 와 DROP을 포함한 모든 문장에 적용된다. sysadmin 이 개체를 한 요소 이름(one-part name)으로 생성했을 때 스키마는 항상 dbo가 됨을 기억하자. 그러나 sysadmin 은 명시적으로 개체가 놓여질 스키마를 지정할 수도 있다.
하위 호환성
SQL 서버 2000 은 사용자와 스키마를 분리(구별)하지 않는다. 그래서 SQL 서버 2000은 스키마의 자리에 개체를 만든 소유자를 박아 넣고 있다. 하위 호환성 유지를 위해서 SQL 서버 2005에서 마이크로소프트는 sp_grantdbaccess 와 sp_adduser 프로시저를 재 작성 했으며 새로운 Data Definition Language (DDL) 문을 만들었다. 이에 대해서는 다음이 “새로운DDL" 부분에서 다룬다.
SQL 서버 2005에서 sp_grantdbaccess 는 사용자를 만들고 사용자 이름과 동일한 이름의 스키마를 만든다. 스키마는 사용자의 디폴트 스키마가 되며 사용자는 스키마의 소유자가 된다. 예를 들어 다음 프로시저를 수행한다고 해 보자.



SQL 서버 2005 는 이것을 내부적으로 새로운 DDL문장으로 해석하는데 [리스트 1]이 이를 보여준다. 뿐만 아니라 SQL 서버 2005는 내부적으로 sp_revokedbaccess sue 를 다음과 같이 다시 쓴다.



SQL 서버 2005 는 사용자와 이름과 ID가 같은 스키마만 삭제한다.
디폴트 스키마 없이 CREATE USER 를 sp_grantdbaccess 대신 수행하면 디폴트 스키마는 dbo가 된다. SQL 서버 2005 는 사용자 이름과 같은 이름의 새로운 스키마를 만들지 않는다.

이제 준비하자

SQL 서버 2005가 출시되었을 때 즉시 업그레이드 할 계획이 없다고 할 지라도 사용자와 스키마를 지금부터 분리해서 생각해줄 것을 권고한다. SQL 서버 2000에서는 스키마는 항상 사용자의 이름과 같지만 권한을 부여할 때 사용자에게 부여하는 것이라는 것을 정확하게는 알고 있어야 한다. 스키마는 개체를 담고 있는 (그리고 그것의 적합성을 판단하는) 그릇일 뿐이다.
사용자와 스키마의 분리는 몇 가지 방법으로 관리를 쉽게 해준다. 가장 큰 이점은 사용자를 관리 하는 것이다. 특히 사용자를 삭제할 때 매우 편해진다. 뿐만 아니라, 여러 사용자 집합을 한 스키마의 소유자로 지정할 수 있는데 이때는 보조 principal(예를 들어 그룹이나 역할)을 스키마의 소유자로 지정하면 된다. 또, 여러 사용자가 같은 디폴트 스키마를 가져서 같은 이름 해결(name resolution)을 할 수 있다.
특정 모듈의 실행자로서 사용자를 지정 할 수 있는 능력은 개체를 액세스 하는데 더 많은 제어 능력을 주며 SQL 서버 2000의 서비스 팩 3를 능가하는 데이터베이스 간 소유권 체인에 있어서 많은 발전이다. 데이터베이스간 소유권 체인은 “전부 아니면 아무 것도(all-or-nothing)”의 해결책이었다: 소유권 체인은 데이터베이스 간에 적용되거나, 아니면 아예 안되거나 둘 중 하나였다. SQL 서버 2005의 발전된 제어력은 하나의 모듈 개발자가 어떤 모듈이 사용자가 실행할 수 있으며 어떤 모듈이 사용자가 실행할 수 없는지를 결정할 수 있게 해 준다.
이런 향상된 점들은 유콘 보안 사양의 빙산의 일각일 뿐이다. 새로운 사양에 대해 귀를 열어 놓고 기다리자. SQL 서버 2005 출시에 가까워 질수록, 이런 사양들에 대해 나는 더 깊이 파고 들 것이다.

[리스트 1] SQL 서버 2005가 번역한 sp_grantdbaccess


새로운DDL

SQL 서버 2005 는 스키마를 다룰 수 있는 새로운 문장들을 제공한다. 여기에 완전한 긴 문법을 적어서 지면을 차지하기 보다는 간단히 요약하여 적을 것이고 더 자세한 것은 SQL 서버 2005를 설치한 후에 온라인 설명서를 참조하는 것이 좋겠다.
CREATE SCHEMA를 가지고 새로운 스키마를 만들 수 있으며 이와 함께 옵션으로 AUTHORIZATION 절을 사용하여 스키마의 소유자를 지정할 수 있다. AUTHORIZATION 절을 사용하지 않으면 CREATE SCHEMA를 수행하는 사용자가 스키마의 소유자가 된다. 소유자는 다른 스키마를 소유할 수 있으며 소유한 스키마 외에 다른 스키마를 디폴트 스키마로 가질 수도 있다.
ALTER SCHEMA 문은 스키마 소유자를 재설정 할 수 있게 해준다. (한 시점에 한 principal 만이 스키마의 소유자가 될 수 있지만 principal은 SQL 서버 사용자, 윈도우 사용자, 윈도우 그룹, SQL 서버 역할 중 어느 것이든 가능하다). 스키마에 TAKE OWNERSHIP 권한을 가진 사용자만이 스키마의 소유권을 가질 수 있다. db_owner 역할의 구성원은 스키마 소유권을 변경할 수 있다.
DROP SCHEMA 는 아무 개체도 담고 잇지 않은 스키마를 제거한다. 스키마에 단 하나의 개체라도 담겨 있으면, 스키마 삭제는 실패한다.
또한 SQL 서버 2005 는 사용자와 함께 동작하는 새로운 DDL(Data Definition Language) 문을 가지고 있다. 이전에 저장 프로시저로 하던 것들을 이제는 CREATE 과 ALTER 문장으로 대신할 수 있다. CREATE USER는 새로운 사용자를 만들며 선택적으로 로그인 명과 연결시킬 수 있다. 또한 디폴트 스키마를 지정할 수 있다. ALTER USER 는 사용자 이름을 바꾸거나 사용자의 디폴트 스키마를 변경할 수 있다.

출처: Windows .NET [2004년 6월호]
"MSSQL" 카테고리의 다른 글
  • 지금 SQL 서버에서는 어떤 문제들이 벌어지고 있을까? (1)2007/05/21
  • SQL Server 2000에서 varchar와 char 데이터 타입 (0)2007/05/21
  • SQL 서버 2005 보안 (0)2007/05/21
  • 새로운 SQL 서버 로그인 생성하기 (0)2007/05/21
  • SQL Server 2000에서 update시 join의 활용 (0)2007/05/21
2007/05/21 09:37 2007/05/21 09:37
Posted by webdizen
Tags DDL, SQL Server 2005, 사용자 스키마 분리
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3004

Leave your greetings.

[로그인][오픈아이디란?]

«Prev  1  Next»

RSS HanRSS
Blog Image
webdizen
이 곳은 컴퓨터에 대해 연구하고, 공유하고, 소통하기 위한 연구실입니다. 개인적으로는 OLAP, Data Mining, Semantic Web, Data Modeling에 대해서 연구하고 있습니다.

Categories

전체 (2998)
Webdizen (134)
Life (6)
Diary (16)
Blog (9)
IDEA (1)
Travel (10)
Book (14)
Photo (7)
Movie (7)
Music (13)
Leisure Sports (10)
Funny (5)
Hardware (119)
Software (120)
Windows (5)
Unix & Linux (119)
Installation (4)
Kernel (10)
System (34)
Develop (22)
X-Window (0)
Applicaton (31)
Security (4)
Framework (2)
Hadoop (2)
Programming (805)
Algorithm & Data Structure (1)
Assembly (38)
UNIX/Linux C (95)
C++ (128)
STL (4)
Java (38)
Win32 API (92)
ATL/COM (44)
MFC (151)
.NET (26)
WCF/WPF (4)
C# (28)
Network Programming (17)
Database Programming (12)
OpenGL / DirectX (13)
Multimedia Programming (0)
Game Programming (21)
Parallel Distributed Progra... (0)
Reverse Engineering (0)
Debugging (9)
Python (1)
Ruby (1)
Ruby on Rails (1)
QT (4)
GTK (0)
JSP (0)
PHP (6)
ASP.NET (6)
ASP (3)
Development (28)
Useful Library (2)
Data Modeling (0)
Database (105)
Oracle (4)
MSSQL (41)
MySQL (2)
Data Warehouse (2)
Data Mining (3)
Network (66)
Web (78)
DHTML (4)
XHTML (1)
Javascript (1)
CSS (1)
AJAX (9)
XML (11)
Flex (1)
Silverlight (3)
Security (91)
DoS (1)
Kernel (10)
Scanning (3)
Sniffing (0)
Spoofing (4)
Overflow (28)
Web (11)
Shell (10)
Format String (14)
Window (2)
Embedded (70)
Multimedia (27)
Mobile (14)
Graphic (24)
Management (633)
Knowledge (581)
Hadoop (0)

Notice

  • 메타 블로그 사이트에 등록
  • 새해 맞이 블로그의 변화
  • 블로그 명칭 변경
  • 도메인(www.webdizen.net) 구...
  • TEXTCUBE 1.6.1로 업그레이드...

Tags

  • 비트맵 출력
  • Functor
  • Filtering
  • COM
  • Registry Key
  • Calendar
  • 산림환경과학대학
  • OLAP 큐브
  • SAX
  • 계정관리
  • NBTScan
  • 블루투스 해드셋
  • WaitForSingleObject
  • 백록관
  • 까딸루냐 광장
  • 해네시 VSOP
  • Bitmap ImageList
  • 점유율
  • 음악
  • 가상 메모리 크기

Recent Articles

  • ASCII Code의 CRLF 제거 방법.
  • Hadoop 에서 c++ API 이용시....
  • Ubuntu Linux에서 Hadoop 구....
  • 내 심장을 한껏 뛰게한 "국가....
  • 스타 스키마 데이터베이스 설....

Recent Comments

  • ■ 온라인카지노 ▶ http://L....
    asdf 11/21
  • 그리고 혹시 해외여행자보험....
    kim 11/05
  • ★★실제 바다게임장과 똑같....
    asdf 11/04
  • sbsyama.co.to← 짱5000만당....
    asdf 11/04
  • ♡KicaZ??o(???) 바카라사....
    fdsf3fass 11/03

Recent Trackbacks

  • 파일 열기/저장하기 CFileDialog.
    은마군의 나태블록 02/11
  • World IT Show 2008.
    상우 :: Oranzie's BLOG 2008
  • cvs서버 설치하기.
    3인3색 2008
  • 속속 공개되는 Google Chart....
    PHP와 Web 2.0 2007
  • 마방진을 구하는 프로그램.
    Oranzie's BLOG 3 2007

Archive

  • 2009/09 (3)
  • 2009/08 (1)
  • 2009/03 (1)
  • 2009/02 (9)
  • 2009/01 (13)

Calendar

«   2009/11   »
일 월 화 수 목 금 토
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

Bookmarks

    • Administration
      • IIS.NET
      • NTFAQ
      • OS의 모든 것
      • 리눅스포털
    • Database
      • SQL Server Central
      • SQL Team
    • Development
      • .NET Heaven
      • ASP Alliance
      • ASP.NET 2.0
      • Bullog.net
      • C# Corner
      • C++ (C PlusPlus.com)
      • C++ Reference
      • CodeGuru
      • CodePlex
      • DebugLab
      • Dev Articles
      • Devpia
      • DotNet Junkies
      • DotNet Zone
      • Driver Online
      • GOSU.NET
      • HOONS 닷넷
      • Joinc 팀블로그
      • KOSR
      • MSDN Home Page
      • OSR Online
      • Sky.ph - 개발자 커뮤니...
      • TAEYO.NET
      • The Code Project
      • WindowsClient.net
      • 김상욱의 개발자 Side
      • 조인시 위키
    • Human Networks
      • belief21c's e-space
      • I think I can
      • Invisible Rover's Blog :D
      • Rodman®
      • ■ Feel So Good~! ■
      • 까만 나비
      • 나를 가꾸는 시간.
      • 나만의 즐거움~~!
      • 단녕
      • 상우 :: Oranzie's BLOG
    • Information Technology
      • Microsoft TechNet
      • 지디넷코리아 - 글로벌...
    • Security
      • FoundStone
      • milw0rm
      • NewOrder
      • OpenRCE
      • Phrack.org
      • Reverse Engineering b1...
      • Reverse Engineering Team
      • RootKit
      • SecurityFocus
      • SecurityXploded by Nag...
      • Wow Hacker
      • Zone-H
Textcube
Louice Studio Inc.
Powered by Textcube. Original designed by Tistory.