해당 글은 Node.js 교과서의 내용을 요약, 정리한 글입니다.
데이터베이스는 관련성을 가지며 중복이 없는 데이터들의 집합이며, 이러한 데이터베이스를 관리하는 시스템을 DBMS라고 한다.
DBMS중에서 RDBMS라고 부르는 관계형 DBMS가 많이 사용된다.
CREATE SCHEMA 'nodejs' DEFAULT CHARACTER SET utf8;
해당 명령어를 입력하여 스키마를 생성한다.
use nodejs
를 이용하여 node.js데이터베이스를 사용하겠다는 것을 알린다.
CREATE TABLE nodejs.users(
->id INT NOT NULL AUTO_INCREMENT,
->name VARCHAR(20) NOT NULL
->PRIMARY KEY(id),
->UNIQUE INDEX name_UNIQUE (name ASC))
->COMMENT = '사용자 정보'
->DEFAULT CHARACTER SET = utf8
->ENGINE = InnoDB;
INT: 정수를 의미함.
VARCHAR: CHAR은 고정 길이, VARCHAR는 가변 길이이다.
TEST: 긴 글을 저장할때 사용, 수백 자 보다 길면 TEXT를 사용하곤 한다.
TINYINT: -128부터 127까지의 정수를 저장할 때 사용한다. BOOLEAN과 같은 역할을 할 수 있습니다.
DATETIME: 날짜와 시간에 대한 정보
NULL, NOT NULL은 빈칸을 허용할 지 묻는 옵션
AUTO_INCREMENT: 숫자를 자동으로 올리기
UNSIGNED: 음수를 무시하고 숫자를 표시
ZEROFILL: 비어 있는 자리에 모두 0을 채워 넣는다.
DEFAULT: 해당 칼럼 값이 없다면 기본값으로 대신 넣는다.
PRIMARY KEY: 로우를 대표하는 고유한 값
UNIQUE INDEX: 해당 값이 고유해야 하는지에 대한 옵션
COMMENT: 테이블에 대한 보충 설명
DEFAULT CHARACTER SET: utf8로 설정하지 않으면 입력되지 않는다.
ENGINE: 여러 가지가 있지만, MyISAM과 InnoDB가 제일 많이 사용된다.
DROP TABLE users;
//테이블을 제거한다.
CREATE TABLE [db이름].[테이블 이름](설정값)
//테이블을 생성한다.
SHOW TABLES;
//테이블을 확인한다.
INSERT INTO nodejs.users (name, age, married, comment) VALUES('zero',24,0,'자기소개');
SELECT * FROM modejs.users;
//where문으로 특정 조건을 가진 데이터만 조회할 수 있습니다.
SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
//OR도 사용할 수 있습니다.
SELECT id, name FROM nodejs.users WHERE married=0 OR age > 30;
//ORDER BY로 정렬이 가능하다.
SELECT id, name FROM nodejs.users ORDER BY age DESC;
//조회할 로우 개수를 설정한다.
SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1;
//로우 개수를 설정하면서 몇 개를 건너뛸지 설정한다.
//게시판 등의 페이징에 유용하다.
SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1 OFFSET 1;
UPDATE nodejs.users SET comment='바꿀 내용' WHERE id=2;
데이터베이스에 있는 데이터를 삭제하는 방법
DELETE FROM nodejs.users WHERE id = 2;
$npm i express morgan nunjucks sequelize sequelize-cli mysql2
$npm i -D nodemon
$npx sequelize init
//modules/index.js
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;
//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('vies',{
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'),'빈 포트에서 대기중');
});
MySQL과 연동할 때는 config 폴더 안의 config.json정보가 사용된다.
따라서 config.json에 password, database등을 수정한다.
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:'user',
paranoid:false,
charset:'utf8',
collate:'utf8_general_ci',
});
}
static associate(db){}
};
테이블과 테이블간의 관계를 정의할 수 있는데, 1:1, 1:N, N:M 으로 정의할 수 있다.
시퀄라이즈에서는 1:N의 관계를 hasMany라는 메서드로 표현한다. 이 메서드를 이용하면 users 테이블의 로우 하나를 불러올 때 연결된 comments 테이블의 로우들도 같이 불러올 수 있다. 반대로 belongsTo 메서드를 사용하면 comments 테이블의 로우를 불러올 때 연결된 users테이블의 로우를 가져온다. 즉, 다른 모델의 정보가 들어가는 테이블에 사용한다.
1:1관계에서는 hasOne메서드를 사용한다. 여기서도 반대의 경우 belongsTo 메서드를 사용하는데, 반대로되면 안된다.
N:M 관계를 표현하기 위해 belongsToMany 메서드를 사용한다. 이 관계에서는 양쪽 보델에 모두 belongToMany 메서드를 사용한다.
관계 쿼리란 MySQL의 JOIN 기능으로 시퀄라이즈의 include 속성을 사용한다.
findOne이나 findAll 메서드를 호출할 때 프로미스의 결과로 모델을 반환한다(findAll은 모두 찾는 것이므로 모델의 배열을 반환한다).
include: [{
model: Comment,
}]
});
console.log(user.Comments); //사용자 댓글
특정 사용자를 가져오면서 그 사람의 댓글까지 모두 가져오는 시퀄라이즈문이다. 어떤 모델과 관계가 있는지 include 배열에 넣어주면 된다. 이때, 배열인 이유는 다양한 모델과 관계가 있을 수 있기 때문이다.
관계를 설정했다면 getCOmments(조회) 이외에도 setComments(수정), addComment(하나 생성), addComments(여러개 생성), removeComments(삭제) 메서드를 지원한다.
//관계 설정시 as로 등록
db.User.hasMany(db.Comment, {
foreignKey: 'commenter',
sourceKey: 'id',
as: 'Answers'
});
//쿼리할 때
const user = await User.findOne({});
const comments = await user.getAnswers();
console.log(comments); //사용자 댓글
** include나 관계 쿼리 메서드에서도 where이나 attributes 같은 옵션을 사용할 수 있다.
만약 시퀄라이즈의 쿼리를 사용하기 싫거나 잘 모르겠다면 직접 SQL문을 통해 쿼리할 수 있다.
const [result, metadata] = await sequelize.query('SELECT * from comments');
console.log(result);