제목 : PostgreSQL 데이터베이스는 무엇일까?
나는 이전에 파일을 이용하는 데이터베이스 SQLite 를 다룬 적이 있다.
파일 시스템을 이용하는 데이터베이스는 SQLite 뿐만 아니라, H2 라는 데이터베이스도 존재한다.
H2 는 Java 계열에서 사용하는 데이터베이스이며, JDBC 와 연동이 아주 잘 되어 있다.
SQLite 는 안드로이드 시스템에서도 사용되는 파일 데이터베이스이며,
Node 계열에서 TypeORM 라이브러리를 사용 할 때, 연동이 잘 되는 데이터베이스이다.
각각의 언어나 프레임워크에서 사용되는 편리한 파일 데이터베이스는 다를 수 있는데,
이는 프레임워크나 특정 언어에서 테이블 엔티티를 각자 작성했을 때,
자동으로 마이그레이션 해 주는 파일 데이터베이스가 다르기 때문이다.
즉, 데이터베이스 시스템에 직접 들어가 Schema(스키마) 를 직접 제작 해 줄 필요 없이,
어플리케이션을 실행하기만 해도 자동으로 스키마를 생성 해 주는 것이다.
이건 사용 해 보면 너무나도 편리한 라이브러리이다.
다시 돌아와서 PostgreSQL 데이터베이스를 다루는 이유는, 내가 듣던 강의에서
데이터베이스에 대한 설명을 거의 하지 않고 연동만 다루었기 때문이다.
아 물론, 각 언어와 프레임워크마다 데이터베이스를 자동으로 마이그레이션 해 주는 프로그램과 라이브러리가 있어서
딱히 데이터베이스의 시스템을 이해하지 않아도 된다고 생각 할 수도 있다.
그러나, 나는 지난 3 년 동안, 컴퓨터를 이해하지 않고 외우려고만 했던 지난 날들을 매우 반성한다.
외우면 "훌륭한 개발자" 는 될 수 있겠으나, "컴퓨터 엔지니어" 로서의 내 꿈에 다가갈 수 없기 때문이다.
그리고, MySQL 이나, MariaDB 와 같은 훌륭한 데이터베이스도 있지만, 왜 PostgreSQL 이 그렇게 유명한지 궁금하다.
예전에 FireShip 이라는 유튜브 채널에서 PostgreSQL 에 대해 말하는 영상을 본 적이 있는데,
갖출 기능은 전부 갖추었는데, 사용하기가 매우 편리하다고 한다.
그런데, 유명하다 못해 SQL 의 대표격인 MySQL 이 있는데, 왜 PostgreSQL 이 뜨게 된 걸까?
분명히 모던 프로그래밍의 시대가 열리면서, PostgreSQL 의 특정 기능들이 접근성을 넓혔다고 예상했다.
그리고, 이 글을 보기 전에, Google Cloud 에서 PostgreSQL 과 여타 다른 DB 와의 차이점을
너무나도 잘 정리 해 놓은 글이 있다. 이를 먼저 참고하길 바란다!
데이터베이스는 크게 2 가지 종류로 나뉜다.
바로, RDBMS 와, NoSQL 이다.
굉장히 편하게 말하자면, "정형 데이터 vs 비정형 데이터" 라고 볼 수 있다.
NoSQL 의 경우, MongoDB 가 대표적이다.
물론, 이 글에서는 Postgres (PostgreSQL) 에 대해서 다룰 것이다.
Postgres (PostgreSQL) 은 객체 관계형이다?
Postgres 는 아주 정확히 말하자면, ORDBMS 이다.
즉, Object Relational Database Management System 의 약자이다.
그렇다면, RDBMS 와 어떤 차이점을 가지고 있나 찾아보니까,
구글 문서에서 말하길,
RDBMS 는 데이터의 관계형 모델을 기반으로 한다.
ORDBMS 는 클래스, 객체, 상속과 같은 객체 지향 개념을 추가로 지원하는 관계형 모델을 기반으로 한다.
예를 들어, ORDBMS 는 RDBMS 에서 처리할 수 없던 "동영상", "오디오", "이미지" 파일과 같은
데이터 유형을 처리할 수 있다고 한다.
Posgres 와 일반적인 SQL 데이터 서버와의 차이점
그리고 Postgres (PostgreSQL) 의 대표적인 특성은, 완전한 Open Source 라는 것이다.
MySQL, Oracle, MSSQL(마이크로소프트) 와는 달리,
내가 돈 벌 목적으로 사용해도 라이선스 비용을 내지 않는다.
물론, 비슷한 특성을 가진 MariaDB 가 있기는 하다.
그러나, Postgres 와는 서로 다른 특성을 가지고 있기에 선택지가 존재한다.
우선, MariaDB 는 MySQL 의 완전 오픈소스화 버전이다.
MySQL 은 경량화, 속도에 더 유리하다.
따라서, 딱히 비구조화 데이터를 많이 활용하지 않을 경우,
즉, 대부분 정형화 된(정해진) 데이터를 사용 할 경우, MariaDB 가 더 유리하다.
Postgres (PostgreSQL) 은 비구조화 데이터 유형을 지원한다.
예를 들면 오디오, 동영상, 이미지와 같은 데이터를 저장 할 수 있다.
또한 함수, 커스텀 데이터 유형, 언어 등을 추가 할 수 있는 확장이 높다.
요약하자면
MySQL or MariaDB : 빠름, 정형화 데이터에 치중
Postgres(PostgreSQL) : 상대적으로 느림 (그래도 빠른편), 정형화 및 비정형화 데이터 모두 지원
Postgres 는 RDBMS 와 NoSQL 역할 둘 다 가능하다?
Postgres 를 살펴보면서 놀랐던 것은, NoSQL 로서의 역할도 가능하다는 것이었다.
물론, MongoDB 와 같이 NoSQL 전문으로 사용되는 데이터베이스보다는 제한이 있겠지만,
RDBMS 종류에 속하는 Postgres 가 NoSQL 기능도 어느정도 지원하다는 것이 매우 놀라웠다.
그도 그럴 것이, 비정형 데이터를 다룰 때, ACID 원칙이 지켜지지 어려울 것이라고 생각하는데,
어떻게 ACID 를 지키면서 NoSQL 기능을 다루는가? 에 대해 궁금증이 생겼다.
먼저, 이에 대해 훌륭한 글을 남기고 있는 Medium 의 글이 있었다.
Medium - NoSQL Capabilities in PostgreSQL
위의 글은 안타깝게도 매우 길고 영어로 되어 있으므로,
간략하게 요약해 보자.
1. Relational, NoSQL 데이터베이스로서의 PostgreSQL
Postgres 의 굉장히 독특한 관점은, 관계형과 NoSQL 데이터베이스 둘 모두의 기능을 갖추었다는 것이다.
이러한 양 측의 능력은 JSON 에 대한 진보된 지원 뿐만 아니라,
다양한 데이터 타입이 지원되기에,
NoSQL 의 유연성과 관계형 데이터베이스의 안정성 및 무결성이 모두 필요한 어플에 알맞는 선택이다.
2. JSON 과 JSONB 데이터 타입
Postgres 는 JSON 데이터에 대해서 2 가지 데이터 타입을 지원한다.
JSON
JSONB
JSON
은 (JavaScript Object Notation) 의 약자에 알맞게
정확하게 입력 형태에 따라 텍스트 형식으로 데이터가 저장된다.
JSONB
는, (JavaScript Object Notation Binary) 의 약자이다.
JSONB
는, 바이너리 형태로 분해되어 데이터로 저장되는데,
쿼리와 조작을 수행 할 때, 데이터가 이미 바이너리 형태로 파싱되었기 때문에 더 효율적으로 만들어 준다.
3. JSON 데이터 색인(indexing - 인덱싱)
Postgres 의 강점 중 하나는 JSON 데이터를 인덱싱(색인) 하는 능력이라고 한다.
GIN (Generalized Inverted Index) 인덱스를 사용하여 효과적으로 JSONB 데이터를 쿼리 할 수 있다고 한다.
GIN 이란, 역 색인 이라고 한다. 거꾸로 색인을 의미한다는 것 까지는 이해했지만, 어떻게 거꾸로 색인을 하는 것인가?
이에 대한 내용이 Postgres 의 공식 문서에 존재했다.
https://www.postgresql.org/docs/current/gin.html
GIN 은 복합적인 값을 색인 하기 위해 설계되었다.
그리고, 인덱스에서 처리하는 쿼리는 복합적인 값 내에 나타나는 요소를 검색해야 한다.
예를 들어 복잡적인 값은 "문서" 가 될 수 있으며,
쿼리는 특정 단어들을 담고 있는 문서들을 검색 할 수 있다.
그리고 단어를 사용하여 색인(인덱싱) 되어야 할 복잡 값을 참조 할 수 있다.
그리고 단어 key 는 "요소의 값" 을 참조한다.
위의 설명을 보고 "역 색인" 이라는 의미는 이해했지만, GPT 에게 한 번 더 질문했다. (현재 GPT o3)
GPT 의 설명을 보고 요약하자면,
- 하나의 Low 는, 쿼리가 찾는 여러 값을 가질 수 있다. (토큰, 배열, 문서, JSON 객체 등)
- 이 때, 찾고자 하는 토큰이 어느 Low 에 속하는지 역으로 (inverted) 관리한다.
- 예를 들어, "apple" : [doc2, doc6], "car" : [doc2, doc5] 이러한 형식
- 항상 테이블을 생성 할 때, 성능을 위해
CREATE INDEX idx_docs_data ON docs USING GIN (data);
와 같은 인덱스를 생성한다.
Postgres 의 데이터베이스는, 일반적인 정규화 SQL 서버들과는 다른 기능을 가지고 있기에,
따라 올 수 있는 단점들이 생각났다.
- 키가 아닌, 값에 대한 메타데이터 참조 또한 저장하기 때문에 더 많은 저장공간이 필요 할 것이다.
- 추후 메타데이터 저장 및 생성을 위해 로직이 추가되어 있으므로, 데이터 저장 과정에서 딜레이가 발생 할 것이다.
- ACID 를 정확히 지키는 RDBMS 에 속하기 때문에, 메타데이터 색인이 최고조로 최적화 되기는 힘들 것이다.
- 따라서, NoSQL 처럼 메타데이터 조회 시, 방대한 데이터에서는 튜닝이 필요 할 것이다.
그러나, 이전에 수영장 정보에 대한 프로젝트를 진행했을 때,
수영장 검색 창에서 어떠한 키워드가 매칭되었을 때, 해당되는 수영장 목록을 보내주고 싶다는 생각을 했었다.
이는 구글이나 네이버처럼, 자동완성 기능을 넣고 싶은 욕심이었다.
그러나, MariaDB 와 같은 SQL 서버에서 WHERE LIKE '%<키워드>%
를 사용하기에는,
너무 많은 컴퓨팅 리소스가 발생하고, 비효율적이었다.
그러나, 만약에 Postgres 를 사용한다고 가정했을 때,
메타데이터를 저장하는 GIN 의 알고리즘으로 해당 기능을 타협 할 수 있다고 생각한다.
기존의 SQL 서버로 키워드 검색 시
키워드 검색 요청 --> 해당 테이블의 모든 데이터를 훑고, 일치 여부 확인 --> 비효율
Postgres 로 키워드 검색 시
키워드 검색 요청 --> Postgres 의 메타데이터 테이블에서 키워드 검색
--> 키워드에 일치하는 모든 low 검색 및 추출 --> 효율적
예시 :
# 유저는 로그인 이메일, 비번, 유저이름, 스스로의 태그를 가진다. (태그는 스스로 정한다 가정)
CREATE TABLE users (
id serial PRIMARY KEY,
email text,
pwd text,
username text,
tags text[] # GIN 을 사용 할 예정
);
# 특정 태그를 배열에 가지고 있는 유저를 메타데이터로 저장하기 위해 GIN 을 사용하여 색인 구성.
CREATE INDEX idx_users_tags ON users USING GIN (tags);
# tags 배열에 "tech" 키워드를 가진 모든 유저의 이메일을 가져온다.
SELECT email FROM users
WHERE tags @> ARRAY['tech'];
위에서 SQL 문법을 보면 알 수 있듯이, 기존에 사용하지 않았던 @>
라는 키워드를 사용한다.
그리고, ARRAY['<찾는 키워드>']
를 이용한다.
이는 메타데이터 검색 전용 키워드들이라고 생각하면 된다.
AUTO_INCREMENT
대신, serial
을 사용하고 있는 모습도 볼 수 있었다.
또한, Postgres 에서 지원하는 데이터 타입 JSON
과, JSONB
중에서, JSONB
를 예시로 든다면,
먼저, 주문 정보를 "전부" JSONB
형태로 가지고 있다고 가정하자.
# 주문된 제품의 특징을 JSON Binary 정보로 가지고 있다 가정.
CREATE TABLE order_attr (
id serial PRIMARY KEY,
attr JSONB
);
# 딱히 idx 를 넣지 않아도 되지만, 최적화를 위해 넣는다고 가정
CREATE INDEX idx_order_attr ON order_attr USING GIN (attr);
# 미국에서 발송된 모든 제품의 이름을 검색한다고 가정
SELECT attr->>"product_name" AS product_name
FROM order_attr WHERE attr @> '{"sending_country": "USA"}'
JSONB 에 저장되어 있는 key
, value
또한 메타데이터의 토큰으로 저장되어,
@>
키워드로 빠르게 찾을 수 있다.
화살표를 사용하는 것은 JSON
형태에서 특정 속성을 지정하기 위해 사용하는데,
이는 다양한 사용법이 존재하여 검색해 보는 것을 추천한다.
Postgres 의 NoSQL 기능, HStore 데이터 타입?
위에서 다룬 JSONB
, 그리고 JSON
은 JS 객체처럼 엄청난 자유도를 가지고 있다.
위 2 개의 데이터 속성은 데이터 계층에서도 거의 무한한 자유도를 가진다.
그러나, 자주 바뀔 수 있는 테이블의 속성에 대해 대응하는 데이터 타입이 존재한다.
그것이 바로 HStore
데이터 타입이다.
예를 들어, 제품의 속성이다.
제품의 속성 또한 정규화 된 테이블로 "가격", "품목", "이미지 경로" 와 같이 지정 할 수 있겠지만,
제품 그 자체는 다양한 카테고리가 존재한다. 음식, 컴퓨터, 그림, 등등..
다양한 카테고리 또한 정규화 할 수 있겠지만, 카테고리는 생겨 날 수도, 없어 질 수도, 변경 될 수도 있다.
따라서, 이에 알맞는 데이터 타입은 HStore
이라고 할 수 있다.
그러나, HStore
은 {key: value}
로서 하나의 계층만 가질 수 있다.
대신, 여러 쌍을 가질 수 있다.
그리고 HStore 에 들어간 value
에 대해 Unique
를 보장한다는 점이 더욱 놀랍다.
예시 :
# 제품의 "모든" 속성을 전부 커스텀화 하도록 만듬 (실제론 이렇게 만들지 않을 거 같네요)
CREATE TABLE products (
id serial PRIMARY KEY,
attr hstore
)
# 컴퓨터 제품을 등록 해 보자!
INSERT INTO products (attr)
VALUES (
'name=>"Mac Book", category=>"computer", size=>"16 inch", storage=>"1 TB", color=>"Space Gray"'
);
# 제품 중, 컴퓨터 카테고리에 속하는 모든 제품들을 불러오자
SELECT * FROM products
WHERE attr @> 'category=>"computer"';
이 글을 작성하며 배운 것
이 글을 작성하게 된 계기는, Udemy 에서 NestJS 강의 마지막에 존재한다.
해당 강의는 NestJS 에 집중한 강의였지, TypeORM 과 연결하는 PostgreSQL 을 다루는 강의가 아니다.
따라서, 내가 자주 사용하던 데이터베이스인 MySQL 과 MariaDB 가 아니라, 왜 Postgres 를 사용하는지 몰랐다.
물론, 다양한 데이터베이스에 대한 이점과 단점이 존재하겠지만, 왜? Postgres 인지 조사하고 싶었다.
이 참에, 데이터베이스의 특성도 다시 익히고, 모던 기능이 탑재된 데이터베이스의 특성도 알고 싶었다.
나중에 어플리케이션을 제작하게 될 때, 내가 제작하게 될 어플리케이션의 한계점을 더 높이고,
또한 생각날 아이디어를 현실화 시키기 위해서는 다양한 CS 지식은 필수이기 때문이었다.
매우 놀란 것은, Postgres (PostgreSQL) 이 NoSQL 로도 사용 할 수 있다는 것이었다.
정규화가 불가능한 매우 방대한 데이터셋을 다루는 NoSQL 기능으로도 사용할 수 있다니,
이렇게 자유도가 높은 데이터베이스가 있나? 매우 놀랐다.
Postgres 의 기능 커스텀을 통해 사이트를 만든 사람도 있다던데,
나는 이걸 장난으로 받아들였다.
그러나, 기능이 정말 많고, 데이터 유형의 자유도가 높음에 따라 진짜겠구나 생각하고 있다.
정규화 된 데이터베이스는 경량화 되어 있기도 하지만, 기능의 제한도 존재한다.
그러나, 정규화와 비정규화를 동시에 지원하는 Postgres 는, 현대의 어플리케이션 제작에
더욱 특화될 수 있다고 생각한다. 이유는, 방대한 데이터셋을 정의하기 위해 정규화 하는 것도 중요하지만,
때에 따라서 속성이 변경 될 수 있는 비정규화 데이터셋 또한 품을 수 있어야 하기 때문이다.
틀린 내용이 있거나, 의견이 있으시면, 댓글로 달아주시면 감사하겠습니다.
참고 사이트
PostgreSQL 공식 사이트
https://www.postgresql.org/docs/current/datatype-json.html
IBM 테크 블로그 (PostgreSQL 이란 무엇입니까?)
https://www.ibm.com/kr-ko/topics/postgresql
Google Cloud (What-is-postgresql?)
https://www.ibm.com/kr-ko/topics/postgresql
MongoDB 리소스 (SQL 대 NoSQL 데이터베이스 이해)
https://www.mongodb.com/ko-kr/resources/basics/databases/nosql-explained/nosql-vs-sql
Medium 블로그 (제목 : "NoSQL Capabilities in PostgreSQL")
https://medium.com/@dudkamv/nosql-capabilities-in-postgresql-9eec822886d9
'잡다 지식' 카테고리의 다른 글
TypeORM CLI 와 데이터베이스 마이그레이션 (0) | 2025.05.10 |
---|---|
SQLite 데이터베이스는 무엇일까? (0) | 2025.04.01 |
IntelliJ IDEA - TypeScript 전역 모듈 타입 선택하기 (타입 에러 해결) (0) | 2025.03.31 |
Udemy 강의 검은 화면 해결법 macbook - Chrome (크롬) (0) | 2025.03.21 |