프로젝트를 시작하면 다들 기술 스택을 고민한다.
DB는 항상 MySQL
을 사용했는데 최근 2024년 스택오버플로우 결산을 보니 PostgreSQL
이 MySQL
을 제치고 1위가 됐다. 같은 RDBMS인데 전통의 강자를 어떤 이유로 이겼는지도 궁금하고 지금 진행 중인 프로젝트에 어떤 DB를 사용하면 좋을지 고민하고 있기에 한번 싹 정리해보겠다.
DB 선택은 간단해 보일 수 있으나, 시간이 지남에 따라 서비스가 확장되고 사용자 요구사항이 복잡해질수록 이 결정이 프로젝트의 성공과 실패를 좌우한다.
- 모든 서비스의 핵심 자원
- 장기적 관점에서의 확장성을 생각
- 데이터의 일관성과 무결성은 서비스 신뢰도와 직결
➡️ 서비스에 맞지 않는 DB를 선택하면 프로젝트는 산으로 간다는 뜻이다.
프레임워크에 따라 결정하지말고 정확히 필요한 데이터베이스를 선택하자!
하지만... 웹 서비스가 폭발적으로 성장하면서, 빅데이터(Big Data) 시대가 도래하게된다.
초당 수천~수만 건 이상의 요청을 처리해야 하는 환경에서,
기존 RDBMS의 수직 확장 한계와 스키마 유연성 부족은 서비스에 큰 장애물이 되었다.
- 세계에서 가장 널리 사용되는 오픈 소스 RDBMS (였으나 두번째로 밀림)
- LAMP 스택(Linux, Apache, MySQL, PHP)의 핵심 요소로, 다양한 웹 호스팅 환경에서 기본 옵션처럼 취급.
[특징]
[장단점 정리]
장점 | 단점 | |
---|---|---|
장점 | - 배우기 쉽고, 웹 호스팅 환경에서 기본적으로 제공되는 경우가 많음 - 대규모 커뮤니티와 광범위한 레퍼런스 - 스토리지 엔진을 선택해 유연성 확보 | - 일부 고급 기능(PostgreSQL 대비)이 부족할 수 있음 - 대규모 트래픽 처리 시 샤딩, 레플리케이션 설정이 복잡 - 오라클에 인수된 이후, 라이선스 정책 변화 가능성에 대한 우려도 존재 |
단점 | - InnoDB로 안정적인 트랜잭션 처리 가능 - 간단한 쿼리와 CRUD 중심의 애플리케이션에서 탁월한 성능 | - 일부 환경에서 정교한 튜닝이 필요할 수 있음 - 매우 큰 규모(초당 수만 트랜잭션 이상)에 대한 확장성은 다른 DB 대비 제한적 |
-- 1. 데이터베이스 생성
CREATE DATABASE IF NOT EXISTS myapp_db;
USE myapp_db;
-- 2. 테이블 생성 (InnoDB 엔진)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 3. 데이터 삽입 (Create)
INSERT INTO users (username, email)
VALUES ('alice', 'alice@example.com'),
('bob', 'bob@example.com');
-- 4. 데이터 조회 (Read)
SELECT * FROM users;
-- 5. 데이터 수정 (Update)
UPDATE users
SET email = 'alice@newmail.com'
WHERE username = 'alice';
-- 6. 데이터 삭제 (Delete)
DELETE FROM users
WHERE username = 'bob';
[특징]
[장단점 정리]
장점 | 단점 | |
---|---|---|
장점 | - ACID 트랜잭션, 풍부한 SQL 표준 기능 - 지리 정보, 반정형 데이터(JSON) 등 다양한 유형 지원 - SQL 표준 준수도가 높아 이식성(Portability) 우수 | - 초기 설정이 다소 복잡 - MySQL 대비 자료와 호스팅 지원이 적을 수 있음(최근에는 많이 개선) |
단점 | - 대규모 트랜잭션 처리에 강함 - 복잡한 쿼리, 통계, 분석 업무에 최적 - 윈도우 함수/CTE 등을 통한 쿼리 최적화 | - 실행 계획이 복잡해질 수 있고, 튜닝을 위한 학습 곡선이 있음 - 기능이 많아 메모리 및 디스크 사용량 증가 가능 |
금융, 정부, 대기업 프로젝트 : 데이터 무결성과 보안이 중요하며, 복잡한 모델링과 트랜잭션을 요구하는 시스템
GIS / 지도 / 위치 기반 서비스 : PostGIS 확장을 통해 고급 지리 연산을 처리 (예: 맵핑, 거리 계산, 겹치는 영역 탐색 등)
웹 애플리케이션 + JSON 혼합 데이터 : RDBMS의 안정성과 NoSQL 스타일 문서 저장을 함께 구현 가능
-- PostgreSQL
CREATE DATABASE myapp_db;
-- 테이블 생성
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
profile JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 데이터 삽입
INSERT INTO users (username, email, profile)
VALUES (
'charlie',
'charlie@example.com',
'{"age": 30, "hobbies": ["coding", "music"]}'
);
-- JSONB 필드 쿼리
SELECT
username,
email,
profile ->> 'age' AS user_age
FROM users;
-- JSONB 필드 업데이트
UPDATE users
SET profile = jsonb_set(profile, '{age}', '31'::jsonb)
WHERE username = 'charlie';
-- 데이터 삭제
DELETE FROM users
WHERE username = 'charlie';
[특징]
장점 | 단점 | |
---|---|---|
Oracle | - 최고 수준의 안정성과 고가용성 - 엔터프라이즈 기능(RAC, Data Guard 등) 풍부 - 전 세계 대기업과 금융권에서 오랜 레퍼런스 축적 | - 높은 라이선스 비용 및 유지보수 비용 - 전문 DBA가 필요할 정도로 복잡한 설정 |
MS SQL Server | - Windows/.NET 생태계와 최적 통합 - SSMS(SQL Server Management Studio)로 편리한 GUI 관리 - BI 기능(SSIS, SSRS 등) 내장 | - OS 종속성(주로 Windows 서버에서 최적) - 대규모 트래픽은 Oracle 대비 경험치가 적을 수 있음 |
-- Oracle DB 예시 (SQL*Plus 환경)
-- 스키마/사용자 생성
CREATE USER myapp_user IDENTIFIED BY myapp_pw
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA 100M ON users;
GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE VIEW TO myapp_user;
-- 사용자 전환
CONNECT myapp_user/myapp_pw;
-- 테이블 생성
CREATE TABLE users (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username VARCHAR2(50) NOT NULL,
email VARCHAR2(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 데이터 삽입
INSERT INTO users (username, email)
VALUES ('alice', 'alice@example.com');
COMMIT;
-- 데이터 조회
SELECT * FROM users;
-- 데이터 수정
UPDATE users
SET email = 'alice@newmail.com'
WHERE username = 'alice';
COMMIT;
-- 데이터 삭제
DELETE FROM users
WHERE username = 'alice';
COMMIT;
잘 모르는 내용이에요 죄송합니다. 하지만 열심히 작성했어요.
// 1. 데이터베이스 및 컬렉션 선택
use myProject;
// 2. 문서 삽입
db.users.insertMany([
{ username: "alice", email: "alice@example.com", hobbies: ["reading", "cycling"] },
{ username: "bob", email: "bob@example.com" }
]);
// 3. 문서 조회
db.users.find({ username: "alice" });
// 4. 문서 수정
db.users.updateOne(
{ username: "bob" },
{ $set: { email: "bob@newdomain.com" } }
);
// 5. 문서 삭제
db.users.deleteOne({ username: "alice" });
# 1. 키-값 삽입
SET user:1 "alice"
SET user:2 "bob"
# 2. 키-값 조회
GET user:1
# "alice"
# 3. 키 삭제
DEL user:2
-- 1. 키스페이스(Keyspace) 생성
CREATE KEYSPACE IF NOT EXISTS myapp
WITH replication = {
'class': 'SimpleStrategy',
'replication_factor': '1'
};
USE myapp;
-- 2. 테이블 생성
CREATE TABLE users (
username TEXT PRIMARY KEY,
email TEXT,
created_at TIMESTAMP
);
-- 3. 데이터 삽입
INSERT INTO users (username, email, created_at)
VALUES ('alice', 'alice@example.com', toTimestamp(now()));
-- 4. 데이터 조회
SELECT * FROM users WHERE username = 'alice';
-- 5. 데이터 업데이트
UPDATE users
SET email = 'alice@newmail.com'
WHERE username = 'alice';
-- 6. 데이터 삭제
DELETE FROM users
WHERE username = 'alice';
// 1. 노드 생성
CREATE (alice:Person { name: "Alice" })
CREATE (bob:Person { name: "Bob" });
// 2. 관계(엣지) 생성
MATCH (a:Person { name: "Alice" }), (b:Person { name: "Bob" })
CREATE (a)-[:FRIEND_OF]->(b);
// 3. 데이터 조회 - 관계 탐색
MATCH (p:Person)-[:FRIEND_OF]->(friend)
RETURN p.name AS Person, friend.name AS Friend;
DB 선택... 프로젝트 설계 따라 고심 한번 해보면 좋을 것 같아요!
https://www.quora.com/What-is-the-difference-between-SQL-NoSQL-MySQL-and-PostgreSQL
https://stackshare.io/stackups/mariadb-vs-mysql-vs-postgresql
https://fourwingsy.medium.com/graphql%EC%9D%84-%EC%98%A4%ED%95%B4%ED%95%98%EB%8B%A4-3216f404134
정말 많은 DB들이 있었네요. 프로젝트하면서 여러가지 써보면 좋을 것 같습니다.
잘 보고 갑니다.