7.Database-Mysql

7.1 데이터 베이스

  • 보통 관계형 데이터 베이스(MySql, Postgresql) 사용
  • 서버 종료 상관없이 데이터를 계속 사용 할 수 있음
  • 여러사람의 동시 접근이 가능하며, 권한을 따로 줄 수 있음
  • 비정형 데이터는 비 관계형 데이터베이스를 사용한다 (NoSql, mongoDB 등)

7.2 MySql, 워크벤치 설치

  • https://dev.mysql.com/downloads/file/?id=514517
  • cd “C:\Program Files\MySQL\MySQL Server 8.0\bin”
  • mysql -h localhost -u root -p
  • mysql 워크벤치 사용해도 됨

7.3 데이터베이스, 테이블 생성하기

  • 워크벤치에서 쿼리 날리기
  • 사용자 테이블 생성
    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;
    
  • 댓글 테이블
  • CHARACTER SET=utf8mb4 : 이모티콘 포함
  • UNIQUE INDEX : name이 고유값
    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;
    

7.4 CRUD 작업하기

  • 데이터베이스에서 많이 하는 작업 4가지
  • C(CREATE) ```mysql

    users

    INSERT INTO nodejs.users (name, age, married, comment) VALUES (‘zero’, 24, 0, ‘자기소개1’); INSERT INTO nodejs.users (name, age, married, comment) VALUES (‘nero’, 32, 1, ‘자기소개2’);

comments

INSERT INTO nodejs.comments (commenter, comment) VALUES (1, ‘안녕하세요 댓글입니다.’);


- R(READ)
```mysql
SELECT * FROM nodejs.users;
SELECT name, married FROM nodejs.users;
SELECT name, age FROm nodejs.users WHERE married = 1 AND age > 30;
SELECT id, name FROM nodejs.users WHERE married = 0 OR age > 30;
SELECT id, name FROM noedjs.users ORDER BY age DESC;
SELECT id, name FROM noedjs.users ORDER BY age DESC LIMIT 1;
SELECT id, name FROM nodejs.users ORDER BY DESC LIMIT 1 OFFSET 1;
  • U(UPDATE)
    UPDATE nodejs.users SET comment = '바꿀내용' WHERE id = 2;
    
  • D(DELETE)
    DELETE FROM nodejs.users WHERE id = 2;
    

7.5 시퀄라이즈 사용하기

  • 시퀄라이즈 ORM
    • MYSQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리
    • MySQL 외에도 다른 RDB(Maria, Postgre, etc..) 와도 호환됨.
    • 자바스크립트 문법으로 데이터베이스 조작 가능
  • 설치
    • npm i express morgan nunjucks sequelize sequelize-cli mysql2
    • mysql2는 노드와 mysql을 연결하는 드라이버
  • 생성
    • npx sequelize init
  • 연결
    • sequelize.sync로 연결
  • 모델 생성
    • models내에 js파일로 모델 생성 ```javascript 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”, tableNmae: “comments”, paranoid: false, charset: “utf8mb4”, collate: “utf8mb4_general_ci”, } ); } };

- 관계 정의 하기
- 1:다 관계
  - hasMany로 표현
  - sourceKey
```javascript
  ...

module.export = class User extends Sequelize.Model {
  static init(sequelize) {
      ...
  };
  static associate(db) {
    db.User.hasMany(db.Comment, { foreignKey: "commenter", sourceKey: "id" });
  }
};
  • 1:다 관계의 반대 관계
    • belongsTo 표현
    • targetKey
    • 여기에 commenter 필드가 추가 된다. ```javascript …

module.export = class User extends Sequelize.Model { static init(sequelize) { … }; static associate(db) { db.Comment.belongsTo(db.User, { foreignKey: “commenter”, targetKey: “id” }); } };

- 1:1 관계
  - hasOne으로 표현
- 1:1 반대 관계
  - 1:다 관계의 반대관계와 동일
- 다:다 관계
  - 중간 테이블이 생김
  - belongsToMany로 표현
  - 양쪽에서 모두 belongsToMany로 지정
  - 중간테이블은 through로 표현
- ORM <-> SQL
- Create는 promise기 때문에 await이나 then을 사용해야 한다.
- 조회
```mysql
INSERT INTO nodejs.users (name, age, married, comment) VALUES ('zero', 24, 0, '자기소개1');
SELECT * FROM nodejs.users;
SELECT name, married FROM nodejs.users;
SELECT name, age FROM nodejs.users WHERE married = 0 OR age > 30;
SELECT id, name FROM users ORDER BY age DESC;
SELECT id, name FROM users ORDER BY age DESC LIMIT 1;
SELECT id, name FROM users ORDER BY age DESC LIMIT 1 OFFSET 1;

UPDATE nodejs.users SET comment = "바꿀 내용" WHERE id = 2;
DELETE FROM nodejs.users WHERE id = 2;
DELETE FROM nodejs.users WHERE id IN (1,3,5);

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

User.findAll({});

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

User.findAll({
  attribute: ['name, age'],
  where : {
      [Op.or]: [{married: 0}, {age: {[Op.gt]: 30}}],
  },
});

User.findAll({
  attribute:['id', 'name'],
  order:[['age', 'DESC']]
});

User.findAll({
  attribute:['id', 'name'],
  order:[['age', 'DESC']],
  limit:1 
});

User.findAll({
  attribute:['id', 'name'],
  order:[['age', 'DESC']],
  limit:1,
  offset:1
});

User.update({
  comment: '바꿀 내용',
}, {
    where: {id:2}
})

User.destory({
    where: {id:2}
})

User.destory({
    where:{id:{[Op.in]: [1,3,5]}}
})
  • 관계 쿼리
    • 결과값이 자바스크립트 객체임
    • include로 JOIN과 비슷한 기능 수행
      • include시 where나 attribute도 동일하게 짖어할 수 있다 ```javascript const user = await User.findOne({}); console.log(user.nick)

// JOIN const user = await User.findOne({ include:[{ model: Comment }] }) console.log(user.Comments)

// 다대다 db.sequelize.models.PostHashtag

// 따로 가져오기 const user = await User.findOne({}); const comments = await user.getComments(); console.log(comments)

// 생성 const user = await User.findOne({}) const comment = await Comment.create(); await user.addComent(comment); //또는 await user.addComment(comment.id) await user.addComment([comment1, comment2])

//수정 삭제 await user.setComment(comment.id) await user.removeComment(comment.id)


- raw쿼리 
- 직접 SQL을 쓸 수 있다.
```javascript
const [result, metadata] = await sequelize.query('SELECT * from comments')

Comments