1.collection1에서 똑같은 collection인 collection2, collection3 등을 참조
2. collection1에 하부 목록으로 expense, incomes 생성
1. users 컬렉션과 별도의 컬렉션 사용
장점
- 확장성: 대규모 데이터를 다룰 때 더 효율적일 수 있습니다. 각 데이터 유형을 별도의 컬렉션에 저장함으로써, 문서 크기에 대한 걱정 없이 데이터를 추가할 수 있습니다.
- 유연성: expenses와 incomes 데이터를 독립적으로 관리할 수 있어, 복잡한 쿼리나 데이터 분석이 용이합니다.
- 성능 최적화: 데이터를 분리함으로써, 특정 작업에 필요한 데이터만 빠르게 조회할 수 있습니다.
단점
- 조인의 필요성: MongoDB에서는 SQL 데이터베이스의 조인과 같은 기능이 제한적입니다. Mongoose의 populate 기능을 사용하여 관련 데이터를 결합할 수 있지만, 이는 추가적인 쿼리를 발생시키며 성능에 영향을 줄 수 있습니다.
- 데이터 일관성 관리: 별도의 컬렉션으로 데이터를 관리할 때, 데이터 간의 관계를 수동으로 관리해야 합니다.
2. users 컬렉션 내에 expenses, incomes를 하부 문서로 포함
장점
- 데이터 일관성: 한 문서 내에서 관련 데이터를 관리함으로써, 데이터 간의 관계를 명확하게 유지할 수 있습니다.
- 단순한 쿼리: 관련 데이터를 함께 조회할 때 추가적인 조인이나 쿼리 없이 단일 문서 조회로 가능합니다.
단점
- 문서 크기 제한: MongoDB에서 단일 문서의 크기는 16MB로 제한됩니다. 사용자의 expenses와 incomes 데이터가 많아지면 이 제한에 도달할 수 있습니다.
- 확장성 제한: 많은 양의 expenses와 incomes 데이터를 저장해야 하는 경우, 성능 저하나 관리의 복잡성이 증가할 수 있습니다.
결론
- 대규모 데이터를 다루거나 확장성이 중요한 경우 : 별도의 컬렉션을 사용하는 것을 추천합니다. 이는 더 유연한 데이터 관리와 성능 최적화를 가능하게 합니다.
- 관련 데이터의 일관성과 간단한 쿼리가 더 중요한 경우 : 또는 애플리케이션에서 관리해야 하는 데이터의 양이 비교적 작은 경우, 컬렉션1의 내에 하부 문서로 포함하는 방식을 추천합니다.
하부 참조든, 같은 콜렉션으로 참조하든 일단 둘다 ref는 써야함.
그렇게 특정 user의 objectId를 참조하게 되어 그 내용만 각 collection2, collection3에서 불러올 수 있다.
이전처럼 require을 서로 안해주어도 User라는 model즉 콜렉션을 참고하게 해준다.
1. collecion1의 참조를 통한 관리하기.
const mongoose = require("mongoose");
// User 스키마 정의
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, trim: true, unique: true },
email: { type: String, required: true, trim: true, unique: true },
password: { type: String, required: true, trim: true },
picture: { type: String },
// 'expenses'와 'incomes' 필드 제거
},
{ timestamps: true }
);
const User = mongoose.model("User", UserSchema);
module.exports = User;
관리 되는 collection들은 아래처럼 ref를 통해 참조.
const ExpenseSchema = new mongoose.Schema(
{
title: { type: String, required: true, trim: true, maxLength: 50 },
// 생략
user: { type: mongoose.Schema.Types.ObjectId, ref: "User" }, // 특정 user의 _id 참조
},
{ timestamps: true, _id: true }
);
const Expense = mongoose.model("Expense", ExpenseSchema);
2. 하부 참조로 관리하기.
user에서 배열을 통해 관리하게끔 한다.
const UserSchema = new mongoose.Schema({
username: { type: String, required: true, trim: true, unique: true },
expenses: [ExpenseSchema], // ExpenseSchema를 내장 문서로 포함
}, { timestamps: true });
const ExpenseSchema = new mongoose.Schema(
{
title: { type: String, required: true, trim: true, maxLength: 50 },
//생략
user: { type: mongoose.Schema.Types.ObjectId, ref: "User" }, // 특정 user의 _id 참조
},
{ timestamps: true, _id: true }
);
_id를 따로 생성해줘야 한다.
// User 문서 예시
{
_id: ObjectId("60af904685153de0f4e331f2"),
username: "user1",
email: "user1@example.com",
// 기타 필드...
}
// Expense 문서 예시
{
_id: ObjectId("60af906885153de0f4e331f3"),
title: "점심 식사",
amount: 12000,
date: new Date(),
category: "식비",
description: "회사 근처 식당에서 점심 식사",
user: ObjectId("60af904685153de0f4e331f2") // User 문서를 참조
}
// Income 문서 예시
{
_id: ObjectId("60af908765153de0f4e331f4"),
title: "프리랜스 프로젝트",
amount: 500000,
date: new Date(),
category: "부수입",
description: "웹 개발 프로젝트 완료",
user: ObjectId("60af904685153de0f4e331f2") // User 문서를 참조
}
Document - Reference
Reference 저장 방법은 pointer 개념으로 이해하면 된다.
Embedded 방식의 Document를 통째로 저장하는것이 아니라 참조 할 수 있도록 ID를 저장하는 방식이다.
예를들어, 2가지 종류의 Publisher Document / Book Document가 있을때, Book Document의 publisher_id 에 Publisher._id 의 value 를 저장하는 것이다.
RDBMS의 외래키와 같은 개념이라고 봐도 되며, 이렇게 _id를 저장해주면 몽고디비가 알아서 찾아 연결해준다.
'🔓데이터베이스 > 몽고db' 카테고리의 다른 글
몽고db는 모델의 이름을 소문자로 전환 + 복수형으로 collection명 정의 (0) | 2024.02.28 |
---|---|
몽고db 클라우드에 정보 보내보기 (0) | 2024.02.14 |
module을 exports하여 postman에서 send 해보기(회원가입 기능) (0) | 2022.12.19 |