CS로 알아보는 프로젝트 - RDB와 INDEX

안녕하세요.

 

많은 분들이 프로젝트를 진행하며 SQL 관계형 데이터 베이스와 NoSQL 사용에 있어 다양한 고민이 있을 것이라 생각합니다.

 

여러분들은 언제 RDB를 선택하고 언제 NoSQL를 선택하시나요?? 

 

단순히 조회가 많다면 NoSQL를 사용해야 한다고 생각하시는 분들도 있으리라 생각합니다.

 

지금부터 NoSQL과 SQL의 차이를 알아보고 언제 어떤 것을 선택하는 것이 더욱 적합한지 최적화 방식은 없는 것인지에 대해 알아보겠습니다.

 

오늘은 두 개의 데이터 베이스 중 관계형 데이터 베이스에 대해서 자세히 알아보도록 하겠습니다.

 

 

먼저 DBMS에 대해 알아볼까요? 

 

DBMS는 DB를 사용하기 위해 사용되는 소프트웨어입니다.

대표적으로 MySQL, Oracle 등이 존재합니다.

 

DB의 유형으로는 계층형, 망형, 관계형, 객체지향형, 객체관계형 등이 존재합니다.

 

가장 널리 사용되고 있는 방식은 RDB라고 불리는 관계형 DBMS입니다.

 

 

그럼 RDB는 무엇일까요? 

 

테이블, 행, 열의 정보를 구조화하는 방식입니다.

테이블을 조인하여 정보 간 관계 또는 링크를 설정할 수 있는 기능을 통해, 여러 데이터 포인트 간의 관계를 쉽게 정의하고 정보를 얻을 수 있습니다.

대표적으로 MySQL, PostgreSQL, MariaDB, Oracle, MS SQL Server 등이 존재합니다.

 

그럼 RDB의 장점과 단점은 무엇이 있을까요? 

 

먼저 장점입니다. 

ACID 원칙을 따르기 때문에 데이터의 일관성과 무결성을 보장할 수 있습니다.

표준화된 SQL를 사용하기에 다른 데이터 베이스 모델에 비해 학습이 쉽고 데이터를 처리하는 속도가 빠른 편입니다.

표준을 사용하기 때문에 대부분의 DBMS에 공통적으로 사용할 수 있다는 장점이 존재합니다.

수직 및 수평적 확장이 가능하기 때문에 큰 규모의 서비스에서 사용할 수 있습니다.

 

 

장점이 존재하 듯 단점 또한 존재하는데요.

 

대용량 데이터를 처리하기에는 한계가 존재하며, 복잡한 데이터 구조를 처리하기에는 어렵다는 단점이 존재합니다.

테이블 간의 관계가 복잡해질수록 성능이 저하되는 문제도 야기할 수 있습니다.

 

 

 

그럼 대용량 데이터를 사용할 때 무조건 NoSQL를 사용해야 할까요? 

꼭 그런 것은 아닙니다. 

 

RDB에서도 충분히 성능 최적화를 통해 대용량 데이터를 효과적으로 다룰 수 있습니다. 

심지어 일관성과 무결성을 유지하면서까지 말이죠! 

그럼 어떻게 해야할까요? 

 

다양한 방법 중 첫 번째 방법으로는 Index를 활용하는 방법입니다. 

 

데이터 베이스에서 Index 많이 들어보셨을 텐데요 Index가 무엇일까요.

 

데이터의 저장 성능(Insert, update, delete) 성능을 포기하는 대신 읽기 속도를 높이는 자료 구조를 의미합니다.

 

다만, 인덱스를 생성할 때 DB의 지점을 저장해야 하기 때문에 10% 정도의 추가 공간이 필요하게 됩니다. 

 

그렇지만 원하는 레코드의 위치를 index로 등록해 두어 레코드를 찾는 속도를 빠르게 할 수 있습니다.

 

 

그럼 Index는 어디에 설정해야 하는 것일까요? 

 

아래와 같은 부분에 설정해 준다면 보다 효과적으로 설정할 수 있습니다. 

WHERE 절에 자주 등장하는 컬럼을 인덱스로 설정
ORDER BY 절에 자주 등작하는 컬럼을 인덱스로 설정
SELECT 절에 자주 등장하는 컬럼들을 잘 조합해서 인덱스로  설정
JOIN이 자주 사용되는 열에 인덱스를 생성해주는 것이 좋음

 

 

Index를 설정한다고 해서 무조건 빨라지는 것이 아닙니다. 

조회하고자 하는 데이터가 전체 데이터의 10 ~ 15% 이내일 경우에만 Index를 타는 것이 효과적입니다.

 

 

그럼 MySQL에서 Index를 구현할 때  사용하는 B-Tree 알고리즘에 대해 알아볼까요?

 

