데이터베이스란?
전자적으로 저장되고 체계적인 데이터 모음으로 단어, 숫자, 이미지, 비디오 등 모든 유형의 데이터가 포함될 수 있다. DBMS를 사용하면 데이터를 저장 / 검색 / 편집이 가능하다.
RDB
키와 값이라는 아주 간단한 관계를 목록으로 만들어 전산시스템에서 활용할 수 있도록 만든 데이터의 집합이다. RDBRelational Database는 관계형이라는 이름처럼 서로 다른 데이터 집합 간의 관계를 설정할 수 있다는 것이 큰 특징이다. 또한, 정확하고 명시적인 데이터 목록 명세가 미리 등록되어 있어야 한다.
Table (표)
데이터를 관리하기 위해서 가장 기본이 되는 개념으로는 테이블을 알아야한다. 아주 간단하게 생각하자면 엑셀을 떠올리면 된다. 행과 열로 이루어져 좌표 번호를 알면 셀을 찾을 수 있고 해당하는 데이터를 찾을 수 있다.
Tuple, Row (튜플, 행)
튜플이라고 부르기도 하고 쉽게 행이라고 이야기하기도 한다. 튜플은 생소한 단어인데 영문권에서 사용하는 단어로 셀 수 있는 개수의 속성들의 순서 있는 열거를 말한다. 우리가 흔히 접하는 Array<Object>
에서 하나의 요소를 가리켜 이 튜플이라고 생각하면 된다. 직관성때문인지 행이나 로우row라고 더 많이 불린다.
Attribute, Column (속성, 열)
속성이라고 하기도 하고, 열이라고 하기도 한다. 튜플과 같은 이유로 컬럼column이라고 더 많이 불린다.
NoSQL DB
NoSQL은 비관계형, 또는 덜 제약적인 데이터베이스를 일컫는다. 카를로찌라는 사람이 표준 SQL을 사용하지 않은 자신의 경량 관계형 데이터베이스를 가리켜 NOSQL
이라는 단어를 사용했다. 지금 우리가 인지하는 NoSQL과는 거리가 좀 있다. 현재의 NoSQL이라는 개념의 방향을 보아하니 NoREL이 더 적합하다는 의견을 이야기 했다고도 한다.
일부에서는 전통적인 SQL 문법 뿐만 아니라 다른 방식의 엑세스Restful API 등를 가능하게 하는 것으로 Not Only SQL
이라는 뜻으로 이해하기도 한다. 이 해석이 카를로찌가 처음 의도했던 바와 가장 가깝다. 그러나, 흔히 실생활에서 이야기하는 NoSQL이란 비관계형, 또는 덜 제약적인 데이터베이스
를 말한다.
DBMS
데이터베이스 관리 시스템으로 조직적인 SQL을 통하여 데이터를 저장 / 검색 / 편집할 수 있는 소프트웨어를 칭한다.
그냥 파일 쓰면 안돼?
써도 된다. DBMS도 결국엔 파일로 데이터를 저장한다. 그러나 파일 저장, 관리, 검색, 집계, 일괄 처리등 모든 기능을 구현하는 것 보다 잘 되어있는 DBMS를 하나 선정하여 활용하면 더 빠르고 안정성 있는 서비스를 구현할 수 있기 때문에 사용한다. 많이 알려진 DBMS를 사용하면 공동작업자들이 새로운 것을 학습하는 시간을 줄이고 일관성있는 코드를 생산할 수 있다.
또한, 데이터를 관리함에 있어서 성능과 관련된 많은 알고리즘들이 기본적으로 제공되므로 본인이 데이터베이스에 한 획을 그을 야망이 있는 것이 아니라면 그냥 설치해서 쓰는 것을 추천한다.
그럼 데이터는 어떻게 저장하는데?
DB로 작업을 하다보면 의문이 하나 생긴다. 도대체 이 데이터란 놈이 어떻게 저장되는가? 우리가 사용하는 파일과 다른건가? DB라는 것과 내가 저장하는 파일은 뭐가 다른것인가?
결론부터 말하자면 그냥 파일로 저장된다. 저장/검색/필터/편집을 위한 수 많은 알고리즘 기법들이 포함된 압축, 디렉토리 분할 파일 관리 어플리케이션이라고 생각하면 좀 더 쉽게 상상해볼 수 있다. DBMS도 결국 프로그램 중 하나일 뿐이다.
Postgresql
상상이 안된다면 직접 까보도록 하자. 대표적으로 Postgresql이 사용하는 데이터이다. Postgresql이 이런식으로 데이터를 저장한다고 한다. 디렉토리를 구분짓거나 파일명을 결정짓는 방법들도 검색하면 나오는데 궁금하면 찾아보자. 검색에 효율적인 방식으로 저장할 것이다. 자세한 설명은 공식문서 또는 이 포스트에도 간략하게 소개되어 있으니 봐보는 것도 재미있다.
안쪽에 데이터를 찾아서 직접 cat
을 통해 확인해보면 바이너리 파일임을 확인할 수 있다. 우리가 저장하는 파일들을 효율적인 알고리즘을 통해 데이터를 인코딩하여 저장한다.
Opensearch
이번엔 Opensearch를 까보자. 꽤나 복잡한 구조로 이루어져 있는데 위는 Docker
를 통해 올린 컨테이너에서 테스트한 내용이다. 인덱스별로 ID를 따서 내부 디렉토리 구조들과 파일구조로 관리를 하고 있다. hello
의 인덱스 ID를 통해 디렉토리를 접근해보면 또 여러가지 파일들이 존재한다.
임의로 디렉토리를 뒤져서 찾은 거라 정확하진 않다. 로컬 테스트로 데이터를 하나 밀어넣고 디렉토리를 뒤져보니 translog
가 증가하면서 state
안에 여러 파일들이 또 생기고 관리되는걸 볼 수 있었다. cat
을 통해 직접 확인해보면 마찬가지로 인코딩된 데이터들이 저장되어있다. Lucene 엔진 이름도 보이고 중간중간에 밀어넣은 테스트 데이터도 확인할 수 있다.
어떤 형식이든지 Opensearch가 제공해주는 다양한 알고리즘을 통해 나온 결과가 이렇게 관리되고 있음을 확인할 수 있었다. 더 자세히 알고 싶다면 Opensearch 깃헙에 공개된 소스를 까보면 될거 같다. 결론은? 어차피 파일이다.
색인(Index)이란?
사전적의미는 책 속의 낱말이나 구절, 또 이에 관련한 지시자를 찾아보기 쉽도록 일정한 순서로 나열한 목록을 가리킨다. 위 사진처럼 몇 페이지에 뭐가 있는지 정리해둔 것을 목차 또는 색인이라고 한다. 원하는 데이터가 몇 페이지에 있는지 1페이지부터 하나씩 찾을 필요없이 색인을 참고하면 해당 페이지로 바로 건너뛰기어 원하는 데이터를 정확하게 찾을 수 있다.
데이터베이스에서 색인이란?
데이터베이스에서 말하는 색인, 인덱스, 인덱싱도 크게 다른걸 말하는 것은 아니다. 색인한다 라고도 표현하지만 인덱싱 한다라고 표현하기도 한다.
튜플에 대해 추가적인 저장공간을 활용하여 검색 속도를 향상시키기 위한 자료구조를 일컫는다. 말이 어려울 수 있는데 조금 더 쉽게 이야기하면 하나의 행을 저장하고 추가적으로 그 행에 책갈피를 달아둔다는 이야기다. 결국 목차처럼 색인을 만들어 두는 것과 일맥상통한다. 자료를 좀 더 빨리 찾기 위한 자료구조로 비트맵 인덱스, 조밀 인덱스, 희소 인덱스, 역방향 인덱스와 같은 종류들이 있다고 한다.
데이터베이스가 저장하는 데이터의 유형이나 검색하는 방식은 점점 더 많은 데이터가 대상이 될 수록 시간이 더 걸린다는 숙명이 있다. 색인이 되어있지 않다면 데이터베이스는 처음부터 끝까지 찾아야 할 것이며 자료의 위치에 따라 성능이 좌우되는 현상을 보이게 된다. 그렇기 때문에 일반적으로 데이터베이스는 색인을 통하여 쿼리의 성능을 높인다.
데이터를 저장할 때 순서화하고 어디에 저장되어 있는지 일종의 북마크를 찍어두어 다음에 쿼리를 실행할 때 데이터베이스는 이 색인을 참조하여 불필요한 검색 구간을 건너뛰고 검색하려는 데이터가 어디쯤 있는지 선별하여 빠르고 정확하게 원하는 자료를 찾을 수 있다.
이런 색인은 검색뿐만 아니라 갱신과 삭제도 향상시킨다. 갱신과 삭제를 위해서는 반드시 튜플을 먼저 검색해야 하기 때문이다.
Opensearch
실무에서 Opensearch를 사용하고 있기 때문에 공부할 겸 조금 정리해보도록 하겠다.
샤드란?
샤드는 Lucene의 인덱스 인스턴스이다. 데이터 집합에 대한 쿼리를 색인하고 처리하는 검색 엔진이라고 생각할 수 있다.
인덱스란?
[
{
"_index": "my-index",
"_source": {
"name": "hello",
"say": "world",
"props": {
"hello": "world"
}
}
},
// ...
]
Opensearch에서 인덱스
란 앞서 설명한 자료구조를 말하지 않는다. 문서를 모아둘 수 있는 논리적 구분을 뜻한다. 테이블의 개념과 대응된다. 하나의 문서는 중첩된 튜플 형태로 표현할 수 있다. 쉽게 JSONObject를 떠올리면 된다.
js-client의 index()
패키지가 제공하는 index
, create
두가지 모두 문서를 만드는 함수이다. 차이는 index()
의 경우, 동일한 ID의 문서가 있다면 덮어 씌워진다. create()
의 경우는 갱신하지 않는다. 문서가 덮어씌워지지 않아야 하는 로직이 있을 수 있기 때문에 두가지로 나누어 제공하고 있다.