7장 MySQL

마조리카·2021년 4월 15일
0

7.1 데이터 베이스란?

데이터 베이스는 관련성을 가지며 중복이 없는 데이터들의 집합입니다. 이러한 데이터베이스를 관리하는 시스템을 DSMS 라고 부릅니다.
보통 서버의 하드 디스크나 SSD 등의 저장메체에 데이터를 저장합니다. 저장 매체가 고장나거나 사용자가 직접 데이터를 지우지 않는 이상 계속 데이터가 보존되므로 서버 종료 여부와 상관없이 데이터를 지속적으로 사용할 수 있습니다.
또한, 서버에 데이터 베이스를 올리면 여러 사람이 동시에 사용 가능합니다. 사람들에게 각각 다른권한을 줘서 어떤사람은 읽기만 가능하고, 어떤 사람은 모든 작업을 가능하게 할 수 있습니다.
데이터베이스를 관리하는 DBSM 중에서 RDBMS라 부르는 관계형 DBMS가 많이 사용됩니다. 대표적 RDBMS로는 Oracle, MySQL, MSSQL 등이 있습니다. 하지만 RDBMS별로 SQL문이 조금씩 다릅니다.

7.4 데이터베이스 및 테이블 생성하기

데이터베이스 생성에는 프롬프트, 워크밴체를 사용할 수 있습니다.

7.4.1 데이터베이스 생성하기

MySQL 프롬프트에 접속

  • CREAT SCHEMA [데이터 베이스명]

SCHMA(스키마)는 데이터베이스를 의미힙니다.

mysql> CREATE SCHEMA 'node.js' DEFAULT CHARACTER SET utf8;
Query OK, 1 row affected (0.01sec)
mysql> use nodejs;
database changed

CHATE SCHEMA 뒤에 DEFAULT CHARACTER SET utf8을 붙여 한글을 사용할 수 있게 만듭니다.
SQL 구문을 입력할 때는 마지막에 세미클론을 붙여야 합니다.

CREATE SCHEMA와 같이 MySQL이 기본적으로 알고 있는 구문을 예약어라고 합니다. 소,대문자 구분은 하지 않지만 사용자 언어와 구별을 위해 대문자로 사용합니다.

워터 마크 사용시

커넥션에 접속한 뒤 데이터베이스를 생성하기 위해 상단 메뉴의 데이터베이스 모양 버튼을 누릅니다. 데이터베이스의 이름은 nodejs로 입력하고 Charset/Collatcion을 각각 utf8과 utf8_general_ci 로 바꿉니다.
nodejs라는 이름의 데이터베이스를 생성합니다. apply를 눌러 적용시킵니다.

7.4.1 테이블 생성하기

데이터베이스를 생성했다면 테이브을 만듭니다. 테이블이란 데이터가 들어갈 수 있는 틀을 의미합니다. 테이블에 맞는 데이터만 들어갈 수 있습니다. 사용자의 정보를 저장하는 테이블을 만들어봅시다.
MySQL 프롬프트에 다음과 같이 입력합니다. 오타가 나지 않도록 주의

CREATE TABLE nodejs.users(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
age INT UNSIGNED NOT NULL,
married TINYINT NOT NULL,
comment TEXT NULL,
created_at DATETIME NOT NULL DEFAULT now()
PRIMARY KEY(id),
UNIQUE INDEX name_UNIQUE (name ASC))
COMMENT = '사용자 정보'
DEFAULT CHARACTER SET = utf8
->ENGINE = InnoDB;

한 글자라도 오타가 나면 에러가 발생하니 주의

칼럼, 로우

데이트 베이스에서 세로줄은 칼럼, 가로줄은 로우라 불린다.

  • INT : 정수를 의미, 소수까지 저장하고 싶다면 FLOAT나 DOUBLE 자료형을 사용하면 됩니다.
  • VARCHAR(자릿수) 외에도 CHAR(자릿수)이라는 자료형도 있습니다. CHAR은 고정길이, VARCHAR은 가변길이 입니다.
  • TEXT는 긴글을 저장할 떄 사용
    TINYINT는 -128~127, 또는 1, 0
  • DATATIME은 날짜와 시간에 대한 정보를 담고 있습니다. DATA는 날짜만, TIME은 시간만 담고있습니다.

