trip : diary = 1 : N
diart : hashtag = N : M
인 경우의 관계 설정
관계 설정방법은 2가지가 있다
마이그레이션과 모델 모두 이용하는 방법과
마이그레이션을 하지않고 모델만 이용하는 방법이 있는데
마이그레이션을 이용하는 방법으로 하겠다
1 : N
우선 trip, diary, hashtag의 migration과 model파일들을 다 만든 상황에서
일반적으로 migration 파일을 만들때
npx sequelize-cli model:generate --name user --attributes name:string
처럼 만드는데 이렇게 말고
npx sequelize-cli migration:generate --name fk-diary
이런식으로 model이 생성되지 않고 migration파일만 생성되게 만든다
trip과 diary는 1 : N이고
diary에 trip_id가 외래키로 존재해야하는데 맨 처음 diary migration파일을 만들때 trip_id를 직접 만들어주지 않는다
fk-diary 파일을
// /migrations/20220412004755-fk-diary.js
"use strict";
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("diary", "trip_id", {
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: "trip",
key: "id",
},
onUpdate: "CASCADE",
onDelete: "CASCADE",
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn("diary", "trip_id");
},
};
위 코드처럼 만들어 준다
diary 테이블에 trip_id칼럼을 생성하는데 해당 칼럼은 trip model의 id값을 참조한다는 의미이다
또한 관계 설정의 꽃인 onUpdate와 onDelete를 CASCADE해주면
trip을 지우거나 업데이트할떄 해당 trip에 귀속되어있는 diary도 삭제되거나 업데이트의 영향을 받는다
그리고 마지막으로
models/index에서
// /models/index.js
db.trip.hasMany(db.diary, { foreignKey: "trip_id", sourceKey: "id" });
db.diary.belongsTo(db.trip, { foreignKey: "trip_id", targetKey: "id" });
위 코드를 추가해줘서 관계 설정을 마무리해준다
trip은 hasMany 많이 가지고 있고
diary는 어디에 소속되어있다는 뜻이다
diary의 구조를 보면
diary테이블을 생성하는 migrate를 할때 만들어 주지 않았던 trip_id가 생성되어 있으며
MUL이 찍혀있는것을 확인 할 수 있다
N : M
N : M의 관계는 중간에 징검다리역할을 하는 join table이 필요하다
위에서와 마찬가지로 diary와 hashtag 테이블이 생성된것을 기준으로 설명하자면
npx sequelize-cli migration:generate --name fk-diary_hashtag
위 코드처럼 조인테이블역할을 할 migration을 생성해준다
// /migrations/20220411075551-fk-diary_hashtag.js
"use strict";
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("diary_hashtag", "diary_id", {
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: "diary",
key: "id",
},
onUpdate: "CASCADE",
onDelete: "CASCADE",
});
await queryInterface.addColumn("diary_hashtag", "hashtag_id", {
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: "hashtag",
key: "id",
},
onUpdate: "CASCADE",
onDelete: "CASCADE",
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn("diary_hashtag", "diary_id");
await queryInterface.removeColumn("diary_hashtag", "hashtag_id");
},
};
// /models/index.js
db.diary.belongsToMany(db.hashtag, {
through: "diary_hashtag",
foreignKey: "diary_id",
sourceKey: "id",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
db.hashtag.belongsToMany(db.diary, {
through: "diary_hashtag",
foreignKey: "hashtag_id",
sourceKey: "id",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
그리고 migration과 model 파일을 위에처럼 만들어준다
belongtToMany를 서로한테 사용해서 N : M 관게임을 명시해준다
그러면
join table인 diary_hashtag 테이블이 생성되며
trip을 삭제시
하위의 diary가 삭제되며
삭제된 diary 하위의 diary_hashtag가 삭제된다
하지만 hashtag까지는 삭제안되는데 N : M 관계이므로
방금 삭제된 diary가 가지고 있었던 hastag가 다른 diary에서도 쓰일 수 있으므로 삭제안되는것이 정상이지만
아무 diary에서도 참조 안하는 hashtag가 존재해도 (즉, join table내에 hashtag_id값이 없어도) 해당 hashtag는 자동으로 안지워지는데 이게 자동으로 지워져야한다고 생각해서 이것저것 시도하다가 결국에는 자동으로 삭제가 안되는것으로 판명났다
N : M 관계에대한 고찰 : https://fullfish.tistory.com/93?category=1054038
Sequelize N : M (다대다)관계에 대한 고찰
diary : hashtag = N : M 일때 처음에는 await diary.create() await diary_hashtag.create() await hashtag.create() 로 각각 3개의 테이블에 데이터를 만들어 줬는데 belongsToMany로 관계설정을 해줬으니까 각..
fullfish.tistory.com
'코딩 공부 > 공부' 카테고리의 다른 글
node-cron을 이용한 schedule (0) | 2022.05.05 |
---|---|
Sequelize N : M (다대다)관계에 대한 고찰 (0) | 2022.05.05 |
Sequelize와 Migration 기본 설정 (0) | 2022.05.04 |
JS로 slack bot 사용하기 (invalid_auth 에러 해결 법) (2) | 2022.04.27 |
포스트맨 자동화 (0) | 2022.04.26 |