일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- restful api
- Nest.js
- swagger
- Kotlin
- spring boot
- component
- It
- react
- front-end
- class
- vue
- kafka
- node.js
- 개발이 취미인 사람
- 상속
- file upload
- 코틀린
- Producer
- 개발자
- java
- Sequelize
- state
- back-end
- props
- 자바
- 반복문
- SWIFT
- AWS
- javascript
- 조건문
- Today
- Total
개발이 취미인 사람
[Node.js] Sequelize 관계성 정의 테이블간에 관계정의 본문
- 지난 시간
안녕하세요. 지난 시간에는 모델을 정의하고 생성하는 부분에 대해 알아봤습니다.
혹시 놓치고 오신 분들은 아래 링크를 통해 학습하고 오시는 걸 추천드리겠습니다.
- 개요
이번 시간에는 시퀄 라이즈에서 모델 간에 관계를 맺는 방법에 대해 알아보겠습니다.
보통 관계를 맺는 방식은 1 : 1(일 대 일), 1 : M (일 대 다), N : M (다 대 다)로 맺습니다.
관계를 맺어주는 코드는 associate라는 함수 안에 정의할 수 있으며, 그 안에 hasOne, hasMany, belongsTo, belongsToMany속성으로 해당 관계 방식을 정의합니다.
- 1 : 1 관계 방식
1 : 1 방식과 같은 경우 예를 들면 "유저" 모델과 "유저 정보" 모델로 매칭을 시킬 수 있습니다.
한 유저에 대한 정보가 크다면 하나에 데이블 보다는 분리를 하는 경우가 발생하는데요. 두 모델을 만들고 관계성을 맺어 사용합니다.
시퀄 라이즈에서 관계를 맺는 방식은 아래와 같습니다.
Users 모델
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
email: {
type: DataTypes.STRING(100),
validate: {
isEmail: true,
},
comment: "이메일",
},
password: {
type: DataTypes.STRING(60),
comment: "비밀번호",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
phone: {
type: DataTypes.STRING(72),
comment: "전화번호",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Users", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Users.associate = models => {
/**
* Users안에 있는 "id값"을 "user_id라는 컬럼 이름"으로 UserInfo모델에 새로운 컬럼으로 추가한다.
*/
Users.hasOne(models.UserInfo, {foreignKey: "user_id", sourceKey: 'id'});
};
return Users;
};
UserInfo 모델
const STATUS = {
PAUSE: 'PAUSE',
ACTIVE: 'ACTIVE',
};
module.exports = (sequelize, DataTypes) => {
const UserInfo = sequelize.define("UserInfo", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
permission: {
type: DataTypes.STRING(45),
comment: "유저 권한(Ex: 관리자, 일반 유저 등등 )",
},
status: {
type: DataTypes.ENUM([STATUS.PAUSE, STATUS.ACTIVE]),
defaultValue: STATUS.PAUSE,
allowNull: false,
comment: "계정상태(ACTIVE, PAUSE)",
},
block: {
type: DataTypes.BOOLEAN,
defaultValue: 0,
comment: "계정 블락 유무",
},
account_expired: {
type: DataTypes.STRING(45),
comment: "계정 유효기간(패키지 별 설정) ex)2020-12-27",
},
password_expired: {
type: DataTypes.STRING(45),
comment: "비밀번호 유효기간(주기적 업데이트) ex)2020-12-31",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "UserInfo", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
UserInfo.associate = models => {
/**
* UserInfo모델 안에 "user_id라는 컬럼 이름"으로 Users모델에 있는 "id값"을 새로운 컬럼으로 추가한다.
*/
UserInfo.belongsTo(models.Users, {foreignKey: "user_id", sourceKey: "id"});
};
return UserInfo;
};
hasOne : 관계를 맺는 대상(자식)에게 자신의 외래 키를 추가합니다. (Users => UserInfo) UserInfo 외래 키가 추가됩니다.
belongsTo : 관계를 맺는 대상(부모)에게 외래 키를 받아 추가합니다. (UserInfo => Users) UserInfo 외래 키가 추가됩니다.
테이블 정보 조회
- 1 : M 관계 방식
1 : M 방식과 같은 경우 예를 들면 "회사" 모델과 "회사 소속 유저" 모델로 매칭을 시킬 수 있습니다.
한 회사에 소속된 유저는 여러 명일 수 있다.
시퀄 라이즈에서 관계를 맺는 방식은 아래와 같습니다.
CompanyInformation 모델
module.exports = (sequelize, DataTypes) => {
const CompanyInformation = sequelize.define("CompanyInformation", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
hospital_name:{
type: DataTypes.STRING(255),
comment:"회사 이름"
},
email: {
type: DataTypes.STRING(100),
validate: {
isEmail: true,
},
comment: "회사 이메일",
},
name: {
type: DataTypes.STRING(100),
comment: "회사(관리자) 이름"
},
phone: {
type: DataTypes.STRING(72),
comment: "회사 전화번호",
},
fax: {
type: DataTypes.STRING(72),
comment: "팩스번호",
},
business_number: {
type: DataTypes.STRING(45),
comment: "사업자등록번호",
},
address: {
type: DataTypes.TEXT,
comment: "주소",
},
package: {
type: DataTypes.JSON,
defaultValue: {cloud:"true"},
comment: "각 프로젝트는 결제 후 사용가능",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "CompanyInformation", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
});
CompanyInformation.associate = models => {
/**
* CompanyInformation안에 있는 "id값"을 "company_id라는 컬럼 이름"으로 Users모델에 새로운 컬럼으로 추가한다.
*/
CompanyInformation.hasMany(models.Users, {foreignKey : "company_id", sourceKey:"id"});
};
return CompanyInformation;
};
Users 모델
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
email: {
type: DataTypes.STRING(100),
validate: {
isEmail: true,
},
comment: "이메일",
},
password: {
type: DataTypes.STRING(60),
comment: "비밀번호",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
phone: {
type: DataTypes.STRING(72),
comment: "전화번호",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Users", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Users.associate = models => {
/**
* Users안에 있는 "id값"을 "user_id라는 컬럼 이름"으로 UserInfo모델에 새로운 컬럼으로 추가한다.
*/
Users.hasOne(models.UserInfo, {foreignKey: "user_id", sourceKey: 'id'});
/**
* Users모델 안에 "company_id라는 컬럼 이름"으로 CompanyInformation모델에 있는 "id값"을 새로운 컬럼으로 추가한다.
*/
Users.belongsTo(models.CompanyInformation, {foreignKey: "company_id", sourceKey: "id"});
};
return Users;
};
hasMany : 관계를 맺는 대상(자식)에게 자신의 외래 키를 추가합니다. 그리고 복수에 데이터를 추가가 가능하며 관계를 맺습니다. (CompanyInfo => Users) Users 외래 키가 추가됩니다.
belongsTo : 관계를 맺는 대상(부모)에게 외래 키를 받아 추가합니다. (Users => CompanyInformation) Users 외래 키가 추가됩니다.
테이블 조회 정보
저희는 Category, ProductCategory, Product 모델을 만들어 보겠습니다.
1번 방식
Category 모델
module.exports = (sequelize, DataTypes) => {
const Category = sequelize.define("Category", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Category", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Category.associate = models => {
Category.belongsToMany(models.Product, {through: "ProductCategory"})
};
return Category;
};
Product 모델
module.exports = (sequelize, DataTypes) => {
const Product = sequelize.define("Product", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Product", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Product.associate = models => {
Product.belongsToMany(models.Category, {through: "ProductCategory"})
};
return Product;
};
ProductCategory 테이블이 존재하며, 칼럼으로 각각에 primaryKey가 생성된 걸 확인할 수 있습니다.
2번 방법
두 번째 방법은 ProcutCategory 테이블을 직접 만들어 생성하는 방법입니다.
Category 모델
module.exports = (sequelize, DataTypes) => {
const Category = sequelize.define("Category", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Category", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Category.associate = models => {
Category.belongsToMany(models.Product, {through: "ProductCategory", foreignKey: "category_id", sourceKey: "id"})
};
return Category;
};
Product 모델
module.exports = (sequelize, DataTypes) => {
const Product = sequelize.define("Product", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "Product", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
Product.associate = models => {
Product.belongsToMany(models.Category, { through: "ProductCategory", foreignKey: "product_id", sourceKey: "id"})
};
return Product;
};
ProductCategory 모델
module.exports = (sequelize, DataTypes) => {
const ProductCategory = sequelize.define("ProductCategory", {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
comment: "고유번호 UUID",
},
name: {
type: DataTypes.STRING(100),
comment: "이름",
},
}, {
charset: "utf8", // 한국어 설정
collate: "utf8_general_ci", // 한국어 설정
tableName: "ProductCategory", // 테이블 이름
timestamps: true, // createAt & updateAt 활성화
paranoid: true, // timestamps 가 활성화 되어야 사용 가능 > deleteAt 옵션 on
});
ProductCategory.associate = models => {
ProductCategory.belongsTo(models.Product, {
foreignKey: 'product_id', sourceKey: "id"
});
ProductCategory.belongsTo(models.Category, {
foreignKey: 'category_id', sourceKey: "id"
});
};
return ProductCategory;
};
연결하고자 하는 모델들은 belongsToMany와 belongsTo를 사용해서 연결하면 됩니다.
동일하게 테이블이 생성됐지만, ProductCategory 테이블 칼럼 정보는 다르다는 걸 확인할 수 있습니다.
직접 실습을 해보시는 걸 추천드리겠습니다. :) 기술을 정확히 알기 위해서는 시간이 들지만., 알고 나면 편안하게 쓸 수 있어요 :)
'백앤드(Back-End) > Node.JS' 카테고리의 다른 글
[Node.js] Sequelize Seeders 사용법 (1) | 2021.02.13 |
---|---|
[Node.js] Sequelize CRUD 사용법 (0) | 2021.02.12 |
[Node.js] Sequelize 모델 정의 및 옵션 설정 (2) | 2021.02.11 |
[Node.js] Sequelize 개념 및 설치 (4) | 2021.02.10 |
[Node.js] 디렉토리 & 파일 쓰기, 읽기, 삭제, 존재 여부 (2) | 2021.01.19 |