시퀄라이즈를 사용하다 보면 1 : N 참조 관계가 있고, N : M 참조관계가 존재한다.
1 : N 참조관계
user.js의 db.User은 hasMany(db.Post)를 가진다고 하는데, 하나의 유저는 여러 개의 게시글을 작성할 수 있기 때문에 hasMany로 표현한 것이고, db.Post는 belongsTo(db.User)에 종속된다. belongsToMany가 아닌 이유는 하나의 유저가 여러 개의 게시글을 작성할 수 있다고 했기에 db.User 하나에 종속되서 Many를 사용하지 않아도 된다.
<models/user.js>
static associate(db) {
db.User.hasMany(db.Post)
}
<models/post.js>
static associate(db) {
db.Post.belongsTo(db.User)
}
1 : 1 참조관계
db.User는 belongsToMany(db.User)에 종속된다고 한다. 그리고 외래 키로 followingId를 참조하고, 팔로워라고 부른다. N : M 참조관계는 서로 참조하지 않고, 참조 테이블을 만드는데, through는 테이블을 만드는 명령어이다. 테이블 이름으로 Follow 테이블을 만들고, Follow를 참조하기 때문에 hasOne이 아닌 belongsTo로 Follow 테이블에 종속된다.
<models/user.js>
static associate(db) {
db.User.belongsTo(db.User, {
foreignKey: 'followingId',
as: 'Followers',
through: 'Follow'
})
db.User.belongsToMany(db.User, {
foreignKey: 'followerId',
as: 'Followings',
through: 'Follow'
})
}
N : M 참조관계
db.Post는 한 게시글에 여러 해시태그가 달릴 수 있고, 여러 게시물은 여러 해시태그를 가진다. 그래서 N : M 참조관계라고 할 수 있다.
db.Post는 여러 해시태그를 가질 수 있고, PostHashtag라는 테이블을 참조해서 belongsToMany이다.
db.Hashtag도 db.Post를 가질 수 있고, PostHashtag라는 테이블을 참조해서 belongsToMany이다.
<models/post.js>
static associate(db) {
db.Post.belongsToMany(db.Hashtag, { through: 'PostHashtag' })
}
<models/hashtag.js>
static associate(db) {
db.Hashtag.belongsToMany(db.Post, { through: 'PostHashtag' })
}
db 연결과 초기화
상수로 선언한 sequelize는 config에서 database, username, password, config 속성을 가져온다. 이 속성은 db.init(sequelize)을 할 때 사용된다.
시퀄라이즈 모델을 가져온 뒤, Key: Value 형태로 넣는데, User: User.init(sequelize)는 User라는 속성은 User모델을 초기화 하고, Hashtag, Post도 마찬가지로 가져와서 초기화를 해준다.
Object.values()함수는 자바스크립트 내장 함수로서, 속성 값들을 배열로 반환하는 함수이다. db객체에 속성과 모델, 초기화를 한 값들을
배열로 반환하면서 .filter()함수를 통해 model로 들어오는 인자의 타입이 associate()메서드를 가진 모델만 필터링하고, 필터링된 모델은 associate()메서드를 호출해서 db와 연결해준다.
<models/index.js>
const Sequelize = require('sequelize')
const sequelize = new Sequelize(config.database, config.username, config.password, config)
const db = {
sequelize,
Sequelize,
User: User.init(sequelize),
Hashtag: Hashtag.init(sequelize),
Post: Post.init(sequelize)
}
Object.values(db)
.filter(model => typeof model.associate === 'function')
.forEach(model => model.associate(db))
콘솔 출력 결과
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'users' AND TABLE_SCHEMA = 'Node_SNS'
Executing (default): SHOW INDEX FROM `users` FROM `Node_SNS`
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'hashtags' AND TABLE_SCHEMA = 'Node_SNS'
Executing (default): SHOW INDEX FROM `hashtags` FROM `Node_SNS`
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'posts' AND TABLE_SCHEMA = 'Node_SNS'
Executing (default): SHOW INDEX FROM `posts` FROM `Node_SNS`
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'Follow' AND TABLE_SCHEMA = 'Node_SNS'
Executing (default): SHOW INDEX FROM `Follow` FROM `Node_SNS`
Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'PostHashtag' AND TABLE_SCHEMA = 'Node_SNS'
Executing (default): SHOW INDEX FROM `PostHashtag` FROM `Node_SNS`
데이터베이스 연결 성공
information_schema 테이블에서 테이블 타입이 base table과 table name이 Node_SNS 스키마에서 users를 가져온다.
information_schema 테이블에서 테이블 타입이 base table과 table name이 Node_SNS 스키마에서 hashtags를 가져온다.
information_schema 테이블에서 테이블 타입이 base table과 table name이 Node_SNS 스키마에서 posts를 가져온다.
information_schema 테이블에서 테이블 타입이 base table과 table name이 Node_SNS 스키마에서 Follow를 가져온다.
information_schema 테이블에서 테이블 타입이 base table과 table name이 Node_SNS 스키마에서 PostHashtag를 가져온다.
이렇게 가져오면 그 뒤로 db를 사용할 수 있다.
'Node.js' 카테고리의 다른 글
Router.use() 에러 (0) | 2024.03.21 |
---|---|
사소한 오류 해결 (0) | 2024.03.20 |
BSON Error 해결 (0) | 2024.03.10 |
list.js Router - 404 Error (0) | 2024.02.16 |
MongoDB Router 연결 (1) | 2024.02.16 |