기존에 OOO를 검색하기 위해서는 전체 페이지를 탐색해야 하기 때문에 3개의 Page를 순회해야 찾을 수 있습니다. 

 

하지만 B_Tree Index를 사용하게 된다면 2개의 Page를 순회하여 보다 빠른 조회가 가능하게 됩니다.

 

 

 

 

그럼 Index는 어떤 것들이 존재할까요.

 

인덱스는 크게 2종류로 나누어집니다. 

 

클러스터 인덱스와 보조 인덱스입니다. 

 

하나하나 자세히 알아보도록 하겠습니다. 

 

 

 

클러스터 인덱스는 primary index라고도 불립니다. 

 

그 이유는 MySQL에서 Primary Key가 있다면 Primary Key를 Cluestered Index로 활용하기 때문입니다.

 

클러스터 인덱스의 특징에 대해 설명드리도록 하겠습니다.

 

1. 나열된 데이터를 일정 기준으로 정렬해 주는 인덱스입니다.

 -> 클러스형 인덱스 생성 시에는 데이터 페이지 전체가 다시 정렬됩니다, => 해당 과정에서 데이터가 많다면 부하가 발생할 수 있습니다.

 

2. 한 개의 테이블에 한 개씩만 만들 수 있습니다. 

 

3. 보조 인덱스 대비 검색 속도는 빠르나 입력/ 수정/ 삭제의 경우 더 느리다는 단점이 존재합니다. 

 

위 데이터 페이지에 클러스터 인덱스를 생성해 보도록 하겠습니다. 

 

인덱싱을 하면 루트 페이지가 만들어집니다. 

-> 루트 페이지의 경우 각 데이터 페이지의 첫 번째 데이터만 모아 매핑 시키는 페이지입니다. 

또한, 데이터가 자동으로 정렬됩니다. 

데이터 페이지 자체를 인덱스 페이지로 하는 특징이 있습니다. 

 

만약,  LJB 임재범을 찾고 싶다면 루트 페이지에서 KBS로 들어가는 작업과 이와 매핑된 1001번 페이지에 들어가서 임재범을 찾는 과정 즉, 2페이지 만에 조회가 가능하게 됩니다. 

 

정렬이 되어있기 때문에 조회가 매우 빠르다는 장점이 존재합니다. 

즉, 영어사전에서 단어를 찾는 것과 매우 비슷하다고 생각해 주시면 좋을 것 같습니다. 

 

 

 

클러스터 인덱스를 이용하여 데이터를 삽입하는 과정에 대해 말씀드려 볼까 합니다. 

 

FNT  데이터를 추가하는데 1000번 페이지에 공간이 없어 페이지 분할이 일어나 2000번 페이지가 생기게 됩니다. 

 

이처럼 정렬이 되어있기 때문에 오히려 삽입 삭제를 할 때, 페이지 분할이나 추가적인 정렬이 필요하게 되어 성능 저하를 야기할 수 있습니다. 

 

 

 

그럼 보조 인덱스를 알아볼까요? (Secondary Index)

 

보조인덱스는 아래와 같은 특징을 가지게 됩니다. 

1. 데이터 페이지는 그냥 둔 상태에서 별도의 페이지에 인덱스를 구성한다.

2. 인덱스 자체의 리프 페이지는 데이터가 아니라 데이터가 위치하는 주소 값을 가진다.

3. 클러스터 인덱스보단 속도가 느리지만 수정/ 삭제/ 삽입의 경우 덜 느리다.

4. 후보키에만 부여할 수 있다. 

 

보조 인덱스 역시 루트 페이지가 만들어지게 됩니다.

다만, 데이터 페이지에 바로 연결시키지 않고 따로 리프 페이지를 만들어서 매핑 후 정렬을 하게 됩니다.

추가 공간이 필요하며, 인덱스를 남용하게 된다면 공간 낭비로 이어질 수 있는 위험성이 존재합니다.

또한, 데이터 페이지는 편화를 주지 않기 때문에 클러스터 인덱스와 달리 어러 개 생성이 가능합니다. 

 

 

추가로 클러스터 인덱스와 보조 인덱스를 함께 사용하는 방법도 존재합니다. 

 

어떠신가요? 

 

RDB에서도 성능을 최적화할 수 있는 방안이 있고 NoSQL대비 장점을 갖는 부분도 많이 존재합니다. 

 

반면, NoSQL이 장점이 가지는 부분도 존재하죠.

 

다음 포스팅에서는 RDB에서 Index를 활용하는 방법에서 물리적으로 성능을 향상할 수 있는 Partioning과 Sharding을 다뤄보도록 하겠습니다. 

 

감사합니다.