인쇄용 버전       전송     
평가 및 의견을 보내려면 클릭하십시오.
MSDN
MSDN Library
기술 문서(Technical Articles)
SQL
 Duwamish Online SQL Server XML 카탈로그...

  저대역폭 보기 설정
Duwamish Online SQL Server XML 카탈로그 찾아보기

John A. Bocharov

Microsoft 개발자 네트워크

2000년 9월

요약 : 이 문서는 데이터 사용 페이지를 작성할 수 있게 해 주는 Microsoft® SQL Server™ 2000의 새 XML 기능을 사용하는 Duwamish Online 카탈로그 찾아보기 재구현에 대해 간략히 설명합니다(분량: 14 페이지/인쇄 페이지 기준).

목차

개요 개요
SQL Server 2000의 XML 지원 구성 요소 SQL Server 2000의 XML 지원 구성 요소
문제점과 솔루션 문제점과 솔루션
성능 성능
결론 결론

개요

Microsoft® SQL Server™ 2000에는 데이터베이스 서버에서 직접 XML을 얻고 ISAPI(Internet Server API) 인터페이스를 통해 데이터베이스를 액세스할 수 있도록 하는 몇 가지 새 XML 기술을 도입했습니다. 이러한 사실은 Duwamish Online에 무엇을 의미하겠습니까 Duwamish Books, Phase 4 n-tier design을 기초로 하는 이 Duwamish Online용 계층 구조는 다섯 개의 물리 계층으로 구성되며 데이터베이스에서 가장 멀리 떨어져 있는 계층(프레젠테이션 계층)을 XML이 사용합니다. SQL Server 2000과 그 XML 지원 기능은 XML만을 사용하는 응용 프로그램을 쉽게 사용할 수 있도록 해 주므로 웹 응용 프로그램 개발에 새로운 모델을 제공합니다.

새 기술의 실용성을 시험하기 위해 SQL Server 2000의 새 XML 기능을 사용하여 Duwamish Online 카탈로그 찾아보기를 다시 구현하고 데이터베이스 위의 Duwamish Online 계층을 모두 교체했습니다. 그 결과 만들어진 응용 프로그램인 Duwamish Online SQL Server XML은 원래의 모든 기능을 복제하며 Duwamish Online에서 볼 수 있는 계층의 대부분을 사용하여 동일한 논리적 작업을 실행합니다. 이 문서에서는 SQL Server의 다양한 XML 기능이 Duwamish Online SQL Server XML에 어떻게 사용되었으며 이 과정에서 어떤 사실을 알 수 있었는지를 설명합니다. 아키텍처 관점에서 Duwamish Online SQL Server XML을 설명한 문서는 MSDN News 2000년 11월/12월에 발표될 예정입니다. 11월 초에 온라인으로 보실 수 있습니다.

SQL Server 2000의 XML 지원 구성 요소

SQL Server 2000 XML 아키텍처는 웹 인터페이스 계층과 데이터베이스 계층의 두 물리 계층을 고려합니다. 웹 인터페이스 계층은 데이터 액세스, 비즈니스 로직, 워크플로, 프레젠테이션 작업을 처리합니다. 코드 모듈화와 기능 계층화에 도움이 되도록 이 아키텍처는 XDR 스키마, 템플릿, XSL 스타일시트를 통합할 수 있습니다. 성능을 최적화하기 위해 이 웹 인터페이스 계층은 SQL Server XML ISAPI 응용 프로그램에서 실행됩니다. 이는 기능 측면에서는 ASP(Active Server Pages) 엔진과 동일하지만 HTTP를 통한 데이터베이스 액세스 부문에서 상당히 전문화되어 있습니다. 새 아키텍처에서는 데이터 캐싱, 데이터 액세스, 그리고 많은 유형의 데이터 변환이 자동화되었으므로 개발 시간과 코드 크기가 현저히 줄어듭니다. 또한 이 자동화를 유연성 있게 처리할 수 있으므로 개발자가 최종 결과를 완벽하게 제어하는 동시에 하위 수준의 코드 쓰기 혼란을 줄여줍니다.

템플릿

