구글와이드(336x280)_상단 2개


검색 경로 최적화 DB

Solutions by Design + 검색 경로 최적화

효과적이지 않은 단순한 키워드-나열 방식을 사용하지 마라.
키워드-나열 디자인이 어떤 문제를 갖는지 예제를 통해 살펴보자. 최근에 필자는 선택한 이미지를 티셔츠에 출력해서 만들어주는 사이트의 웹 응용프로그램을 이용한적이 있었다. 예전에 필자가 방문한 다른 사이트에서 미국 남서부의 상징적인 대여섯 개의 이미지를 기억하고 있었다. 필자는 코코펠리(Kokopeli:미국 남서부 원주민들의 기쁨의 표시인 곱사등을 가진 피리 부는 사람) 이미지를 찾기 위해서 southwest 라는 키워드로 검색 했지만 원하지 않는 네 개의 이미지만을 얻었다. [그림1]은 웹 응용프로그램을 통해 반환 받은 이미지들을 포함한 스크린 샷이다. 운 좋게도 필자는 해당 데이터베이스에 접속 할 수 있어서 쿼리 분석기를 이용해서 이미지 테이블을 직접 검색할 수 있었다.
[그림1 웹사이트에서 찾은 Southwest 이미지들]
[그림2]는 와일드카드 문자(%)를 사용해서 southwest 키워드를 포함하고 있는 이미지를 찾기 위해 asset 테이블에 대해 LIKE '%southwest%' 와 같이 직접 쿼리를 수행한 결과이다. [그림2]에 나와있는 asset 테이블의 레이아웃을 살펴보면, 이미지가 해당 테이블에 직접 저장되지 않는 것에 주목할 수 있다. 대신 테이블의 각 행은 asset_image 컬럼에 웹 사이트에서 연동할 이미지 포인터를 가진다. 예제의 경우는 웹 서버에 저장된 이미지 파일인 .jpg 파일명들이 포인터가 된다. 일반적으로 테이블에는 숫자나 문자로 된 식별자를 갖는데 예제 테이블은 각 행의 이미지(name)을 위한 식별자(ID) 컬럼을 가지고 있으며, 또 각 이미지에 대한 설명(keywords) 컬럼을 포함하고 있다. 데이터베이스에는 Southwestern 관련되어 [그림1]에서 보았던 네 개의 이미지보다 많이 포함되어 있다는 것을 알 수 있다. 필자의 키워드 검색 쿼리로는 일곱 개의 이미지가 반환되었다.
[그림 2 키워드 검색으로 찾은 Southwest 이미지들]
키워드가 한 필드에 같이 열거되어 있기 때문에 웹 응용프로그램과 필자는 쿼리의 정확도를 높이기 위해서 와일드카드 문자를 사용해야 했다. 쿼리에서 와일드카드 문자를 사용하는 방법에 대한 설명은 SQL Server 2000 온라인 설명서(BOL)의 "검색 조건의 패턴 일치" 항목을 참고할 수 있다. [그림2]와 같은 테이블 디자인은 패턴 일치를 위해 문자열 표현식 시작 부분을 와일드카드 문자로 사용해야 하고, 이로 인한 테이블 스캔이 유발되며, 결국 데이터베이스 성능 저하를 초래하게 될 것이다. 만약 와일드카드 문자를 문자열 표현식의 중간이나 마지막 부분에 사용하고 유용한 인덱스가 있는 경우라면 옵티마이저는 인덱스를 사용할 것이다.
비록 테이블 스캔이 SQL Server 저장소 엔진에 의해 좀더 최적화되었다 하더라도 (온라인 설명서의 "SQL Server 아키텍처 : 페이지 읽기" 항목), 대량의 테이블을 다루는 데이터베이스 성능은 테이블 스캔보다 인덱스를 사용하는 것이 대부분 효과적이다. (온라인 설명서의 "데이터베이스 만들기 및 유지 관리 : 인덱스 디자인" 항목). 설령 예제 테이블의 keywords 컬럼에 인덱스가 존재하더라도, 문자열의 시작 부분에 위치하지 않은 표현을 검색하면 SQL Server는 인덱스를 사용할 수 없게 된다.
키워드를 나열 문자열로 저장하는 keywords 컬럼은 이 테이블을 최악의 디자인으로 전락시키고 있다. 나열은 프로그래밍 언어에서 굉장히 유용한 구조다. 나열을 통해서 데이터베이스 외부에서 간단하고 효과적으로 데이터를 다룰 수 있다. 그러나 관계형 데이터베이스 내부에서 나열은 조악한 저장 구조이다. 이 문제를 다르게 설명하면 Asset 테이블은 정규화되지 않았다고 이야기할 수 있다. 데이터 정규화에 관해 더 알고 싶으면, 필자의 1999년 3월 기사 "정규화:왜 필요한가" InstatdocID 4887를 참고할 수 있다. 나열을 사용하여 키워드를 저장하면, 단일 테이블에 다대다(M:N)관계를 저장하게 된다. Asset 테이블의 개별 행에서 이미지와 키워드는 M:N 관계를 갖게 된다. 하나의 이미지는 하나 이상의 키워드로 묘사될 수 있는 엔티티이고, 하나의 키워드는 하나 이상의 이미지를 설명할 수 있는 엔티티이다.
예를 들어 [그림2]에서 이미지 ID 3677은 다섯 개의 키워드(Southwest, art, bull, native, American)로 설명된다. 각각의 키워드들이 이미지 ID 3677외에도 다른 이미지를 설명할 수 있기 때문에 해당 키워드는 다른 이미지의 keywords 컬럼에서 반복된다. [그림2]는 이런 디자인에 때문에 발생한 많은 중복 데이터를 보여준다. 중복 데이터 외에도 [그림2]에서 보듯이 키워드 나열에서 원하는 데이터를 얻기 위해 SELECT 쿼리를 어떻게 작성해야 하는지 아이디어를 보여주고 있다. 하지만 이 웹 사이트의 일반적인 고객이라면 테이블 데이터에 직접 접근할 수 없을 뿐 아니라 SELECT 쿼리를 작성할 줄도 모를 것이다. 일반적인 고객은 쿼리를 작성한 웹 개발자나 저장 프로시저를 작성한 데이터베이스 개발자의 작업대로 [그림1]의 결과를 보게 될 것이다.