자료형 뒤에 NOT NULL, UNSIGNED, AUTO_INCREMENT, DEFAULT 등의 옵션

  • NULL, NOT NULL 은 빈칸을 허용할지 여부를 묻는 옵션입니다. comment 컬럼만 NULL이고 , 나머지는 모두 NOT NULL입니다. 자기소개를 제외한 나머지 컬럼은 로우를 생성할 떄 데이터를 입력해야 합니다.

  • id 컬럼에는 추가로 AUTO_INCREMENT가 붙습니다.
    숫자를 저절로 올리겠다는 뜻입니ㅏㄷ

  • UNSIGNED 는 숫자 자료형에 적용하는 옵션입니다. FLOAT와 DOUBLE에는 적용 불가

  • ZEROFILL은 숫자의 자릿수가 고정되어 있을 떄 사용할 수 있습니다. 가끔 자료형으로 INTS 대신 INT(자릿수) 처럼 표현하는 경우가 있습니다.
    예를들어 INT(4)인데 숫자 1을 넣는다면 0001입니다.

  • created_at에는 DEFAULT now()라는 옵션이 붙어 있습니다. 데이터베이스 저장시 해당 컬럼에 값이없다면 기본값을 대신 넣습니다. now()는 현재 시각을 넣으라는 뜻입니다. CURRENT_TIMESTAMP와 같습니다

  • 해당 컬럼이 기본 키인 경우 PRIMARY KEY 옵션을 설정합니다. 기본 키란 로우를 대표하는 ㄱ유한 값을 의미합니다. 데이터베이스에 데이터를 넣을 때는 로우 단위로 넣습니다. 이때 로우들을 구별할 고유한 식별자가 필요합니다. 이름 나이 결혼여부 컬럼은 다른 사람과 내용이 겹칠 수 있습니다. 자기소개는 내용을 입력하지 않아도 되므로 고유하지 않습니다. 따라서 id라는 새로운 컬럼을 하나 만들어 고유한 번호를 부녀한 것입니다.

  • UNIQUE INDEX는 해당 값이 교유해야 할지에 대한 옵션입니다. name 컬럼이 해당됩니다. 인덱스의 이름은 name_UNIQUE로 , name 컬럼을 오름차순으로 기억하겠다는 것입니다.(ASC), 내림차순은 DESC입니다.

  • COMMENT는 테이블에 대한 보충 설명을 의미합니다. 이 테이블이 무슨역할을 적어두면 됩니다 필수는 아닙니다.

  • DEFAULT CHARACTER SET을 utf8로 설정하지 않으면 한글이 입력되지 않습니다.
    -ENGINE은 여러가지 있지만, MyISAM과 InnoDB가 제일 많이 사용됩니다.

  • 삭제시엔 DROP TABLE [이름]

워크벤치 사용시

nodejs 데이터베이스 아래에 있는 Tables를 마우스 오른쪽 클릭하면 메뉴가 뜹니다. Create Table 을 선택합니다.
사용자의 이름, 나이, 결혼 여부, 자기소개 메세지를 저장하고 싶다면 Column Name의 빈칸을눌러 입력합니다
Table Name 은 테이블의 이름을 의미합니다.
Comments는 테이블에 대한 설명,
Column Name 다음에 있는 Datatype은 저장할 데이터의 자료형을 뜻합니다.


