관계형 데이터베이스(RDBMS) 방식을 MongoDB로 바꾸기위한 NoSQL에서 관계 설정 방법
기본 참조 방식은 참조된 문서의 ID를 다른 문서에 저장하여 관계를 맺는 방식이다. MongoDB에서는 DBRef를 사용하거나, 단순히 다른 문서의 _id 값을 저장하는 방식이 있다.
@Document(collection = "chatmessages")
public class ChatMessage {
@Id
private String id;
private String message;
@DBRef
private Chatroom chatroom; // 참조된 문서 ID
}
{
"_id": "chatroom1",
"name": "General Chat",
"members": [
{ "$ref": "Member", "$id": "member1" },
{ "$ref": "Member", "$id": "member2" }
],
"messages": [
{ "$ref": "ChatMessage", "$id": "msg1" },
{ "$ref": "ChatMessage", "$id": "msg2" }
]
}
{
"_id": "member1",
"userId": "user123",
"isDeleted": false
}
{
"_id": "msg1",
"userId": "user123",
"content": "Hello, everyone!",
"timestamp": "2024-11-13T10:00:00"
}
직접 참조는 다른 문서를 필드로 포함하는 방식으로, 다른 문서의 전체 객체를 필드로 넣어 하나의 문서 내에 완전한 데이터를 포함시키는 방식이다. 이 방법은 임베디드 문서(Embedded Document)로도 불린다.
예를 들어, Chatroom 문서 안에 ChatMessage를 배열로 내장시켜 저장한다.
@Document(collection = "chatrooms")
public class Chatroom {
@Id
private String id;
private String roomname;
private List<ChatMessage> chatMessages; // 임베디드된 ChatMessage 객체
}
{
"_id": "chatroom1",
"name": "General Chat",
"members": [
{
"memberId": "member1",
"userId": "user123",
"isDeleted": false
},
{
"memberId": "member2",
"userId": "user456",
"isDeleted": false
}
],
"messages": [
{
"messageId": "msg1",
"userId": "user123",
"content": "Hello, everyone!",
"timestamp": "2024-11-13T10:00:00"
},
{
"messageId": "msg2",
"userId": "user456",
"content": "Hi there!",
"timestamp": "2024-11-13T10:05:00"
}
]
}
| 기준 | 기본 참조 (@DBRef) | 직접 참조 (Embedded 방식) |
|---|---|---|
| 데이터 중복 | 중복을 방지, 참조된 문서만 ID로 저장 | 데이터 중복 가능, 동일 데이터가 여러 문서에 포함될 수 있음 |
| 조회 성능 | 참조된 문서를 추가로 조회해야 하므로 성능에 영향을 미침 | 한 번의 조회로 모든 데이터를 가져오기 때문에 성능이 빠름 |
| 문서 크기 제한 | 제한 없음 (ID만 저장하므로 크기가 작음) | 문서 크기가 커지면 16MB 제한에 도달할 수 있음 |
| 데이터 일관성 | 참조된 문서가 변경되면 자동으로 반영됨 | 중복 데이터 수정 시 일관성 문제 발생 가능 |
| 유연성 | 더 유연한 데이터 모델링 (중복 없이 참조 가능) | 중복이 허용되는 경우 더 적합 |
| 성능 | 쿼리가 두 번 발생할 수 있어 성능에 영향을 줄 수 있음 | 쿼리 한 번으로 데이터를 모두 가져올 수 있어 성능이 좋음 |