템플릿은 URL을 통해 액세스할 수 있는 XML 설명 파일입니다. Duwamish Online SQL Server XML에서 템플릿은 워크플로 작업을 실행합니다. URL에 입력으로 지정된 매개 변수를 사용하며 XML 또는 HTML 블럭을 출력으로 작성합니다. 다음 예는 Duwamish Online SQL Server XML에 카탈로그 페이지를 만드는 템플릿의 하위 집합입니다.

<!-- This namespace declaration is required for all template files ->
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<sql:header>
<!-- The sql:param tag specifies an input parameter to the template. 
It is specified in the URL in standard query string format (e.g.
http://myserver/myvroot/templates/cat.xml?PKId=829 )
The value of this parameter is then stored in the variable @PKId -->
<sql:param name = "PKId">
</sql:param>
</sql:header>
<!-- The sql:query tag wraps an SQL query.This query calls a stored 
procedure, which runs faster than an uncompiled, ad hoc query. ->
<sql:query>
exec GetCategoryForXML @PKId
</sql:query>
</ROOT>

이 템플릿은 다음 URL을 액세스하면 실행할 수 있습니다.

http://myserver/myvroot/templates/cat.xml?PKId=829&contenttype=text/xml

여기서 myserver는 사용자 서버 이름이며, myvroot/templates는 사용자가 템플릿 파일을 설정한 디렉터리이고, cat.xml이 템플릿입니다.

contenttype 매개 변수에 주의하십시오. 이 매개 변수는 ISAPI 응용 프로그램에서 보관하므로 이 템플릿에서 선언되지 않습니다. 페이지가 정확하게 표시되도록 하려면 이 매개 변수의 값이 내용과 일치해야 합니다. 이 템플릿은 HTML 표시에 사용할 수도 있습니다. 이에 대해서는 다시 설명하도록 합니다. 이 예에서 XML 생성 논리는 이 템플릿에서 참조하는 GetCategoryForXML 저장 프로시저에 캡슐화되어 있으므로 이 코드에서는 명확하게 나타나지 않습니다. 만들어진 XML은 다음과 같습니다.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
   <Categories CatId="829">
      <Category ItemId = "830" ItemName = "Anthropology">
         <Product ItemId = "439" ItemName = "African Genesis" />
         <Product ItemId = "413" ItemName = "Cannibals and Kings" />
      </Category>
   </Categories>
</ROOT>

앞의 코드에서는 분명하게 하기 위해 일부 특성과 제품 및 범주를 생략했습니다.

XSL 변환

다행히, 템플릿 기능은 XML 검색 시 중단되지 않습니다. 템플릿을 조금만 변경하므로 SQL Server XML ISAPI 응용 프로그램은 XSL 스타일 시트를 자동 검색하여 그 결과에 적용합니다. 이렇게 추가된 사항은 루트 태그에 표시됩니다.

<ROOT xmlns:sql = "urn:schemas-microsoft-com:xml-sql" sql:xsl="mystyle.xsl" >

페이지를 정확하게 표시하려면 반드시 URL에 "contenttype=text/html"을 추가해야 합니다. 이전 섹션의 템플릿 액세스에 사용된 URL은 다음과 같이 변경할 수 있습니다.

http://myserver/myvroot/templates/cat.xml?PKId=829&contenttype=text/html

사용자의 스타일 시트가 XSLT를 사용하는 경우에는 <xsl:output> 태그를 사용해도 같은 결과를 얻을 수 있습니다.

이제, XML 데이터를 검색하는 방법을 살펴 보도록 합니다. 이 방법들은 이 템플릿의 설명을 이용하면 됩니다.

XDR 스키마

XDR(XML Data Reduced) 스키마는 데이터베이스의 정보를 XML로 쉽게 변환할 수 있도록 해줍니다. SDR 스키마는 그 자체가 XML 문서로, 데이터베이스의 테이블과 열을 출력된 XML 문서의 요소와 특성으로 매핑하는 강력한 구문을 제공합니다. 하지만 이 기술의 근본적인 힘은 XPath(XML Path Language) 구문을 사용하는 정보의 특정한 하위 집합을 검색하는 능력에 있습니다( http://www.w3.org/TR/xpath 참조). XPath는 XML 문서 내의 특정한 요소를 찾는 구문을 제공합니다. XDR 구문을 사용하면 데이터베이스를 하나의 거대한 XML 문서로 취급할 수 있으며 XPath 대기열은 이 문서의 일부만을 선택해서 사용자에게 반환합니다. 물론, 성능을 고려하기 때문에 이렇게 큰 XML 문서를 실제로 만들지는 않습니다.

XDR 스키마는 템플릿에서 <sql:xpath-query> 태그를 사용해 참조합니다. 다음은 Duwamish Online SQL Server SML 항목 세부 사항 페이지를 만드는 템플릿인 detail.xml의 한 버전입니다.

<ROOT xmlns:sql = "urn:schemas-microsoft-com:xml-sql">
<sql:header>
<sql:param name = "PKId"></sql:param>
<!-- The tag for the parameter looks exactly the same as before, but 
inside an xpath-query tag it is referenced by $PKId instead of @PKId. 
The syntax change is necessary to avoid ambiguity since the @ symbol is 
reserved for attributes in XPath --> 
</sql:header>
<!-- The mapping-schema attribute of the xpath-query tag specifies which 
XDR schema to use. The text inside the <xpath-query> tag contains the 
XPath query that should be applied. -->
<sql:xpath-query mapping-schema = "../schemas/detailex.xml">
   /Detail[@ItemId=$PKId]
</sql:xpath-query>
</ROOT>

위의 템플릿은 외부 파일인 detailex.xml을 참조합니다. 이 파일은 XDR 스키마로서, 다음과 같습니다.

<!-- This namespace is required for all XDR Schema elements -->
<Schema xmlns="urn:schemas-microsoft-com:xml-data"
<!-- The dt namespace allows you to specify datatypes.However, in most 
cases this is not necessary.A table that matches SQL datatypes to their 
schema counterparts can be found in the SQL Server Books Online (XML and 
Internet Support -> Creating XML Views Using Annotated XDR Schemas -> 
Annotations to XDR Schema -> Data Type Coercions) -->
xmlns:dt="urn:schemas-microsoft-com:datatypes"
xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
<!-- The sql:relation attribute specifies that although the XML tag is 
called Detail, the data comes from the Items table in the database-->
   <ElementType name="Detail" sql:relation="Items" >
<!-- The <AttributeType> tag can be used to specify an attribute's data 
type. The id data type corresponds to a key in the database.-->
      <AttributeType name="ItemId" dt:type = "id"/>
<!-- When no data type is specified, it defaults to string. -->
      <AttributeType name="ItemName" />
      <AttributeType name = "UnitPrice"dt:type = "r8"/>
<!-- The <attribute> tag creates an attribute. By default, the column 
name is assumed to be the same as the name of the attribute. -->
      <attribute type="ItemId" />
      <attribute type="ItemName" />
<!-- The sql:relation and sql:field attributes on this tag convey that 
this part of the structure is populated with data from another table (in 
this case the UnitPrice column of the RetailItems table.) -->
      <attribute type="UnitPrice" sql:relation = "RetailItems"
         sql:field = "UnitPrice">
<-- The <sql:relationship> tag is used to specify a join between two 
tables.In this case, it joins the Items and RetailItems tables. -->
         <sql:relationship key-relation = "Items" key = "ItemId"
            foreign-relation = "RetailItems" foreign-key = "ItemId" />
 
      </attribute>
   </ElementType>
</Schema>

이 스키마는 XML 출력 구조와 이 구조 적용에 관한 설명을 제공하며 쿼리 즉, XPath 쿼리의 역할 제한에 대한 설명은 전혀 제공하지 않습니다.

이 "XDR 스키마" 섹션을 시작할 때 템플릿의 XPath 쿼리를 고려하십시오. 분명히 하기 위해 $PKId를 407로 교체했습니다. 여기 사용된 숫자는 이 템플릿에 대한 URL 입력 중 하나입니다.

/Detail[@ItemId=407]

위의 XPath 쿼리의 조건(@ItemId = 407)은 특정한 레코드를 선택할 때 사용됩니다. 하지만 이 데이터는 XPath 쿼리 구문이 허용하는 어떤 방식으로나 제한이 가능합니다. 예를 들면, XPath 쿼리는 특정한 범위의 레코드(예: /Detail[@ItemId > 500 and @ItemId < 1000] )나 자식에 특정한 속성이 있는 레코드( /Detail[@UnitPrice = 7.99] )를 선택할 수 있으며 원하는 조건을 결합할 수도 있습니다. 사실, XDR 스키마를 사용하는 이유 중 하나는 유연성이 크기 때문입니다.

위의 쿼리는 XML 노드(Detail 요소 및 ItemId 특성)만 참조하며 쿼리가 매핑하는 데이터베이스 개체(Items 테이블과 ItemId 열)는 참조하지 않는다는 사실을 기억해야 합니다. 따라서 데이터베이스에서 높은 수준의 데이터 추상화를 제공하며 데이터베이스가 수정된 경우 스키마도 적절히 변경되어 있다면 해당 템플릿 코드를 다시 사용할 수 있습니다.

스키마는 템플릿을 통해서, 또는 URL로 직접 액세스할 수 있습니다. 다음 URL 쿼리는 둘다 결과는 동일하지만 하나는 템플릿을 사용하며 다른 하나는 템플릿을 사용하지 않습니다.

다음 URL에서 detail.xml은 이 섹션의 앞 부분에 제시된 템플릿을 참조합니다.

http://myserver/myvroot/templates/detail.xml?PKId=407&contenttype=text/html

다음 URL에서 detailex.xml은 앞서 본 XDR 스키마를 참조합니다. 이 스키마에 대한 XPath 쿼리가 이 URL에 추가됩니다.

http://myserver/myvroot/schemas/detailex.xml/Detail[@ItemId=407]

템플릿이 더 큰 유연성을 제공하므로 일반적으로 템플릿을 많이 사용합니다. 템플릿에는 여러 쿼리를 넣을 수 있으며 이렇게 만들어지는 데이터에 XSL 스타일 시트를 추가하는 옵션 설명도 넣을 수 있습니다.

위의 두 경우 만들어지는 XML은 다음과 같습니다.

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<Detail ItemId = "407" ItemName = "&quot;Sure You&apos;re Joking, Mr. Feynman!&quot;" UnitPrice="6.99" />
</ROOT>

XDR 스키마에는 다소 유감스러운 한계가 있습니다. Duwamish Online 항목 카탈로그는 원래 순환하는 특징이 있는데 이 스키마는 재귀 데이터 구조를 지원하지 못합니다. 이는 Duwamish Online에 치명적인 한계입니다. 한 테이블은 판매 범주와 항목을 모두 저장하며, 두 번째 테이블은 이 둘 간에 부모/자식 관계를 설정합니다. 따라서 범주 페이지의 데이터를 검색하기 위해 Duwamish Online SQL Server XML은 저장 프로시저를 사용하며 이 프로시저는 XML을 반환합니다.

FOR XML 절

SQL Server 2000 XML 기술의 핵심은 데이터베이스에 있습니다. 익숙한 SELECT 문에 새 FOR XML 문이 추가되었습니다. 이름이 의미하는 것처럼 이 새 기능을 사용하면 결과 집합을 레코드 집합이 아닌 XML 문자열로 반환할 수 있습니다. 이 섹션의 나머지 부분을 완전히 이해하려면 SQL(Structured Query Language) 실무에 대한 지식이 있어야 합니다.

FOR XML은 세 가지 형태입니다. 첫 번째는 FOR XML RAW로서, 레코드 집합의 각 행마다 <row> 태그를 반환합니다. 이 형태는 구조화된 데이터를 설명하는 XML의 기능을 효과적으로 사용하지 못하므로 적용이 매우 제한됩니다. 두 번째 형태는 FOR XML AUTO로서, 테이블 별칭 명명 및 참여 방법을 지시하여 데이터에 이름을 붙이고 구조화합니다. 마지막 형태인 FOR XML EXPLICIT를 사용하면 XML의 정확한 구조와 명명 구성표를 지정할 수 있습니다. FOR XML EXPLICIT 구문은 쿼리를 간소화하고 실행을 최적화하도록 도와주는 몇 가지 지시문을 제공합니다.

세 가지 방법을 각각 사용하여 앞 섹션의 XML을 다시 만들어 봅시다. 다음 쿼리는 FOR XML RAW를 사용합니다.

Select Detail.ItemId, Detail.ItemName, RetailItems.UnitPrice
From Items Detail
   INNER JOIN RetailItems
   on Detail.ItemID = RetailItems.ItemId 
Where Detail.ItemId = 407 FOR XML RAW

그 결과는 다음과 같습니다.

<row ItemId="407" ItemName="&quot;Sure You&apos;re Joking, Mr. Feynman!&quot;" UnitPrice="6.9900"/>

쿼리의 모든 데이터는 보존되어 있지만 이 행 태그는 XML의 설명 기능을 이용하지 않습니다. 따라서 위의 데이터를 사용하는 응용 프로그램은 이 쿼리의 내부 작업에 대해 엄청난 양의 사전 지식을 가지고 있어야 합니다. 예를 들면, 많은 테이블에 ItemId가 있으며 심지어는 다른 데이터베이스에도 있습니다. 그렇다면 여기 사용된 ItemId는 무엇을 나타내는 것일까요 하지만 같은 쿼리에서 RAW를 AUTO로 바꾸면 원하는 것에 상당히 가까운 결과를 얻을 수 있습니다.

<Detail ItemId="407" ItemName="&quot;Sure You&apos;re Joking, Mr. Feynman!&quot;"><RetailItems UnitPrice="6.9900"/></Detail>

실제 결과와 원하는 결과의 유일한 차이점이라면 UnitPrice 특성은 다른 테이블에서 온 것이므로 독립적인 태그로 표시된다는 것입니다. EXPLICIT 모드를 사용하면 XDR 스키마를 사용해 얻어진 결과를 중복할 수 있습니다. 이 쿼리는 다음과 같습니다.

Select 1 as TAG, NULL as PARENT,
   Detail.ItemId as [Detail!1!ItemId],
   Detail.ItemName as [Detail!1!ItemName],
   RetailItems.UnitPrice as [Detail!1!UnitPrice]
From Items Detail
   INNER JOIN RetailItems
      on Detail.ItemID = RetailItems.ItemId 
Where Detail.ItemId = 407 FOR XML EXPLICIT

이 구문은 다른 두 구문보다 훨씬 더 복잡하지만 더 강력합니다. 가장 큰 차이점은 쿼리에 추가 열이 둘 덧붙여졌다는 것입니다. 이 두 열은 이 구문이 필요로 하는 메타데이터를 구성합니다. 이 변환을 촉진하기 위해 FOR XML EXPLICIT에는 개별 태그마다 ID가 필요합니다. 위 예의 경우에는 1입니다. SELECT 문의 첫 번째 항목은 이 행이 ID가 1인 태그에 속한다는 것을 표시합니다. 그리고 그 뒤에 오는 NULL 선택은 이 행에 부모 태그가 없다는 것을 나타냅니다.

이 문서에서는 FOR XML EXPLICIT의 모든 기능을 다루지는 않습니다. XML 및 인터넷 지원, XML 데이터 검색 및 쓰기, FOR XML을 사용하는 XML 문서 검색, Explicit 모드 사용 등에 대한 자세한 내용은 SQL Server Books Online 문서를 참조하십시오.

문제점과 솔루션

데이터 인코딩: 기초

Duwamish Online 카탈로그 찾아보기 사용자 인터페이스는 사용자가 마우스를 가능한 한 적게 누르고(따라서 웹 응용 프로그램에는 아주 중요한 특징인 서버 이동을 최소화하고) 가장 쉽고 직관적으로 원하는 곳을 탐색할 수 있도록 한다는 목표에 맞게 개발되었습니다. Duwamish Online 항목 카탈로그는 계층적으로 조직되어 있었으므로 이 작업은 간단했습니다. 예를 들면, 서적과 같은 큰 범주에는 소설 및 컴퓨터 서적과 같은 하위 범주가 있고 이 하위 범주에는 또 다시 하위 범주나 책 제목이 들어갈 것입니다. 우리는 현재 웹 상의 많은 전자 상거래 사이트와 포털이 사용하는 모델을 사용하기로 했습니다. 사용자가 범주 목록에서 역사 서적을 검색하면 페이지 상단에 탐색 모음이 나타납니다(그림 1 참조).

d51ctlgbrowse01.gif

그림 1. Duwamish Online 탐색   모음

이 탐색 모음을 사용하면 사용자는 "상위" 계층을 쉽게 검색할 수 있습니다. 또한 "하위" 계층을 검색할 수 있도록 현재 표시된 범주에 속한 개별 항목에 대한 링크가 표시됩니다. 이러한 탐색 모음을 실행하는 방법은 다양합니다.

  • 검색할   데이터베이스로   가서   현재   계층     사용자의   위치에서   경로를   결정합니다 . 우리가 사용한 데이터베이스 스키마는 한 항목이 동일한 계층 내 여러 곳에서 표시되도록 해 주므로 이 방법은 효과가 없을 수도 있습니다. 예를 들면, "How Software Works"라는 제목은 컴퓨터 서적에도 표시되고 Dewey 10진 분류 번호에 따른 해당 범주에도 표시됩니다. 따라서 해당 사용자가 "How Software Works"를 찾고 있다는 사실밖에 응용 프로그램이 아는 바가 없다면 이 응용 프로그램은 그 곳으로 이동하기 위해 사용해야 할 경로를 결정할 수 없습니다.

  • 사용자의   경로와   내용을   데이터베이스에   저장합니다. 이 방법을 사용하면 백-엔드 데이터베이스로 또 한번 이동해야 하므로 성능에 커다란 영향을 미칩니다. 그래서 우리는 이 방법은 사용하지 않기로 했습니다.

  • 서버에   사용자   경로를   저장하고   매번   세션 ID   사용해   액세스합니다. 이 방법은 웹 팜에 서버 선호도를 사용하기로 한 경우에는 효과적입니다. 선호도가 있다면 특정한 웹 서버에서 자신의 세션을 시작하는 사용자는 그 웹 서버로 돌아올 것입니다. 하지만 선호도가 없다면 사용자가 이 사이트를 방문하는 동안 서버를 몇 번 변경할 가능성이 높습니다. 이는 한 사용자에 대해 서버가 축적한 데이터를 액세스할 수 없다는 것을 뜻합니다.

  • URL   탐색   모음을   만드는     필요한   모든   정보를   저장합니다. 우리는 Duwamish Online에 이 방법을 사용하기로 결정했습니다.

탐색 모음(그림 1)을 만드는 페이지의 URL은 다음과 같은 형태입니다.

category.asp?PKId=829&PKName=Books&PKId=838&PKName=History

이 경우, 정보 페이지는 PKId와 PKName라는 두 쌍의 매개 변수를 받습니다. ASP에서는 이들 매개 변수가 지정하는 모든 데이터를 검색할 수 있으므로 문제가 없습니다. 하지만 XML을 지원하는 SQL Server 2000에서는 중복된 매개 변수는 버려집니다. SQL은 배열을 지원하지 않으므로 이는 당연한 결과입니다. Duwamish Online SQL Server XML 구현을 이해하려면 여기서 채택한 데이터 구조를 구현과는 분리해야 합니다.

사실은 다음과 같습니다. PKId와 PIName 쌍은 각각 항목 계층의 수준에 해당됩니다. 해당 항목 계층의 하위 수준을 검색하면 원래 데이터는 유지되며 새 항목이 추가됩니다. 그리고 해당 항목 계층의 상위 수준을 검색하면 마지막으로 그 데이터 구조에 추가된 하나 이상의 항목이 제거됩니다. 스택은 후입 선출(LIFO) 데이터 패러다임을 특징으로 합니다. Duwamish Online 구현은 임의 액세스를 허용하므로 많은 점에서 스택 배열 구현 방식과 유사합니다.

Duwamish Online에서 볼 수 있는 중복 매개 변수 스키마는 Duwamish Online SQL Server XML에서는 사용할 수 없으므로 SQL Server의 XML에 맞는 배열과 유사한 스택을 구현하는 유일한 방법은 PKId와 PKName 목록을 구분 기호로 분리해서 사용하는 방법일 것입니다. 하지만 이 방법을 사용할 경우 두 가지 큰 문제가 있습니다. 첫 번째는 적절한 구분 기호를 찾는 것입니다. 그리고 더 심각한 두 번째 문제는 SQL이 문자열을 조작할 수 없도록 만들어져 있으므로 문자열 조작 루틴은 분명 재고를 해야 한다는 것입니다. 배열과 유사한 구현을 시도할 경우 데이터베이스 측에 엄청난 양의 불필요한 오버헤드와 매우 복잡한 코드를 발생시킬 수 있습니다.

데이터베이스에서 데이터를 검색할 경우에는 스택의 맨 위에 있는 항목만 사용되며 나머지는 탐색 모음을 만드는 데만 사용된다는 점을 기억해야 합니다. 따라서 링크된 목록과 유사한 구현을 만들기로 결정했습니다. 이 템플릿에 사용되는 세 가지 매개 변수는 PKId, PKName, Path입니다. 이 중 PKId와 PKName에는 검색할 현재 항목에 대한 정보가 들어 있으므로 데이터베이스 서버가 빠르고 효율적으로 적절한 정보를 반환할 수 있습니다. 또한 Path에는 탐색 모음을 만드는 데 필요한 모든 정보가 들어 있습니다. 이제, 어떻게 실행되는지를 살펴 봅시다.

사용자가 최상위 범주를 보고 있을 경우 Path는 비어 있으며 URL 요청은 다음과 같습니다.

PKId=829&PKName=Books

사용자가 하위 범주(예: History)를 선택하면 이전 요청은 Path 변수로 들어갑니다. 하지만 앰퍼샌드 때문에 파서가 혼동을 일으키지 않도록 이 요청은 먼저 URL 전송용으로 인코딩됩니다. 이 첫 번째 단계를 거치면 쿼리는 다음과 같이 나타납니다.

PKId%3D829%26PKName%3Dbooks

이 문자열은 Path라는 변수에 할당되며 사용자가 새로운 요청 시 선택할 수 있도록 적절한 PKId 및 PKName과 결합됩니다. 이 요청은 다음과 같습니다.

PKId=838&PKName=History&Path=PKId%3D829%26PKName%3Dbooks

새 항목 요청을 만들려면 위의 요청을 단순한 문자열로 취급하여 URL 전송에 맞게 인코딩해야 합니다.

PKId%3D838%26PKName%3DHistory%26Path%3DPKId%253D829%2526PKName%253Dbooks

이것이 해당 계층의 다음 수준에 대한 Path 변수가 됩니다. 탐색 모음을 만들려면 이 과정을 거꾸로 따르면 됩니다. 위와 같은 문자열이 주어지면 알고리즘은 먼저 문자열을 디코딩합니다. 그 다음 PKId와 PKName을 분석하여 탐색 모음이 만들어지며, Path 변수에는 다음 실행에 사용할 수 있도록 인코딩된 문자열이 들어 있습니다. 이 문자열을 디코딩하여 PKId, PIName, Path 세그먼트로 분석하고 그 PKId와 PIName을 사용하여 또 다른 탐색 모음이 만들어집니다. 모든 데이터를 다 분석할 때까지 이 과정이 반복됩니다.

다음은 이 알고리즘이 어떻게 스타일 시트로 통합되는지를 보여주는 개요입니다.

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/TR/WD-xsl">
<!-- This is a standard for an XSL stylesheet.Unfortunately, XSLT does 
not allow script, so it could not be used here.->
   <xsl:template match = "/">
<!-- The info node contains metadata.The data contained is taken 
directly from the URL parameters without any manipulation on the database 
server. -->
      <xsl:for-each select = "ROOT/Info">
<!-- Script is called by means of an <xsl:eval> tag.The return value of 
the function called is inserted into the resulting document.In this 
case, the function is designed to return nothing. The "this" reference 
passed to the function points to the XMLDOM node for the current context. 
-->
         <xsl:eval>parsePath(this)</xsl:eval>
<!-- The parsePath function creates a data structure in script that stores 
the information from the Path parameter in an easy-to-retrieve fashion. 
To iterate through the data structure, the stylesheet then calls the Info 
template(see below). --> 
         <xsl:apply-templates select = "." />
      </xsl:for-each>
   </xsl:template>
   <xsl:template match = "Info">
<!-- This XSL template uses a script condition to determine if it has 
reached the end of the data structure and if the condition is true, it 
executes again.In a way this is similar to an XSL version of a "while" 
loop.--> 
      <xsl:if expr = "nextNode()">
<!--Insert an HTML link for the current item into the 
result document (actual code ommitted for clarity). -->
<!--And execute the template again.->
         <xsl:apply-templates select = "." />
      </xsl:if>
   </xsl:template>
   <xsl:script>
<!-- It is necessary to wrap script in a CDATA block to 
keep it from confusing the XML parser.-->
<![CDATA[
// PathItems is a reference to the data structure used to hold the
// results of the analysis done by parsePath var PathItems;
// PathItemsIndex contains the current position in the data 
// structure
 
var PathItemsIndex;
// the parsePath function parses the metadata contained in the XML 
// and puts it into a data structure in script
function parsePath(node) {
   // actual code omitted for clarity
}
function nextNode() {
   // the PathItemsIndex variable counts down rather than up
      PathItemsIndex--;
   // the function returns true if there are more items in the path,
   // and false otherwise.
      return (PathItemsIndex >= 0);
}
]]>
   </xsl:script>
</xsl:stylesheet>

이 알고리즘은 서버 변환 시 실행되므로 클라이언트는 스크립트리스(scriptless)로 유지할 수 있습니다.

제어 불가능한 문자열

Duwamish Online은 중간 계층 구성 요소에서 엄청난 양의 문자열을 조작합니다. 몇 가지 기술을 사용하는 응용 프로그램에서는 문자열 조작이 필요합니다. 어떤 환경에서 안전한 문자열이 다른 환경에서는 심각한 문제를 일으킬 수 있기 때문입니다. 예를 들면, "a < b"는 SQL 데이터베이스에는 안전하게 저장되지만 웹 페이지에 정확하게 표시하려면 "a &lt; b"로 변경해야 합니다. 또한 URL의 매개 변수로 정확하게 전송하려면 또 한번 수정해야 합니다. 앰퍼샌드는 이 경우에는 완전히 다른 의미를 갖기 때문입니다.

SQL에는 앞서 본 것처럼 필요한 문자열 조작을 효율적으로 실행하기 위한 기능이 없으므로 XSL 스타일 시트의 스크립트 블록에 문자열 조작 루틴을 추가했습니다. 이 스크립트는 웹 서버 변환 시 실행되므로 클라이언트쪽 브라우저 기능에 관계 없이 응용 프로그램은 정확하게 표시되는 HTML을 반환합니다.

성능

최근 테스트에서 웹 응용 프로그램 스트레스 도구를 사용하여 Duwamish Online과 Duwamish Online SQL Server XML의 카탈로그 검색 성능을 비교했습니다. 우리는 RAM 256MB인 Dell Pentium III 550Mz Xeon Dual 프로세서에 설치된 두 응용 프로그램의 모든 구성 요소를 사용하여 이 테스트를 실행했습니다. 그림 2는 그 결과입니다.

d51ctlgbrowse02.gif

그림 2. 성능 비교 테스트

그림에서 보는 것처럼 Duwamish Online SQL Server XML에서 분명한 성능 향상이 나타났습니다. 사실, Duwamish Online은 캐시를 사용하므로 주어진 카탈로그나 세부 항목을 데이터베이스에서 단 1회만 검색한다는 점을 고려하면 이 성능 향상은 생각하는 것보다 훨씬 큽니다. Duwamish Online에서 캐시된 성능과 캐시 되지 않은 성능을 비교한 테스트 결과 10배의 성능 향상이 증명되었기 때문입니다.

Microsoft SQL Server XML Technology Preview에는 그 기능 세트의 일부로서 ISAPI 캐시가 포함되어 있었습니다. 이 캐시 기능 예비 테스트에서 캐시가 없는 SQL Server XML 기반 버전에 비해 크기순으로 성능이 증가한 것을 알 수 있었습니다. 유감스럽게도 릴리스된 SQL Server 2000 버전에는 이 캐시 기능이 없으며 웹 릴리스 버전에는 이 기능을 포함시킬 계획입니다.

결론

SQL Server 2000의 XML 기능은 데이터 사용 페이지를 작성하는 데 적합합니다. 사용자가 보기에는 그 결과물이 ASP 기반 응용 프로그램을 사용한 경우와 같아 보일 수 있지만, 더 적은 수의 코드를 사용하고 성능은 우수하며 유지 관리 오버헤드가 더 적습니다. 데이터가 클라이언트로 가는 중에 다량의 조작이 필요하거나 복잡한 표시 로직이 필요한 경우 이 장점이 어느 정도 줄어들 수는 있지만 SQL Server에서 XML의 기능은 절대 간과할 수 없습니다.

최종수정일: 2000년 11월 13일

© 2009 Microsoft Corporation. All rights reserved. 사용약관  |  상표  |  개인정보보호
Page view tracker