Overview

우리는 대부분의 활동을 스마트폰 하나로 해결할 수 있습니다. 은행에 가지 않아도 앱만 있으면 은행 업무를 할 수 있고, 몇 번의 터치만으로 다양한 물건을 구매할 수 있습니다. 모든 것을 온라인에서 해결합니다. 이 말을 바꿔 말하면, ‘온라인에 연결되지 않았다는 건 대부분의 경제활동에서 벗어났다’는 의미이기도 합니다.

우리가 온라인에서 무언가를 클릭(또는 터치)한다는 건 서버에 호출하는 행위이기도 합니다. 서버가 실시간으로 원하는 결과를 우리에게 다시 보내주는 것이죠. 이렇듯 많은 사람들에게 실시간으로 서버가 자료를 처리하는 과정을 OLPT(Online transaction processing)라고 합니다.


Table의 구조

OLTP 처리를 하려면 DB를 어떻게 설계해야 할까요. 예를 들어봅시다. 모든 웹사이트는 서비스를 이용하려면 우선 회원가입을 해야 합니다. 가입을 할 때는 ID 와 비밀번호를 꼭 만들어야 하고요. 이것을 DB Table로 가정하면 회원 Table은 ID와 암호 컬럼으로 구성될 겁니다.

회원
ID 암호

위의 Table은 가입자 수가 많아지면 운영을 하고 건수가 많아지면 두 가지 문제가 발생합니다. 첫 번째는 ID가 중복된다는 것, 그리고 두 번째는 자료가 많아질수록 가입된 회원의 ID를 가져오는 게 느려진다는 것이죠. 전자의 문제는 Application 단에서 어느 정도 확인할 수는 있지만 다중 사용자 구조에서 중복되지 않는다는 보장을 할 수 없습니다. 후자의 문제는 Table만으로는 해결되지 않습니다. 이를 해결하려면 Index(Primary Key)를 생성해 해결할 수 있습니다.

Index 생성으로 문제를 해결할 수 있다는 게 생소할지도 모릅니다. 우선 Index의 기본적인 구조를 알아야 합니다. 보통 Table에 자료를 Insert하면 입력한 순서대로 자료가 쌓입니다.

회원
입력순서 ID 암호
1 홍길동 1234
2 강감찬 5678
3 이순신 abcd
4 김좌진 efgh

하지만 Oracle Cluster Table과 MySQL InnoDB Table은 Table에는 입력한 순서대로 쌓이지 않고, 특정 KEY에 따라 쌓입니다. 그러므로 모든 테이블이 꼭 위의 예시처럼 순서대로 쌓이진 않습니다. Oracle Cluster Table과 MySQL InnoDB Table은 아래 예시처럼 보여집니다.

회원
입력순서 ID 암호
2 강감찬 5678
4 김좌진 efgh
3 이순신 abcd
1 홍길동 1234

이번에는 Index에서 가장 많이 사용하는 BTree Index를 살펴보겠습니다. Index는 보통 테이블의 자료를 빠르게 검색하기 위해 생성합니다. 1개의 Table 위에 N개의 Index를 생성할 수 있습니다.1) 회원 테이블의 ID를 KEY로 하는 Index를 생성한다고 가정하면 아래와 같은 Index 구조를 가집니다.

회원_ID_Index
ID(KEY) Table 위치 값
강감찬 XXX
김좌진 XXX
이순신 XXX
홍길동 XXX

Index는 KEY의 순서(오름차순 or 내림자순)로 정렬되어 있습니다. 그러므로 N개의 KEY를 지정해 Inedx를 생성하면 N개의 KEY 순서대로 정렬됩니다. 그렇다면 BTree Index는 왜 정렬되어 있을까요? 자료를 찾는 속도가 빠른 것과는 어떤 관계가 있을까요?

자료 구조를 조금이라도 공부했다면 이미 BTree라는 이름에서 눈치채셨을 겁니다. Btree Index는 이진검색(Binary Search)에 기반을 두고 있습니다. Binary Search는 자료가 정렬되어 있는 상태에서 자료의 절반 위치를 찾아가는 구조입니다. (처음 전체의 절반, 절반의 절반 , 그 절반의 절반) 전체를 읽을 때보다 빠르게 원하는 값을 찾을 수 있고, 자료를 읽어내는 속도도 빨라집니다. 이렇게 해서 Index가 생성되어 있다면 Index에서 값을 빠르게 찾을 수 있고, 이 값이 위치한 Table의 레코드를 바로 접근해 원하는 값을 가져올 수 있게 됩니다. Index에서 원하는 값을 빠르게 찾을 수 있기 때문에 Index를 생성할 때 속성(UNIQUE or NON UNIQUE)을 설정해 중복 허용 여부를 지정할 수 있습니다. Index와 Table관계를 표시하면 아래와 같습니다.

회원_ID_Index
ID(KEY) Table 위치 값
강감찬 2
김좌진 4
이순신 3
홍길동 1
회원
입력순서 ID 암호
1 홍길동 1234
2 강감찬 5678
3 이순신 abcd
4 김좌진 efgh




Primary Key

만약 ID의 컬럼 속성을 NOT NULL로 설정하면 중복이 되지 않고 값을 항상 입력합니다. ID의 무결정을 보장하고, 자료도 빠르게 찾을 수 있게 되는데요. 방법은 크게 두 가지로 설정할 수 있습니다. 하나는 Unique Index 와 NOT NULL을 사용하는 것이고, 다른 하나는 Primary Key를 지정하는 것입니다.2) 그렇다면 우리는 어떤 것을 지정하는 것이 좋을까요? 사실 DB 특성과 Table특성, 용도에 따라 달라지기 때문에 정답은 없지만 일반적으로 Primary Key를 지정합니다.

Primary Key를 지정하는 건 몇 가지 이유가 있습니다. 첫째, 논리적으로 Primary Key를 지정해 Table의 기준을 알 수 있습니다. 둘째, 거의 모든 DB가 같은 조건(Index가 여러 개 있을 경우)이라면 Primary Key를 우선적으로 사용합니다. 마지막으로, 특정 DB는 Table(MySQL InnoDB Table)이 Primary Key로 정렬되고, 이것이 위치 값으로 사용되면 다른 Index를 쓰는 것보다 속도가 빠릅니다. 그러므로 가능한 Primary Key를 사용하는 것이 좋고, 그 외의 경우엔 Index를 사용하면 됩니다.


Conclusion

지금까지 OLTP 처리를 할 때의 기본적인 회원 Table 구조와 문제점 및 해결 방안 , 간단한 Index 및 Primary Key를 알아봤습니다. 다음 글에서는 조금 더 확장된 개념인 단일 Table을 Select하는 법을 다뤄보겠습니다. 뭐든 기초가 중요하니까요. 하하..

참고
1) Oracle Bitmap Index의 경우 2개 테이블을 연결하여 1개의 Index를 생성할 수도 있습니다.
2) Primary Key는 NOT NULL컬럼만 지정 가능합니다.


한석종 부장 | R&D 데이터팀
hansj@brandi.co.kr
브랜디, 오직 예쁜 옷만