자료형 오른ㅉ고을 보면 여러 체크박스에 체크 표시가 되어 있습니다.

  • PK는 기본키 여부 체크, id 컬럼이 users 테이블의 기본키였습니다. 기본키인 id 컬럼에는 AI 가 추가로 체크 표시되어 있습니다.
  • NN은 빈칸을 허용할지 여부를 묻는 NOT NULL
    comment만 체크 표시가 되어 있지 않습니다. 사실 created_at 의 경우에는 DEFAULT값이 있으므로 NOT NULL을 체크하지 않아도 항상 default값이 입력됩니다.
  • UQ는 UNIQUE INDEX 입니다.
  • UN은 UNSIGNE입니다
  • ZF는 ZEROFILL입니다
  • Default/Expression은 기본값을 저장해두는 곳입니다. created_at에 현재 시간을 저장해야 하므로 now()나 CURRENT_TIMESTAMP를 입력합니다.
  • 삭제는 Drop table입니다.

이번엔 사죵자의 댓글을 저장하는 테이블을 만들어 봅시다.
CREATE TABLE nodejs.comments(
id INT NOT NULL AUTO_INCREMENT,
commenter INT NOT NULL,
comment VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL DEFAULT now(),
PRIMARY KEY(id),
INDEX commenter_idx (commenter ASC),
CONSTRAINT commenter
FOREIGN KEY (commenter)
REFERENCES nodejs.users (id)
ON DELETE CASCADE
ON UPDATE CASCADE)
COMMENT = '댓글'
DEFAULT CHARSET=utf8mb4
ENGINE=InnoDB


comments 테이블에는 id, commenter(댓글을 쓴 사용자 아이디), comment(댓글 내용), created_at(로우 생성일)칼럼이 있습니다.

commenter 컬럼에는 댓글을 작성한 사용자의 id를 저장할 것입니다. 이렇게 다른 테이블의 기본키를 저장하는 컬럼을 외래 키 라고 부릅니다. CONSTRAINT [제약조건명] FOREIGN KEY [컬럼명] REFERENCES [참고하는 컬럼명]으로 외래키를 지정할 수 있습니다.

comments 테이블에서는 commenter 컬럼과 users테이블의 id 컬럼을 연결했습니다. 다른 테이블의 기본 키이므로 commenter 컬럼에 인덱스도 걸어 봤습니다.

그 후 ON UPDATE와 ON DELETE는 모두 CASCADE로 설정했습니다. 사용자 정보가 수정되거나 삭제되면 그것과 연결된 댓글 정보도 같이 수정하거나 삭제한다는 소리입니다.

워크벤치 사용 시

nodejs 데이터베이스에서 Tables를 마우스 오른쪽 클릭한 후 Create Table..을 선택하여 새 테이블과 새 칼럼을 생선합니다.
Charset/Collation이 utf8이 아니라 utf8mb4라는 사실에 주의하세요. 한글뿐만 아니라 이모티콘까지 넣고 싶으면 사용합니다.

댓글 테이블을 만들 떄는 사용자 테이블을 만들 때와 달리 추가 작업이 필요합니다. 댓글 테이블은 사용자 테이블과 관계가 있습니다. 특정 사용자가 입력한 댓글을 저장하기 때문입니다. 따라서 댓글 테이블과 사용자 테이블을 연결하는 작업이 필요합니다. 칼럼 설정을 완료한 후에 Foreign Keys탭으로 이동합니다.

외래 키 관계는 다음 그림처럼 commenter 칼럼과 users 테이블의 id 칼럼을 연결하면 됩니다. 오른쪽 Foreing Key options의 on update와 on delete는 모두 cascade로 바꿔줍니다.


CRUD 작업하기

CRUD는 create, read, update, delete의 첫글자를 모은 두문어자이며, 데이터베이스에서 많이 수행되는 네가지 작업입니다.

7.5.1 Create(생성)

테이터를 생성해서 데이터베이스에 넣는 작업입니다. users 테이블에 데이터를 몇개 넣어보겠습니다.
use nodejs; 명령어를 사용했다면 users만 사용해도 됩니다.

INSERT INT0 nodejs.users (name, age, married, comment) VALUES ( 'zero', 24, 0, '자기소개');

데이터를 넣는 명령어는 INSERT INT0 테이블명 VALUES([값1],[값2],...)입니다.

워크벤치 사용시