[그림 3 키워드 검색에 적합한 디자인]
키워드-나열 디자인으로 인한 문제는 데이터베이스 성능과 데이터 중복 외에 더 있을 수 있다. 키워드 나열을 피해야 하는 가장 중요한 이유는 작성한 쿼리가 문제가 없다고 혼동하는데 있다. 데이터 입력이 통제되고 표준화되지 않았기 때문에 용어의 다양한 형태가(예를 들어 Southwestern 대신 Southwest를 사용) 가능하고 그런 변형들이 필자의 첫 쿼리가 실패한 원인이 되었다. 처음에는 원하는 이미지를 찾지 못한 것은 오타와 생략 혹은 용어의 부정확한 정의들로 인한 것이며, 마침내 찾아낸 일곱개의 이미지는 필자가 원하는 이미지가 웹 사이트에 존재한다는 것을 의미한다. 단어와 구절들을 분리하지 않고 연속적으로 나열한 키워드는 구절 데이터를 입력한 사람의 의도를 모호하게 만들 수도 있다. 아마도 3677 이미지의 데이터를 입력한 사람의 의도는 다섯 개의 키워드 대신에 한 개의 단어(bull)와 두 개의 구절(Southwest art 와 Native American)이었을지도 모른다. 키워드 나열은 입력자의 의도를 놓치거나 그 의미가 혼합되어 버리는 문제를 가진다.
[그림3]에서 3개의 테이블을 사용해서 M:N 관계를 적절히 디자인한 구조를 보여주고 있다. 이 경우에 IMAGE 테이블과 KEYWORD 테이블 그리고 키워드와 이미지를 연결하는 교차 테이블로 IMAGEKEYWORD테이블이 필요하다. 입력 용어에 대해 KEYWORD 테이블에 존재하는 키워드로 제한하기 위해서 적절히 디자인된 데이터 입력 UI를 추가할 필요가 있다. 이런 인터페이스는 다양한 키워드 변형으로 발생하는 문제들을 감소 시킬 수 있을 것이다.
"Instantdoc ID 44273"의 [웹리스트1]은 [그림3]에서 보여준 세 개의 테이블을 생성하는 코드를 포함하고 있으며, [웹리스트2]는 해당 테이블들에 대한 데이터를 생성하는 스크립트이다. [리스트1]에 나온 것처럼 JOIN 쿼리를 실행해서 일곱 개의 SouthWestern 이미지가 모두 반환되는 것을 확인 할 수 있다.
나열은 친숙하고 사용하기 편하며, 간단한 디자인만으로 사용할 수 있으리라 생각할 수 있다. 근시안적으로 처리된 정규화되지 않은 데이터는 성능 저하뿐 아니라 원하지 않는 쿼리 결과를 초래한다는 것을 알 수 있었다. 그렇다고 잘 훈련된 데이터베이스 디자이너가 필요한 것은 아니다. M:N관계에 대해 세 개의 테이블을 이용한 것처럼 단순한 데이터베이스 디자인 원칙을 고수하면 많은 시간과 수고를 줄일 수 있을 것이다.
리스트 1 : Southwestern 이미지를 검색하는 쿼리
/*-------------------------------------------------------------------
        search by keyword
 -------------------------------------------------------------------*/
