데이터베이스는 현대 IT 시스템의 핵심 요소이며, NoSQL 데이터베이스는 대규모 데이터를 유연하고 효율적으로 처리하는 데 강력한 도구가 됩니다. 본 글에서는 MongoDB와 Cassandra를 중심으로 NoSQL 데이터베이스의 개념, 장점, 설계 원칙, 그리고 실제 활용 사례를 다루겠습니다.
1. NoSQL 데이터베이스란?
NoSQL은 “Not Only SQL“의 약자로, 관계형 데이터베이스(RDBMS)와 달리 스키마리스(Schema-less) 구조와 수평적 확장(Scale-out) 기능을 지원하는 데이터베이스를 의미합니다. 일반적으로 다음과 같은 특징을 가집니다.
• 비정형 및 반정형 데이터 저장: JSON, XML, Key-Value, Wide-column 형식으로 데이터를 저장.
• 유연한 스키마: 사전 정의된 테이블 구조 없이 데이터를 동적으로 저장 가능.
• 수평적 확장: 샤딩(Sharding)과 복제(Replication)를 통해 확장 용이.
• 고성능 처리: 대량의 읽기/쓰기 작업을 빠르게 처리.
대표적인 NoSQL 유형에는 문서(Document)형, 키-값(Key-Value)형, 열(Column)형, 그래프(Graph)형이 있으며, MongoDB와 Cassandra는 각각 문서형과 열형 데이터베이스를 대표합니다.
2. MongoDB 개요 및 설계 원칙
MongoDB란?
MongoDB는 문서(Document) 기반의 NoSQL 데이터베이스로, JSON과 유사한 BSON 포맷을 사용하여 데이터를 저장합니다. 유연한 스키마와 강력한 쿼리 기능 덕분에 웹 애플리케이션, 빅데이터 처리, IoT 시스템에서 많이 사용됩니다.
MongoDB의 주요 특징
- 스키마리스 구조: 컬렉션(Collection) 내 문서(Document)마다 다른 필드를 가질 수 있음.
- 강력한 인덱싱: B-tree 기반의 인덱싱과 복합 인덱스를 지원.
- 샤딩 및 복제: 데이터 노드를 자동으로 분산하여 고가용성을 보장.
- Aggregation Framework: 강력한 데이터 분석 기능 제공.
MongoDB 설계 원칙
1) 문서 구조 최적화
MongoDB는 데이터를 JSON 문서 형태로 저장하므로, 데이터 모델을 어떻게 구성하느냐가 성능에 직접적인 영향을 줍니다.
- 중첩(Nesting) vs. 참조(Referencing)
- 중첩(Nested Documents): 관계가 깊은 데이터를 한 문서에 저장.
- 참조(Referenced Documents): 데이터 중복을 줄이고 개별적으로 관리할 필요가 있을 경우.
예를 들어, 전자상거래 시스템의 주문 정보를 저장하는 방법을 보면:
중첩 방식:
{
"order_id": "12345",
"customer": { "name": "홍길동", "email": "hong@example.com" },
"items": [
{ "product": "노트북", "price": 1500000 },
{ "product": "마우스", "price": 25000 }
]
}
참조 방식:
{
"order_id": "12345",
"customer_id": "67890",
"items": ["98765", "87654"]
}
2) 샤딩(Sharding) 전략
MongoDB는 샤딩을 통해 데이터 수평 분할(Scale-out)이 가능합니다. 샤딩 키(Sharding Key)를 잘 선택해야 성능 최적화가 가능합니다.
- 해시 샤딩(Hash Sharding): 데이터 균등 분배 (장점: 균등 분포, 단점: 범위 쿼리 비효율)
- 범위 샤딩(Range Sharding): 특정 범위 기준으로 데이터 배치 (장점: 범위 쿼리 효율, 단점: 특정 샤드에 부하 집중)
3) 복제(Replication) 및 인덱싱 최적화
- 복제 세트(Replica Set)를 사용하여 장애 발생 시 자동 페일오버(Failover) 지원.
- 인덱스 최적화를 위해 Compound Index, TTL Index를 활용.
3. Cassandra 개요 및 설계 원칙
Cassandra란?
Cassandra는 분산형(NoSQL) 컬럼 패밀리 데이터베이스로, Facebook에서 개발하여 오픈소스로 공개된 이후, 대규모 데이터 처리에 강한 성능을 제공하는 데이터베이스입니다.
Cassandra의 주요 특징
- 완전한 분산형(Decentralized): 특정 마스터 노드 없이 모든 노드가 동일한 역할을 수행.
- 수평적 확장(Linear Scalability): 노드 추가만으로 성능 확장 가능.
- 고가용성(High Availability): 여러 데이터 센터에 복제 가능.
- 튜닝 가능한 일관성(Consistency): QUORUM, ONE, ALL 등의 일관성 수준 설정 가능.
Cassandra 설계 원칙
1) 테이블 구조 설계
Cassandra는 열(Column) 기반 스토리지이며, 데이터는 Key-Value 구조를 기반으로 구성됩니다.
- Row Key: 기본 키 역할 (데이터 파티셔닝의 기준).
- Column Family: 비슷한 성격의 데이터를 저장하는 테이블 개념.
예를 들어, 사용자 로그인 데이터를 저장하는 테이블 설계를 보면:
CREATE TABLE user_logins (
user_id UUID PRIMARY KEY,
last_login_time TIMESTAMP,
ip_address TEXT
);
2) 파티셔닝 전략
Cassandra는 데이터를 분산 저장하기 위해 Consistent Hashing을 활용합니다. 파티셔닝 키를 적절히 설정하면 부하 분산이 가능합니다.
- RandomPartitioner: 균등한 데이터 분배.
- ByteOrderedPartitioner: 범위 기반 검색에 유리하지만 특정 노드에 부하 집중 가능.
3) 데이터 복제 및 일관성
Cassandra는 튜닝 가능한 일관성 수준을 지원하며, Replication Factor(RF) 설정을 통해 데이터 내구성을 조정할 수 있습니다.
- Replication Factor 3: 3개의 노드에 동일한 데이터를 저장.
- Consistency Level: QUORUM: 다수 노드 응답 시 트랜잭션 확정.
4. MongoDB vs. Cassandra 비교
항목MongoDBCassandra
데이터 모델 | 문서(JSON) | 컬럼 패밀리 |
확장성 | 수평적 확장(샤딩) | 수평적 확장(노드 추가) |
쓰기 성능 | 비교적 낮음 (트랜잭션 지원) | 매우 빠름 (쓰기 최적화) |
읽기 성능 | 높은 성능 | 노드 간 복제 지연 발생 가능 |
사용 사례 | 웹 애플리케이션, IoT | 로그 분석, 데이터 웨어하우스 |
5. 예제 SQL 및 쿼리 코드
MongoDB와 Cassandra의 설계 원칙을 보다 명확하게 이해할 수 있도록 예제 SQL 및 쿼리 코드를 간단하게 살펴보겠습니다.
MongoDB에서는 "MongoDB Query Language(MQL)"을, Cassandra에서는 "CQL(Cassandra Query Language)"을 사용합니다.
MongoDB 설계 및 예제 코드
1) 컬렉션 생성 및 데이터 삽입
MongoDB에서는 use 명령어를 사용하여 데이터베이스를 선택한 후, insertOne() 또는 insertMany()를 사용하여 데이터를 삽입할 수 있습니다.
예제: 전자상거래 주문 데이터 저장
use ecommerce
db.orders.insertOne({
"order_id": "ORD12345",
"customer": {
"customer_id": "CUST67890",
"name": "홍길동",
"email": "hong@example.com"
},
"items": [
{"product": "노트북", "price": 1500000, "quantity": 1},
{"product": "마우스", "price": 25000, "quantity": 2}
],
"order_date": new Date(),
"status": "shipped"
})
2) 데이터 조회
MongoDB에서는 find() 메서드를 사용하여 데이터를 조회할 수 있습니다.
예제: 특정 고객의 주문 조회
db.orders.find({"customer.customer_id": "CUST67890"})
예제: 주문 상태가 shipped인 주문 조회
db.orders.find({"status": "shipped"})
예제: 특정 가격 이상의 제품을 포함한 주문 조회 ($gt 연산자 사용)
db.orders.find({"items.price": {$gt: 1000000}})
3) 인덱스 설정
MongoDB에서는 성능 최적화를 위해 인덱스(Index) 를 설정할 수 있습니다.
예제: customer_id 필드에 인덱스 추가
db.orders.createIndex({"customer.customer_id": 1})
이는 주문 데이터를 고객 ID 기준으로 빠르게 검색할 수 있도록 도와줍니다.
4) 데이터 업데이트
예제: 특정 주문의 배송 상태 업데이트
db.orders.updateOne(
{"order_id": "ORD12345"},
{$set: {"status": "delivered"}}
)
5) 데이터 삭제
예제: 특정 고객의 모든 주문 삭제
db.orders.deleteMany({"customer.customer_id": "CUST67890"})
Cassandra 설계 및 예제 코드
Cassandra에서는 CQL을 사용하여 테이블을 생성하고 데이터를 저장합니다.
1) 테이블 생성
Cassandra에서 테이블을 생성할 때는 PRIMARY KEY를 적절히 설정하여 데이터의 **파티셔닝(Partitioning)**을 고려해야 합니다.
예제: 주문 테이블 생성
CREATE TABLE ecommerce.orders (
order_id UUID PRIMARY KEY,
customer_id UUID,
product_name TEXT,
price DECIMAL,
quantity INT,
order_date TIMESTAMP
) WITH CLUSTERING ORDER BY (order_date DESC);
위에서 order_id가 PRIMARY KEY 역할을 하며, order_date DESC 옵션을 추가하여 최신 주문이 먼저 조회되도록 설정하였습니다.
2) 데이터 삽입
Cassandra에서 데이터를 삽입할 때는 INSERT INTO를 사용합니다.
예제: 주문 데이터 삽입
INSERT INTO ecommerce.orders (order_id, customer_id, product_name, price, quantity, order_date)
VALUES (uuid(), uuid(), '노트북', 1500000.00, 1, toTimestamp(now()));
- uuid() : UUID를 자동 생성하는 함수.
- toTimestamp(now()) : 현재 시간을 TIMESTAMP로 변환.
3) 데이터 조회
예제: 특정 고객의 모든 주문 조회
SELECT * FROM ecommerce.orders WHERE customer_id = uuid('550e8400-e29b-41d4-a716-446655440000');
Cassandra는 분산 시스템이므로 WHERE 절에서 반드시 PRIMARY KEY(또는 PARTITION KEY)를 사용해야 합니다.
예제: 최신 10개 주문 조회
SELECT * FROM ecommerce.orders ORDER BY order_date DESC LIMIT 10;
4) 인덱스 추가
Cassandra는 기본적으로 보조 인덱스(Secondary Index)를 권장하지 않지만, 특정 필드에 대해 빠른 검색이 필요할 경우 CREATE INDEX를 사용할 수 있습니다.
예제: 제품명(Product Name)으로 검색할 수 있도록 인덱스 추가
CREATE INDEX ON ecommerce.orders (product_name);
5) 데이터 업데이트
Cassandra는 UPDATE문을 지원하지만, UPSERT 방식으로 동작합니다. 즉, 데이터가 존재하면 업데이트하고, 없으면 삽입됩니다.
예제: 주문 수량 변경
UPDATE ecommerce.orders
SET quantity = 2
WHERE order_id = uuid('123e4567-e89b-12d3-a456-426614174000');
6) 데이터 삭제
예제: 특정 주문 삭제
DELETE FROM ecommerce.orders WHERE order_id = uuid('123e4567-e89b-12d3-a456-426614174000');
예제: 특정 고객의 모든 주문 삭제
DELETE FROM ecommerce.orders WHERE customer_id = uuid('550e8400-e29b-41d4-a716-446655440000');
MongoDB vs. Cassandra 예제 코드 비교
기능 | MongoDB (MQL) | Cassandra (CQL) |
테이블(컬렉션) 생성 | db.createCollection("orders") | CREATE TABLE orders (...) |
데이터 삽입 | db.orders.insertOne({...}) | INSERT INTO orders (...) VALUES (...) |
데이터 조회 | db.orders.find({...}) | SELECT * FROM orders WHERE ... |
인덱스 추가 | db.orders.createIndex({...}) | CREATE INDEX ON orders (...) |
데이터 업데이트 | db.orders.updateOne({...}) | UPDATE orders SET ... WHERE ... |
데이터 삭제 | db.orders.deleteOne({...}) | DELETE FROM orders WHERE ... |
5. 결론
MongoDB와 Cassandra는 각각 강력한 기능을 갖춘 NoSQL 데이터베이스로, MongoDB는 유연한 문서 저장 및 분석에 적합하고, Cassandra는 고속 쓰기 및 분산 시스템에 강점이 있습니다. 최적의 NoSQL 데이터베이스를 선택하려면 데이터 특성과 사용 목적을 고려한 설계가 필수적입니다.
'컴퓨터과학' 카테고리의 다른 글
샤딩과 데이터 분할: 대용량 데이터 시대의 최적 솔루션! (1) | 2025.02.01 |
---|---|
SQL 쿼리를 더 빠르게! Query Planner & Execution Plan 이해하기 (4) | 2025.01.31 |
분산 데이터베이스 설계: 핵심 개념과 설계 원칙 (0) | 2025.01.29 |
트랜잭션 관리 심화: ACID와 MVCC의 이해와 활용 (1) | 2025.01.28 |
데이터베이스 인덱싱 구조: B-Tree와 Hash Indexing의 모든 것 (0) | 2025.01.27 |