GUI를 사용하면 편리하게 작업이 가능합니다.
users 테이블에 마우스 커서를 올려보면 아이콘이 세 개 뜨는데, 세번째 아이콘을 선택하면 현재 테이블에 들어 있는 데이터들이 나옵니다.
원하는 데이터값을 넣어주면 됩니다.

7.5.2 read(조회)

  • SELECT * FROM nodejs.users;

  • SELECT * FROM nodejs.comment;

  • 원하는 컬럼을 넣어서
    SELECT name, married FROM nodejs.users;

  • WHERE을 사용하면 특정 조건으 가진 데이터만 조회가능
    AND로 여러 조건을 묶을 수 있다.
    SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;

  • OR도 가능하다
    SELECT name, age FROM nodejs.users WHERE married = 1 OR age > 30;

  • ORDER BY [컬럼명][ASC|DESC]키워드를 사용하면 정렬도 가능
    SELECT id, name FROM nodejs.users ORDER BY age DESC;

  • 조회할 로우 개수를 설정가능.
    LIMIT [숫자]로 가능
    SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1;

  • 건너뛰기 가능 OFFSET [숫자];
    SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1 OFFSET 1;

워크벤치

워크벤치에서 사용하고 싶으면 쿼리 입력창에 SQL문을 입력하고 실행버튼(번개)를 누릅니다.

7.5.3 UDATAE

UPDATE nodejs.users SET comment = '바꿀 내용', WHERE id =2 ;

delete(삭제)

DELETE FROM NODEJS.USERS where ID = 2;
DELETE FORM [테이블명] WHERE [조건]


7.6 시퀄라이즈 사용하기

시퀄라이즈는 ORM입니다. 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구입니다.

{
"name": "learn-sequelize",
"version": "0.0.1",
"description": "시퀄라이즈를 배우자",
"main": "app.js",
"scripts": {
  "start": "nodemon app"
},
"author": "ZeroCho",
"license": "MIT",
}

이제 시퀄라이즈에 필요한 sequelize 와 ewquelize-cli, mysql2 패키지를 설치합니다.
설치 완료후 npx sequelize init 명령어로 호출합니다

config, moudels, migrations, seeders 폴더가 생성되었습니다. models 폴더 안에 index.js 가 생성되었는지 확인합니다. sequelize-cli가 자동으로 생성해주는 코드는 그대로 사용할 때 에러가 발생하고 , 필요 없는 부분도 많음으로 다음과 같이 수정합니다.

const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

db.sequelize = sequelize;

module.exports = db;

Sequelize는 시퀄라이즈 패키지이자 생성자입니다.
config/config.json 에서 데이터베이스 설정을 불러온 후 new Sequelize를 통해 MySQL연결 객체를 생성합니다. 연결 객체를 나중에 재사용 하기위해 db.sequelize에 넣어두었습니다.

7.6.1 MySQL 연결하기

시퀄라이즈를 통해 익스프레스 앱과 MySQL을 연결해야 합니다. app.js를 생성하고 익스프레스와 시퀄라이즈 연결 코드를 작성합시다.

const express = require('express');
const path = require('path');
const morgan = require('morgan');
const nunjucks = require('nunjucks');

const { sequelize } = require('./models');

const app = express();
app.set('port', process.env.PORT || 3001);
app.set('view engine', 'html');
nunjucks.configure('views', {
express: app,
watch: true,
});
sequelize.sync({ force: false })
.then(() => {
  console.log('데이터베이스 연결 성공');
})
.catch((err) => {
  console.error(err);
});

app.use(morgan('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use((req, res, next) => {
const error =  new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});

app.use((err, req, res, next) => {
res.locals.message = err.message;
res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
res.status(err.status || 500);
res.render('error');
});

app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 대기 중');
});

require('./models')는 require('./models/index,js')와 같다.

db.sequelize를 불러와서 sync 메서드를 사용해 서버 실행 시 MySQL과 연동되도록 했습니다. 내부 force: flase 옵션은 true로 하면 서버가 실행 될떄마다 테이블이 재생성됩니다. 테이블을 수정하고싶을떄 true로 합시다.