SELECT i.ImageID, i.ImageName, i.ImageFile
FROM dbo.Image i
        JOIN dbo.IMAGEKEYWORD ik  ON  i.ImageID = ik.ImageID
        JOIN dbo.KEYWORD k  ON  ik.KeywordID = k.KeywordID
WHERE KeywordDscr = 'southwest'
GO

대부분의 사람들은 자료를 검색하기 위해 키워드를 사용해본 경험을 가지고 있을 것이다. 도서관에 처음 갔을 때 카탈로그로 찾거나 온라인 검색엔진을 이용한 키워드 검색을 해 보았을 것이다. 어떤 식으로든 키워드에 대해 접해봤을 것이다. 일상적인 업무에서 데이터 검색과 정렬, 전문가 영역에서의 데이터베이스 디자인 등 여러 가지 목적으로 키워드를 사용했을 것이다. 키워드가 매우 친숙하기 때문에 키워드를 이용하기 위해 간단하게 데이터베이스 디자인을 할 수 있을 것이다. 그러나 이런 손쉬운 지름길이 성능 저하에 원인이 될 수 있다는 걸 명심해야 한다. 키워드 나열(keyword array)은 나쁜 데이터베이스 디자인의 대표적인 예이다. 단순 키워드 나열은 테이블 스캔을 자주 유발하기 때문에 데이터베이스 성능을 저하시킨다. 또한 사용자가 쿼리를 정확하게 작성하지 않거나 정확하게 유도되지 않는 응용프로그램에서는 사용자가 검색하려는 대상을 찾지 못하는 경우도 발생할 수 있다.
최종 수정일 : 2005년 3월 16일

null



바보들의 영문법 카페(클릭!!)

오늘의 메모....

시사평론-정론직필 다음 카페
http://cafe.daum.net/sisa-1

바보들의 영문법 다음 카페
http://cafe.daum.net/babo-edu/

티스토리 내 블로그
http://earthly.tistory.com/

내 블로그에 있는 모든 글들과 자료에 대한 펌과 링크는 무제한 허용됩니다.
(단, 내 블로그에 덧글쓰기가 차단된 자들에게는 펌, 트랙백, 핑백 등이 일체 허용되지 않음.)

그리고 내 블로그 최근글 목록을 제목별로 보시려면....
바로 아래에 있는 이전글 목록의 최근달을 클릭하시면 됩니다.
그러면 제목을 보고 편하게 글을 골라 보실 수 있습니다.

그리고 내 블로그내 글을 검색하시려면 아래 검색버튼을 이용하시면 됩니다.


가가챗창

flag_Visitors

free counters