Nodejs - Mongoose(2)

이율곡·2023년 3월 4일
0

Node js

목록 보기
22/26
post-thumbnail

Mongoose 관계 설정

MongoDB가 NoSQL이라 할지라도 스키마를 통해 관계를 설정함으로써 유지보수가 용이하고 데이터를 관리하기 쉽게 할 수 있다.

일대일 예시

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);

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

관계를 정의할 경우 임베디드 방식과 참조 방식이 있는데 주로 일대일 관계는 임베디드 방식으로 정의하는 경우가 다수다.

일대다 예시

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);

위의 코드는 일대다 관계를 정의한 코드이다. 게시글과 댓글을 예시로 들었다. 두 스키마 다 서로를 필드로 정의하고 있다. 여기서 postSchem는 comments 필드를 []로 정의했는데 이 의미는 comments 필드가 배열로 받겠다는 의미이다.

일대다 관계는 임베디드 형식으로 서로를 참조하는 것보다는 참조형 형식으로 참조하는 것이 일반적이다.

다대다 예시

다대다는 예시를 두 가지로 들 수 있다. 첫 번째는 위의 예시들과 같은 참조 필드를 이용한 다대다 관계 설정이 있고, 두 번째는 중간 컬렉션을 이용하는 방법이 있다.

참조 필드

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);

참조 필드 방식으로 다대다 관계를 정의한 코드이다. 위의 예시들과 똑같다. 하지만 이 방식을 일반적으로 사용하지 않는다. 그 이유는 이 방식을 사용할 경우 스키마에 쌓이는 데이터가 배로 불어나기 때문에 데이터 관리를 효율적으로 할 수 없기 때문이다

그래서 다대다 관계를 설정할 때는 중간 컬렉션 방식을 일반적으로 사용한다.

중간 컬렉션 방식

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);

위의 코드는 중간 컬렉션을 활용하여 다대다 관계를 설정한 코드이다. enrollmentSchema가 중간 컬렉션 역할을 한다. 중간 컬렉션을 활용할 때는 서로를 참조하지 않는다. 중간 컬렉션 모델의 인스턴스에 각각의 모델과 관련된 필드를 지정한다.

이렇게 함으로써 참조방식보다 효율적으로 데이터를 관리할 수 있고 좋은 유지보수성을 갖을 수 있다.

정리하기

이번에는 Mongoose로 관계를 설정했다. 크게 어렵지는 않았지만 무언가를 새롭게 배워가는 과정이 재밌었다. 또한 배운 것이 있다면 데이터 베이스는 스키마를 정의하는 과정이 제일 중요하고 그 다음이 스키마 간의 관계를 정의하는 것이다. 그 이후에는 CRUD이기 때문에 크게 어려움은 없는 거 같다. 왜 앞에 두 과정이 가장 중요한지 Mongoose를 공부하면서 배웠다.

profile
음악을 좋아하는 사람이 음악을 만들 듯, 개발을 좋아하게 될 사람이 쓰는 개발이야기

0개의 댓글