config 폴더 안에 config.json정보가 사용됩니다. 다음과 같이 수정합니다.
자동 생성한 config.json에 operatorAliases 속성이 들어 있다면 삭제합니다.

{
"development": {
  "username": "root",
  "password": "nodejsbook",
  "database": "nodejs",
  "host": "127.0.0.1",
  "dialect": "mysql"
},
"test": {
  "username": "root",
  "password": null,
  "database": "database_test",
  "host": "127.0.0.1",
  "dialect": "mysql"
},
"production": {
  "username": "root",
  "password": null,
  "database": "database_production",
  "host": "127.0.0.1",
  "dialect": "mysql"
}
}

development.password와 development.database를 현재 MySQL 커넥션과 일치하게 수정하면 됩니다. test와 production 쪽은 각각 테스트용도와 배포용도로 접속하기 위해 사용되는 것이므로 여기서는 설정하지 않습니다.
password 속성에는 여러분의 MySQL 비밀번호를 입력하고, database 속성에는 nodejs를 입력합니다.

이설정은 process.env.NODE_ENV가 development일 떄 적용됩니다. (기본적으로 development입니다)

나중에 배포할 때는 process.env.NODE_ENV를 prodction으로 설정해둡니다. 따라서 배포 환경을 위해 데이터베이스를 설정할 때는 config/config.json의 production 속성을 수정하면 됩니다.

마찬가지로 테스트 환경 process.env.NODE_ENV가 test일땐 test 속성을 수정합니다.

npm start로 실행하면 라우터를 만들지 않았으므로 접속은 되지않지만 데이터베이스와 연결이 됩니다.

7.6.2 모델 정의하기

이제 MySQL에서 정의한 테이블을 시퀄라이즈에서도 정의해야합니다.
MYSQL의 테이블은 시퀄라이즈의 모델과 대응됩니다.
시퀄라이즈는 모델과 MySQL의 테이블을 연결해주는 역할을 합니다.
user와 comment 모델을 만들어 user테이블과 comments 테이블에 연결해봅시다.
시퀄라이즈는 기본적으로 모델이름은 단수형, 테이블이름은 복수형으로 사용합니다.

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model {
static init(sequelize) {
  return super.init({
    name: {
      type: Sequelize.STRING(20),
      allowNull: false,
      unique: true,
    },
    age: {
      type: Sequelize.INTEGER.UNSIGNED,
      allowNull: false,
    },
    married: {
      type: Sequelize.BOOLEAN,
      allowNull: false,
    },
    comment: {
      type: Sequelize.TEXT,
      allowNull: true,
    },
    created_at: {
      type: Sequelize.DATE,
      allowNull: false,
      defaultValue: Sequelize.NOW,
    },
  }, {
    sequelize,
    timestamps: false,
    underscored: false,
    modelName: 'User',
    tableName: 'users',
    paranoid: false,
    charset: 'utf8',
    collate: 'utf8_general_ci',
  });
}

static associate(db) {}
};

user 모델을 만들고 모듈로 exports 했습니다. user 모델은 sequelize.model을 확장한 클래스로 선업합니다. 크래스 문법을 사용하지만 클래스에 대한 지식이 없어도 사용 할 수 있습니다. 패턴만 숙지하면 됩니다. 모델은 크게 static init 메서드와 static associate 메서드로 나뉩니다.

init 메서드에는 테이블에 대한 설정을 하고, associate 메서드에는 다른 모델과의 관계를 적습니다. init 메서드부터 살펴봅시다. super.init 메서드의 첫 번째 인수가 테이블 컬럼에 대한 설정이고, 두번째 인수가 테이블 자체에 대한 설정입니다.

시퀄라이즈는 알아서 id를 기본 키로 연결하므로 id 커럼을 적어줄 필요가 없습니다. 나머지 컬럼의 스펙을 입력합니다. MySQL테이블과 컬럼 내용이 일치해야 정확하게 대응합니다.
단, 시퀄라이즈의 자료형은 MySQL의 자료형과는 조금 다릅니다.
VARCHAR는 STRING으로,
INT는 INTEGER
TINYINT는 BOOLEAN
DATATIME은 DATE로
ZEROFILL은 INTEGER.UNSIGNED.ZEROFILL

