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