현재 연재중인 기사
▷ 물탱크 구조로 알아본 오라클의 블록 옵션 ‘PCTFREE와 PCTUSED’
▷ 이산가족 찾기 생방송을 통해 배우는 DB 원리
▷ 개발자에게 맞는 DB 공부방법 찾기: 물리적 분류와 논리적 분류 그리고 인덱스
▶ 데이터베이스 인덱스의 오해와 진실
▷ 쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (상)
▷ 쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (하)
▷ 누구도 알려주지 않았던 ‘오라클 인덱스 생성도’의 비밀
▷ 누구도 알려주지 않았던 ‘오라클 쿼리 작성의 비법’
▷ 퀴리 최적화 및 튜닝을 위한 오라클 공정쿼리 작성법
▷ 만능 쿼리와 한 방 쿼리
▷ 오라클 옵티마이저 ‘CBO와 RBO’ 이해하기
▷ 재미있는 DB 이야기 ‘60갑자와 쿼리’
▷ 그림으로 배우는 ‘오라클 조인의 방식’ 이야기
▷ 반드시 알아야 하는 오라클 힌트절 7가지
▷ 오라클 플랜을 보는 법
▷ 개발자들의 영원한 숙제 ‘NULL 이야기’
▷ 알면 유용한 오라클 기능 ‘GATHER_PLAN_STATISTICS’
▷ 알면 유용한 오라클 기능들
▷ 오라클 DICTIONARY를 활용한 DB툴 프로그램 ‘FreeSQL’
▷ 이제는 말할 수 있다: 주식 자동매매 프로그램(상)
▷ 이제는 말할 수 있다: 주식 자동매매 프로그램(하)
▷ 개발자들이 자주 접하는 오라클 에러 메세지
▷ 재미있는 DB 이야기 ‘사라진 날짜를 찾아라’
▷ 오라클 랜덤 함수와 사용자 정의 함수
▷ 그림으로 배우는 ‘공정쿼리와 인덱스 생성도’
▷ 이병국의 개발자를 위한 DB 이야기: 디폴트 세팅의 함정과 오라클 파라미터
▷ 재미있는 DB 이야기 ‘놀라운 마방진의 세계’
▷ 오라클 운반 최소 단위 BLOCK
▷ 이병국의 개발자를 위한 DB 이야기: 이세돌과 알파고의 세기의 대결
▷ 이병국의 개발자를 위한 DB 이야기(30회) : DB 엔지니어의 가볍게 읽는 세상 이야기
▷ 이병국의 개발자를 위한 DB 이야기: 튜닝(31회) : 개발자를 위한 DB 튜닝 실전(1편)
▷ 이병국의 개발자를 위한 DB 이야기: 튜닝(32회) : 개발자를 위한 튜닝 실전(2편)
▷ 이병국의 개발자를 위한 DB 이야기: 튜닝(33회) : 개발자를 위한 튜닝 실전(3편)
* 좋은 연재 글이라 펌
개발자에게 맞는 DB 공부방법 찾기: 물리적 분류와 논리적 분류 그리고 인덱스
이병국 andongcn@dreamwiz.com 프리랜서 DB 엔지니어로서 동아제약 전산실에서 SW 개발 업무를 시작으로 프리랜서 개발자로 독립해 활동하던 중 우연한 기회에 DB와 인연을 맺게 됐다. 현재 삼성생명 전산 운영팀에서 쿼리 성능을 개선하는 DB 튜닝과 IOA 업무를 맡고 있다. 개발자 출신의 DB 엔지니어로 활동하면서 개발자에게 DB 관련 지식이 꼭 필요함을 절감했다. ‘정보의 불균형이 시장 왜곡을 가져온다’는 ‘레몬시장이론’은 중고차 거래에서 흔히 나타나기 쉽다. 좋은 차와 나쁜 차를 아는 중개인과 모르는 구매자 사이에는 정보의 비대칭 때문에 구매자가 손해를 볼 수 있다. 구매자도 차에 대해 기본적인 지식을 알고 있어야, 정보의 균형이 맞으므로 서로 손해를 보지 않고 합리적인 가격에 차를 거래할 수 있다. 마찬가지로 개발자들도 DB에 대해 기본적인 지식을 습득하여 정보의 균형을 맞추면, DB 엔지니어와 협업이 더 쉬워지고 한 단계 더 발전한 자신의 모습을 발견할 것이다.
성공과 실패의 경험을 나누자, 용기와 희망을 나누자 개발업무를 시작으로 IT계에 입문했던 필자가 10년 가까이 DB 엔지니어로서 활동하면서 얻은 경험과 지식을 나누고자 한다. DB를 자주 접하는 SW 개발자뿐 아니라, DB 전문가를 꿈꾸는 대학생에서 DB 분야에 입문한 지 1~2년 된 기 입문자가 쉽게 이해할 수 있도록 비유를 통해 쉽게 접근해볼 계획이다. 물론 전문가들이라도 다시 한번 개념을 정립하는 의미에서 필요한 내용이 될 수 있다. 전체적으로 DB의 기본 원리와 개념을 이해하고 테이블, 인덱스, 쿼리, 튜닝, 플랜 등 개발자들이 알아야 하는 DB 전분야에 대해 쉽게 이해하도록 설명하겠다. DB 기술서적이나 번역서보다는 조금 더 부드럽게 접근할 계획이다. 그렇다고 흔히 서점에서 만날 수 있는 개발자 위주의 SQL 소개서도 아니다. 이 연재는 시리즈로 나갈 것이다. 연재를 끝까지 읽는 독자라면, 준전문가 수준의 DB 원리를 아는 것을 목표로 한다.
인류의 역사는 분류의 역사다
지난 연재에서 분류에 대해서 자세히 설명했다. KBS 이산가족 찾기 생방송, 대형할인매장, 개미집구조 등을 예로 들면서 분류의 의미와 장점에 대해서 설명했다. 분류의 특징적인 내용을 요약하면 다음과 같다. 1. 분류의 역사는 인류의 역사와 궤를 같이한다. 2. 분류는 인간 세계뿐만 아니라 동물의 세계에서도 존재한다. 3. 수많은 자료를 정리-관리-검색한다는 의미에서 분류는 DB 그 자체다. 4. 과거의 계층적인 분류부터 최근의 컴퓨터 정보 분류에 이르기까지 분류는 지속적으로 발전했다. 5. 체계적으로 정리된 자료는 검색 시간을 줄이고 비용을 줄인다. 이것이 분류의 힘이다. 이번 연재에서는 물리적 분류와 논리적 분류의 차이점에 대해 설명한다. 또한 지난 연재에서 DB의 많은 부분에서 분류가 활용된다고 했는데, 그 첫 번째인 인덱스에 대해서 소개한다. ‘실마리를 찾다!’ 어떤 일을 새로 시작하였거나 공부를 할 때, 남보다 유독 나만 받아들이기 힘들어 했던 것들이 있지 않았던가? 개발자 출신인 필자도 10년 넘게 DB 엔지니어로 일하면서 유독 받아 들이기 어려웠던 DB의 개념 몇 가지 있었다. 이번 회에서 소개할 ‘DB 인덱스’도 그 가운데 하나다. 눈으로 글을 읽으면 무슨 말인지 짐작은 가는데, 몸이 받아들이지 못했다고나 해야 할까? 그 이유를 나중에 알게 됐다. 이번 회에서는 혹시라도 필자와 같은 고민을 하고 있을 개발자들을 위해 나의 경험을 나누고자 한다.
물리적 분류에서 논리적 분류로
분류는 물리적(직접적) 분류와 논리적(간접적) 분류로 나눌 수 있다. 불과 몇 십 년 전까지는 물리적 분류가 대부분이었다. 물리적 분류는 시각적 분류이기도 하다. 20세기 이전에는 물리적 분류만으로도 충분할 만큼 세상은 복잡하지 않았다. 하지만 정보화 시대에 접어 들면서 세상은 복잡해지고 분류할 정보는 점점 늘어났다. 또한 분류의 규칙과 요구 사항은 점점 다원화됐다. 컴퓨터가 사용되면서 대량의 정보에 대한 분류에도 새로운 방법 적용이 시도됐다. 물리적 분류만으로는 더 이상 이 복잡한 세상을 분류하거나 이해하기 어렵다. 이를 해결 할 수 있는 방법이 논리적 분류이다. 먼저 물리적 분류에 대해 살펴 보자.
물리적 분류: 우리 집 거실의 책장
1년 전 지금 살고 있는 집에 이사 오면서 방에 있는 책장을 거실로 빼고 TV는 안방으로 옮겼다. 가족들이 주로 생활하는 거실을 책 읽는 공간으로 꾸미고 싶었기 때문이다. 처음엔 책장을 분류하면서 자주 보거나 아직 읽지 않은 책들은 책장 1단에, 더 이상 보지 않을 책들은 책장 4단에 꽂아 두었다. 얼마 지나지 않아 이 방법이 옳지 않음을 깨달았다. 키가 작은 둘째가 4단 높이에 있는 책을 보기 위해서 1단 혹은 2단을 딛고서 책을 꺼내는걸 보았다. 책장이 넘어질 것 같아 마음이 조마조마 했다. 결국 지금은 가족들의 키 순으로 책을 다시 분류했다. 둘째가 사용하는 책장 1단은 늘 어지럽다. 책을 읽고 난 후 아무렇게나 두기 때문이다. 분류는 인류의 역사와 함께 시작되었으므로 DNA에 내재되어 있을 법한데, 우리 둘째는 그렇지 않은가 보다. 그렇다면 분류는 후천적인 교육의 산물인지 궁금해진다.
위의 <그림 1>처럼 책을 보관할 실제 공간(책장)에 직접 분류하는 것을 물리적(직접적) 분류라 한다. 기존 분류가 마음에 들지 않으면, 다른 분류 방법으로 재분류하면 된다. 그리고 원하는 책을 빠르게 찾기 위해서는 평소에 늘 분류하고 유지하는 노력이 필요하다. 세상에 공짜로 얻어지는 것은 없다.
물리적 분류의 한계: 방송국 음반 자료실
여러분들이 지금까지 경험하고 인지하는 대부분의 분류는 물리적 분류였다. 만약 라디오 방송국에서 다음과 같은 기준으로 음반을 분류한다고 가정하자(물론 요즘은 디지털화해 파일로 관리하겠지만). 여러분들은 어떻게 분류할 것인가? 현실적으로 분류가 가능한가?
1. 가수를 기준으로 해당 가수의 초창기부터 지금까지 년도별로 분류한다(가수별-년도별).
2. 팝송, 재즈, 클래식, 블루스, 교향곡, 트로트 등 장르를 기준으로 가수별로 분류한다(장르별-가수별).
3. 연도를 기준으로 해당 시기의 가수별로 분류한다(연도별-가수별).
4. 연도를 기준으로 인기가요 순으로 분류한다(연도별-가요 순위별).
5. 국가를 기준으로 가수별-연도별로 세부적으로 분류한다(국가별-가수별-연도별).
방송국의 음악 담당 PD들은 이외에도 더 다양한 분류를 원할 것이다. 이 모든 분류를 동시에 충족할 수 있는 물리적 분류는 존재할까? 단언컨대 없다. 만약 획기적인 물리적 분류 방법이 있다면 알려 주기 바란다
동일한 공간과 동일한 시간에서는 오로지 하나의 물리적 분류만 가능하다. <그림 2>처럼 여러 분류 방법을 동시에 만족하는 물리적 분류는 존재하지 않는다. 만약 동일한 공간이 아니라면, 가능할 수도 있다.
그 대신 분류의 종류만큼 저장 공간이나 음반 수는 배수가 되어야 한다. 또한 동일한 시간이 아니라면 가능할 수? 따라야 한다.
현실적으로 자원(보관 공간, 음반, 시간)이 무한정 제공될 수 없으므로, 결국 동일한 시공간에서 물리적 분류는 한 가지만 존재한다. 그렇다면 동시에 여러 분류를 가능케 하는 해결 방안은 없을까?
분류 대상과 분류 정보를 분리하자
우리가 일상 생활에서 경험한 대부분의 분류는 물리적 분류였다고 이미 말했다. 물리적 분류는 분류 대상과 분류 정보가 1:1의 관계에 있고 일체형이다. 그런데 라디오 방송국 음악 담당 PD들이 원하는 음반 분류는 다양하다. 분류 대상(음반)과 분류 정보(색인)의 관계는 1:1 관계가 아니라 1:n의 관계다. 음반을 나라별, 가수별, 연도별, 장르별, 인기순위별 등 여러 분류로 나눌 수 있어야 한다. 이러한 다양한 분류를 동시에 가능하게 하는 유일한 방법은 분류 대상(음반)과 분류 정보(색인)를 분리하는 것이다. 이것이 논리적 분류다. 정보화 세계에서 대량의 복잡한 자료를 다양하게 분류하는 데 적합한 분류다.
<그림 3>의 음반 자료실에는 분류 대상(음반)이 실제로 보관되어 있는 물리적인 장소로서 음반이 순차적으로 보관되어 있다. 또한 주변에 있는 분류 정보(색인)에는 각각의 분류 특성에 맞는 정보가 구성돼 있으며, 실제 음반에 대한 물리적 위치 정보도 갖고 있다. 이와 같이 분류 대상(음반)과 분류 정보(색인)을 분리함으로써 다양한 분류가 동시에 가능하게 됐다. 논리적 분류는 컴퓨터 대중화와 함께 현재 널리 이용되고 있다. DB의 많은 부분에서도 논리적 분류가 활용되고 있다. 인류의 역사에서 직립 보행의 의미만큼이나, 논리적 분류는 분류의 역사에서 중요한 의미를 갖고 있지 않을까? 부연하자면 인류는 직립 보행을 하기 전에는 4개의 다리로서 걷고, 뛰고, 사냥했다. 그 후 2개의 다리와 2개의 손으로 분리되면서 손은 자유로워졌다. 걷고, 뛰고, 사냥하는 데 있어서 약간의 불편함은 있었지만, 물건을 잡고-던지고-만들고-(열매를) 따는 등의 다양한 역할을 할 수 있게 된 것이다. 인류는 직립 보행을 해서 획기적으로 발전했다기보다는 손이 자유로워져서 발전하게 된 것이라고 한다. 손이 다리에서 분리되어 새로운 역할을 맡았기 때문이다. 마찬가지로 분류 대상과 분류 정보를 분리함으로써, 그동안 (물리적 분류에서) 할 수 없었던 다양한 분류가 동시에 가능하게 되었다. 이러한 논리적 분류는 컴퓨터를 사용하는 정보화 세계에서 중요한 의미를 지닌다.
물리적 분류와 논리적 분류
앞서 소개했듯이, 물리적 분류는 인류 역사와 함께 시작되었던 분류 방식이다. 동일한 시공간에서 유일하게 한 가지 분류만 가능하다고 했다. 반면 논리적 분류는 컴퓨터 사용과 더블어 대량의 정보로 넘쳐나는 정보화 시대에 적합한 분류 방식이다. 분류 대상과 분류 정보를 분리함으로써 동일한 시공간에서 다양한 분류가 가능해졌다. 물리적 분류와 논리적 분류에 대해서 아래와 같이 비교-요약할 수 있다.
인덱스는 논리적 분류
필자가 왜 분류에 대해 이렇게 강조하는지를 여러분은 이미 눈치를 챘을 것이다. 그렇다. DB에서 인덱스는 논리적 분류의 특성을 갖고 있기 때문이다. DB에서 인덱스는 중요한 요소이며, 차지하는 의미는 크다. DBA보다는 특히 개발자에게 아주 중요한 의미를 가진다. DBA에게 인덱스는 DB에서 관리되어야 할 여러 요소 중에서 하나지만, 개발자에게 인덱스는 빈번하게 사용하는 DB의 핵심 요소이기 때문이다.
<표 1>의 논리적 분류의 특성에서 ‘분류 대상과 분류 정보가 분리(종속적)’라고 했다. 여기에서 분류 대상은 테이블과 동일한 의미고, 분류 정보는 인덱스와 동일한 의미다. 또한 종속적 이라는 말은 테이블과 인덱스의 관계가 종속적임을 의미한다. DB에서 테이블을 삭제하면, 인덱스는 자동으로 함께 삭제됨을 우리는 안다. 그래서 테이블과 인덱스의 관계는 종속적인 관계다.
참고적으로 테이블을 삭제할 때 뷰는 자동으로 삭제되지 않는다. 그래서 테이블과 뷰의 관계는 종속적인 관계가 아니다. 뷰는 테이블의 객체 정보를 갖고 있으므로 굳이 함께 삭제할 이유는 없다. 하지만 인덱스(분류 정보)는 테이블(분류 대상)의 위치 정보를 갖고 있으므로, 테이블 삭제 시 자동으로 삭제돼야 이치에 맞다.
<표 1>의 논리적 분류의 특성에서 ‘동일한 시공간에 동시에 다양한 분류 가능’이라고 했다. 이 말은 하나의 테이블에 여러 개의 인덱스가 종속적으로 연결돼 있다는 것으로 이해해도 좋다.
테이블에는 분류 대상이 있고, 인덱스에는 분류 정보가 있다. 테이블은 분류 정보를 갖고 있지 않다. 만약 갖고 있다면, 어떤 문제가 있을까? 분류 대상과 분류 정보가 분리되지 않았다면, 어떤 문제가 발생할까?
1. 저장 공간을 분류의 특성에 맞게 미리 할당해야 한다.
2. 상시적으로 공간 이동을 하여야 하고, 분류를 유지 하는 데 많은 비용이 든다.
3. 오직 하나의 분류만 가능하다.
1번과 2번에서 많은 유지 비용이 필요한 것도 문제지만, 특히 3번에 대한 제약은 심각하다. 데이터에 대한 다양한 분류를 원하는 정보화 세계에서는 치명적인 약점이다. 이러한 이유 때문에 DB를 처음 만든 사람이 테이블과 인덱스를 분리했을 것이다. 그래서 테이블은 분류 대상만을 가지게 되었고, 인덱스는 분류 정보를 갖게 됐다.
분류 대상(테이블)과 분류 정보(인덱스)가 분리되었으므로, 하나의 테이블에 대하여 다양한 분류와 접근이 가능하게 됐다. 약간의 단점도 있겠지만 유리한 점이 훨씬 더 많다.
지식은 그것을 필요로 하는 사람의 몫
DB의 인덱스에 대해서 네이버에서 검색하면 다음과 같은 내용이 조회된다. 또한 DB 관련 도서들을 찾아봐도 아래의 내용과 크게 다르지 않다.
- 인덱스는 책의 목차와 같다.
- 인덱스는 테이블의 원하는 레코드를 빠르게 찾아갈 수 있도록 만들어진 데이터 구조다.
- 인덱스는 SQL 명령문의 처리 속도를 향상시키기 위해서 컬럼에 대해 생성하는 객체다.
- 오라클의 인덱스 내부 구조는 B-tree 구조다.
- 인덱스를 생성하는 구문에 대한 내용… Create Index.........
위는 틀림이 없이 인덱스에 대해 잘 설명했다. 하지만 개발자에게 중요한 것은 인덱스의 목적이나 기능이 아니다. 인덱스 생성 구문도 아니다. 또한 개발자에게 인덱스가 B-tree 구조인지, 그 어떤 구조인지는 그리 중요하지 않다. 인덱스 목적-기능-구조-생성 구문을 몰라도 된다는 것이 아니라, 중요하지 않다는 말을 하고 싶다. 인덱스를 만들고 관리하는 것은 DBA다. 개발자는 인덱스를 어떻게 잘 만들 것인지가 중요하다. 어떻게 잘 분류할 것인지를 고민하는 게 중요하다.
지금까지 개발 및 DB 분야 일을 하면서 인덱스의 중요함을 뼈저리게 느꼈다. 필자가 개발자 초년생이었을 때, 인터넷 검색 서비스에서 인덱스를 공부하거나 DB 관련 책을 보면서 공부했다. 하지만 인덱스에 대해서 잘 알지도 못했고, 인덱스를 잘 만들지도 못했다. 10여 년의 시간이 지난 후, ‘인덱스는 분류’라는 것을 터득했을 때에 비로소 인덱스를 잘 만들게 되었다. 그리고 잘 분류할 수 있게 되었다. 그때부터 인덱스에 대한 어려움은 없었다. 이것을 터득하기까지 10년이라는 먼 길을 돌아왔다.
여러분들은 필자처럼 먼 길을 걷지 않았으면 좋겠다(물론 ‘젊어서 사람을 강하게 함을 부정하지 않는다^^). 지?로 하는 사람의 것’이라고 믿고 있다.
‘인덱스는 논리적 분류’라는 것을 인식하고 접근한다면, 인덱스에 대한 이해가 빠르고, 좋은 인덱스, 최적의 인덱스를 만들 수 있는 시발점이 될 것이다. 인덱스를 만들 때 인덱스와 분류를 연관시켜서 생각하길 바란다. 그때 비로소 인덱스는 편안하게 여러분을 찾아갈 것이다.
지금까지 검색 사이트나 DB 관련 책을 많이 보았지만, 인덱스와 분류를 연관시켜서 설명하는 것을 본적은 없었다. 그래서 약간의 두려움도 있었지만, 이번 연재의 방향이 올바르고 내용이 적합하다는 확신은 있다. 조금이나마 여러분에게 도움이 되었으면 해서 용기를 내서 글을 썼다.
다음 연재는 ‘데이터베이스 인덱스의 오해와 진실’에 대한 글이다. 많은 이들이 잘못 이해하고 있는 인덱스에 대해서 필자가 생각하는 바를 말한다.
용기를 갖자 오라클 DB뿐 아니라 대부분의 DB 구성 알고리즘은 어느 날 ‘하늘에서 뚝 떨어져 새로 만들어진 것’이 아니라 실생활에서 이용되는 혹은 이미 상식 수준에서 인지되는 그런 보편적인 원리를 바탕으로 만들어졌으므로 쉽게 접근하고 이해할 수 있다. 서두에서 말했듯이 ‘레몬시장이론’을 상기하며 DB를 지레짐작으로 어려워하지 말고 용기를 내고 하나씩 터득해 나가기를 바란다. 이 글은 DB 전문가 수준의 이해를 요구하지는 않는다. 단지 DB에 대해서 더 친숙하고 더 쉽게 이해하고 접근하길 바랄 뿐이다. 이 글을 읽으면서 궁금하거나 의문 나는 점이 있으면, 댓글을 달아주실 것을 적극 바란다. 아무리 어렵고 힘든 일이더라고 ‘관계’와 ‘소통’으로 풀어나갈 수 있음을 다시 한 번 믿으며….