allowNull은 NOT NULL 옵션과 동일합니다. unique는 UNIQUE 옵션입니다.
defaultValue는 기본값을 의미합니다.
Sequelize.Noew로 현재 시간을 기본값으로 사용할 수 있습니다.
SQL의 now()랑 같습니다

super.init 메서드의 두번 째 인수는 테이블 옵션입니다.

  • sequlize : static init 메서드이 매개변수와 연결되는 옵션으로 db.sequelize 객체를 넣어야 합니다. 나중에 model/index.js에서 연결합니다.

  • timestamps : 현재 false로 되어 있으며, 이 속성 값이 true면 시퀄라이즈는 createAT과 updateAt 컬럼을 추가합니다. 각각 로우가 생성될 떄 수정될 떄의 시간이 자동으로 입력됩니다. 하지만 예제에서는 직접 created_at 컬럼을 만들었으므로 timestamps 속성이 필요하지 않습니다. 따라서 속성값을 false로 하여 자동으로 날짜 컬럼을 추가하는 기능을 해제했습니다.

  • underscored: 시퀄라이즈는 기본적으로 테이블명과 컬럼명을 캐멀 케이스(careatAt)로 만듭니다. 이를 스테이크 케이스(created_at) 로 바꾸는 옵션입니다.

  • modelName: 모델이름을 설정할 수 있습니다. 노드 프로젝트에서 사용합니다.

  • tableName: 실제 데이터 베이스의 테이블 이름이됩니다. 기본적으로는 모델이름을 소문자 및 복수형으로 만듭니다.

  • paranoid: true로 설정하면 deletedAt이라는 컬럼이 생깁니다. 로우를 살제할 때 완전히 지워지지 않고 deletedAt에 지운 시각이 기록됩니다. 로우를 조회하는 명령을 내렸을 때는 deletedAt의 값이 null인 로우(삭제되지 않았다는) 를 조회합니다.
    이렇게 하는 이유는 나중에 로우를 복원해야 하는 상황이 생길 것 같다면 미리 true로 설정합니다.

  • charset과 collate: 각각 utf8과 utf8_general_ci로 설정해야 한굴이 입력됩니다.
    이모티콘 까지 원하면 utf8mb4와 utf8mb4_general_ci를 입력합니다.

    comment 모델도 만들어 봅시다.

const Sequelize = require('sequelize');

module.exports = class Comment extends Sequelize.Model {
static init(sequelize) {
  return super.init({
    comment: {
      type: Sequelize.STRING(100),
      allowNull: false,
    },
    created_at: {
      type: Sequelize.DATE,
      allowNull: true,
      defaultValue: Sequelize.NOW,
    },
  }, {
    sequelize,
    timestamps: false,
    modelName: 'Comment',
    tableName: 'comments',
    paranoid: false,
    charset: 'utf8mb4',
    collate: 'utf8mb4_general_ci',
  });
}

static associate(db) {
  db.Comment.belongsTo(db.User, { foreignKey: 'commenter', targetKey: 'id' });
}
};

위에 users테이블과 연결된 commenter 컬럼이 없습니다.

모델을 생성했다면 models/index.js와 연결합니다

  
  const Sequelize = require('sequelize');
const User = require('./user');
const Comment = require('./comment');

const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

db.sequelize = sequelize;

db.User = User;
db.Comment = Comment;

User.init(sequelize);
Comment.init(sequelize);

User.associate(db);
Comment.associate(db);

module.exports = db;

db라는 객체에 user와 comment 모델을 담아두었다.
앞으로 db객체를 require하여 두 모델에 접근 가능.
user.init, comment.init해야 연결된다.


7.6.3 관계 정의하기

1:N

hasMany 메서드 사용, 반대로 belongsto메서드도 있다.

