[MongoDB]-Mongoose 스키마 디자인 관계 유형

hannah·2023년 11월 2일
0

db

목록 보기
5/6

MongoDB는 탈 RDBMS를 의미하는 표준화된 구조적 질의 언어가 없는 데이터베이스 또는 관계를 갖지 않는 데이터베이스의 NoSQL의 Document Database의 한 종류이다.
이처럼 MongoDB는 관계형 데이터베이스가 아니지만 스키마를 통해 관계를 설정함으로써 유지보수가 용이하고 데이터를 관리하기 쉽게 할 수 있다.

👉 1. 일대일(One to One)

💫 embed

모든 1:1 data를 key-value-pair로 저장한다.

const userSchema = new mongoose.Schema({
	name: {
    	type: String,
        required: true
    },
    email: {
    	type: String,
        required: true
    }
});

const userInfoSchema = new mongoose.Schema({
	user: {
    	type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    phone: {
    	type: String,
        required: true
    }
});

const User = mongoose.model('User', userSchema);
const UserInfo = mongoose.model('UserInfo', userInfoSchema);

우선 userSchemauserInfoSchema로 각각의 스키마를 정의했다. userInfoSchema에서는 user 필드를 통해 User 모델과 연결하여 일대일 관계를 정의했다. 이때 ObjectId 고유식별자를 활용하여 고유값을 연결한다.

👉 2. 일대다(One to Many)

💫 reference

const postSchema = new mongoose.Schema({
	title: {
    	type: String,
        required: true
    },
    content: {
    	type: String,
        required: true
    },
    comments: [{
    	type: mongoose.Schema.Types.ObjectId,
        ref: 'Comment'
    }]
});

const commentSchema = new mongoose.Schema({
	content: {
    	type: String,
        required: true
    },
    post: {
    	type: mongoose.Schema.Types.ObjcetId,
        ref: 'Post'
    }
});

const Post = mongoose.model('Post', postSchema);
const Comment = mongoose.model('Comment', commentSchema);

게시글과 댓글을 예시로 들면, 서로의 스키마를 필드로 정의하고 있다. 여기서 postSchemacomments 필드를 []로 정의했는데 이 의미는 comments 필드가 배열로 받겠다는 의미이다.
일대다 관계는 임베디드 형식으로 서로를 참조하는 것보다는 참조형 형식으로 참조하는 것이 일반적이다.

👉 3. 다대다(Many to Many)

💫 1. reference

const postSchema = new mongoose.Schema({
	title: {
    	type: String,
        required: true
    },
    content: {
    	type: String,
        required: true
    },
    tags: [{
    	type: mongoose.Schema.Types.ObjectId,
        ref: 'Tag'
    }]
});

const tagSchema = new mongoose.Schema({
	name: {
    	type: String,
        required: true
    },
    posts: [{
    	type: mongoose.Schema.Types.ObjectId,
        ref: 'Post'
    }]
});

const Post = mongoose.model('Post', postSchema);
const Tag = mongoose.model('Tag', tagSchema);

참조 필드 방식은 스키마 각각에 배열을 사용하여 서로를 참조하는 방법이다.
이 방식은 간단하고 직접적이며, 작은 규모의 프로젝트나 단순한 관계에서는 무리없이 작동한다.

💫 2. 중간 컬렉션

const studentSchema = new mongoose.Schema({
	name: {
    	type: String,
        required: true
    },
    age: {
    	type: Number,
        required: true
    }
});

const subjectSchema = new mongoose.Schema({
	name: {
    	type: String,
        required: true
    }
});

// 중간 컬렉션
const enrollmentSchema = new Schema({
	student: {
    	type: mongoose.Schema.Types.ObjectId
        ref: 'Student'
    },
    subject: {
    	type: mongoose.Schema.Types.ObjectId
        ref: 'Subject'
    }
});

const student = new mongoose.model('Student', studentSchema);
const subject = new mongoose.model('Subject', subjectSchema);
const enrollment = new mongoose.model('Enrollment', enrollmentSchema);

중간 컬렉션을 활용할 때는 studentSchemasubjectSchema가 서로 참조하지 않고 중간 컬렉션 모델의 인스턴스에 각각의 모델과 관련된 필드를 지정한다.

중간 컬렉션의 장점

  1. 유연성: 중간 컬렉션을 통해 추가 정보나 관계 속성을 저장할 수 있으므로 더 복잡한 관계를 다루기에 유용하다.

  2. 명확한 관계: 중간 컬렉션을 사용하면 두 스키마 간의 관계를 보다 명시적으로 이해할 수 있다.

  3. 성능 최적화: 중간 컬렉션을 사용하면 관련 데이터를 더 효과적으로 쿼리하고 필터링할 수 있으며, 복잡한 쿼리를 수행하기에 좀 더 효율적일 수 있다.

  4. 일반적인 관행: 중간 컬렉션을 사용하는 방식은 관계형 데이터베이스에서의 다대다 관계를 모델링하는 일반적인 방식과 유사하다. 따라서 이 방식을 사용하는 것은 개발자나 데이터베이스 관리자가 이해하고 유지보수하기 쉬울 수 있다.

❗어떤 방식을 선택할지는 프로젝트의 요구 사항과 복잡성에 따라 다를 수 있다. 복잡한 관계나 추가 정보가 필요한 경우 중간 컬렉션을 사용하는 것이 더 유용할 수 있다.


참고사이트

0개의 댓글