1:N
user : comment
user -> comment = hasMany
comment -> user = belongsTo

static associate(db) {
  db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id' });
}
};

  static associate(db) {
  db.Comment.belongsTo(db.User, { foreignKey: 'commenter', targetKey: 'id' });
}
};

다른 모델의 정보가 들어가는 테이블에 belongTo를 사용합니다.

1:1

1:1 관계에서는 hasMany 메서드 대신 hanOne 메서드를 사용합니다.
사용자 정보를 담고 있는 가상의 Info 모델이 있다고 하면 다음과 같이 표현할 수 있습니다.

db.User.hasOne(db.Info, { foreignKey: 'UserId', sourceKey: 'id' });
db.Info.belongTo(db.User, { foreignKey: 'UserId', targetKey: 'id' });

N:M

다대다 관계, 시퀄라이즈는 N:M 관계를 표현하기 위한 belongsToMany 메서드가 있습니다.
게시글 정보를 담고 있는 가상의 Post 모델과 해시태그 정보를 담고 있는 가상의 Hashtag 모델이 있다고 한다면 다음과 같이 표시가능.

db.Post.belongsToMany(db.Hashtag, { through: ' PostHashtag' });
db.Hashtag.belongsToMany(db.Post, { through: 'postHashtag' });

양쪽 모두 belongsToMany 메서드를 사용합니다.
N:M 관계의 특성상 새로운 모델이 생성됩니다.
through 속성에 그 이름을 적으면 됩니다.

N:M 에서는 데이터를 조회할 때 여러 단계를 거쳐야 합니다. #노드 해시태그를 사용한 게시물을 조회하는 경우
먼저 #노드 해시태그를 Hashtag 모델에서 조회하고,
가져온 태그의 아이디(1)을 바탕으로 PostHashtag 모델에서 hashtagid가 1인 postId들을 찾아 Post모델에서 정보를 가져옵니다.
자동으로 만들어진 모델들도 다음과 같이 접근합니다.

db.sequelize.models.PostHashtag

7.6.4 쿼리 알아보기

시퀄라이즈로 CRUD 작업을 하려면 먼저 시퀄라이즈 쿼리를 알아야 합니다.
SQL문을 자바스크립트로 생성하는 것이라 시퀄라이즈만의 방식이 있습니다.

쿼리는 프로미스를 반환하므로 then을 붙여 결괏값을 받을 수 있습니다.
async/await 문법과 같이 사용할 수도 있습니다.

로우를 생성하는 쿼리

INSERT INTO nodejs.users (name, age, married, comment) VALUES ( 'zero', 24, 0 , '자기소개');

const { User } = require('../models');
User.create({
	name: 'zero',
	age: 24,
	married: false,
	comment: '자기소개1',
});

models 모듈에서 User 모델을 불러와 create 메서드를 사용하면 됩니다.
주의해야 할 점은 MySQL의 자료형이 아니라 시퀄라이즈 모델에 정의한 자료형대로 넣어야 한다는 것입니다.
시퀄라이즈가 알아서 MySQL 자료형으로 바꿉니다.
자료형이나 옵션이 부합하지 않으면 에러가 발생합니다.

다음은 Users 테이블의 모든 데이터를 조회하는 SQL문 입니다.

SELECT * FROM nodejs.users;
User.FIndALL({});

다음은 Users 테이블의 데이터 하나만 가져오는 SQL문입니다.

SELECT * FROM nodejs.users LIMIT 1;
User.findOne({});

attributes 옵션을 사용해서 원하는 컬럼만 가져올 수 있습니다.

SELECT name, married FROM nodejs.users;
User.findAll({
	attributes: ['name', 'married'],
});

where 옵션이 조건들을 나열합니다.

SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
const { Op } = require('sequelize');
const { User } = require('../models');
User.findAll({
	attributes: [ 'name', 'age'],
	where: {
		married: true,
		age: { [Op.gt[: 30],
	},
});

MySQL에서는 undefined 지원 X, 빈칸 넣고싶으면 NULL

0개의 댓글