데이터베이스 : 관련성을 가지며 중복이 없는 데이터들의 집합
DBMS : 데이터베이스를 관리하는 시스템
RDMS라고 부르는 관계형 DBMS가 많이 사용
(MySQL, 워크밴치 설치 과정 생략)
CREATE SCHEMA [데이터베이스명] : 데이터베이스를 생성하는 명령어 (스키마 = 데이터베이스)
use nodejs; : nodejs 데이터베이스를 사용하겠다는 것을 알림
DEFAULT CHARACTER SET ufg8mb4 DEFAULT COLLATE utf8 mb4_general_ci를 붙여 한글, 이모티콘 사용 가능
CREATE TABLE [데이터베이스명.테이블명] : 테이블을 생성하는 명령어
뒤에 콤마(,)로 구분하여 컬럼들을 만든다.
컬럼 옆에는 컬럼의 자료형을 선언한다. (INT, VARCHAR(자릿수), TINYINT, TEXT, DATETIME
자료형 뒤에는 다양한 옵션들을 붙인다. NOT NULL, NULL, UNSIGNED, AUTO_INCREMENT, ZEROFILL, DEFAULT
PRIMARY KEY : 기본 키로 로우를 대표하는 고유한 값을 의미
COMMENT : 테이블에 대한 보충 설명, 필수 아님
ENGINE : MyISAM, InnoDB가 많이 사용
DESC [테이블명] : 만들어진 테이블을 확인하는 명령어
DROP TABLE [테이블명] : 테이블을 제거하는 명령어
외래키(foreign key) : 다른 테이블의 기본 키를 저장하는 컬럼
CONSTRAINT [제약조건명] FOREIGN KEY [컬럼명] REFERENCES [참고하는 컬럼명] : 외래키 지정
CASCADE 설정 : 사용자 정보가 수정되거나 삭제되면 그것과 연결된 정보도 같이 수정하거나 삭제
SHOW TABLES; : 테이블 이름을 띄움
CRUD : create, read, update, delete의 첫 글자를 모은 두 문자어
데이터를 생성해서 데이터베이스에 넣는 작업
INSERT INTO [테이블명] ([컬럼1], [컬럼2], ... ) VALUES ([값1], [값2], ...) : 데이터를 넣는 명령어
데이터베이스에 있는 데이터를 조회하는 작업
SELECT * FROM [테이블명] : 테이블의 모든 데이터를 조회하는 sql문
데이터베이스에 있는 데이터를 수정하는 작업
UPDATE [테이블명] SET [컬럼명=바꿀 값] WHERE [조건] : 수정 명령어
데이터베이스에 있는 데이터를 삭제하는 작업
DELETE FROM [테이블명] WHERE [조건] : 삭제 명령어
시퀄라이즈 : mysql 작업을 쉽게 할 수 있도록 도와주는 라이브러리
ORM : 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해 주는 도구로 시퀄라이즈가 이에 분류됨
시퀄라이즈를 쓰면 자바스크립트 구문을 알아서 SQL로 바꿔준다.
npm i express morgan nunjucks sequelize sequelize-cli mysql2
npm i -D nodemon
npx sequelize init
- 시퀄라이즈에 필요한 sequelize와 sezuelize-cli, mysql2 패키지 설치
//app.js 생성하고 익스프레스와 시퀄라이즈 연결 코드 작성
const express = require('express');
const path = require('path');
const morgan = require('morgan');
const nunjucks = require('nunjucks');
const { sequelize } = require('./models');
// = require('./models/index.js');
const indexRouter = require('./routes');
const usersRouter = require('./routes/users');
const commentsRouter = require('./routes/comments');
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 })
//true로 설정하면 서버를 실행할 때마다 테이블을 재생성함.
//테이블을 잘못 만든 경우 true로 설정하면 됨
.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('/', indexRouter);
app.use('/users', usersRouter);
app.use('/comments', commentsRouter);
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'), '번 포트에서 대기 중');
});
//config.json
{
"development": {
"username": "root",
"password": {비밀번호}, //mysql 비밀번호
"database": "nodejs", //nodejs로 바꾸기
"host": "127.0.0.1",
"dialect": "mysql"
},
...
}
//models/user.js
const Sequelize = require('sequelize');
class User extends Sequelize.Model {
static initiate(sequelize) {
User.init({
name: {
type: Sequelize.STRING(20), //varchar
allowNull: false, //not null
unique: true, //unique
},
age: {
type: Sequelize.INTEGER.UNSIGNED, //int
allowNull: false,
},
married: {
type: Sequelize.BOOLEAN, //tinyint
allowNull: false,
},
comment: {
type: Sequelize.TEXT,
allowNull: true,
},
created_at: {
type: Sequelize.DATE, //datetime
allowNull: false,
defaultValue: Sequelize.NOW, //default now()
},
}, {
sequelize,
//static initiate 메서드의 매개변수와 연결되는 옵션
timestamps: false,
//true면 시퀄라이즈는 createaAt, updateAt컬럼 추가, 각각 로우가 생성, 수정될 때 시간 입력
underscored: false,
//캐멀 케이스를 스네이크 케이스로 바꾸는 옵션
modelName: 'User',
//모델 이름 설정
tableName: 'users',
//테이블 이름 설정
paranoid: false,
//true로 설정하면 deletedAt컬럼 생기고 로우 삭제할 때 시간 입력
charset: 'utf8',
collate: 'utf8_general_ci',
});
}
static associate(db) {
db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id' });
}
};
module.exports = User;
//models/comment.js
const Sequelize = require("sequelize");
const { FOREIGNKEYS } = require("sequelize/lib/query-types");
class Comment extends Sequelize.Model {
static initiate(sequelize) {
Comment.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, { FOREIGNKEYS: "commenter", targetKey: "id" });
}
}
module.exports = Comment;
//models/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;
db.User = User;
db.Comment = Comment;
User.initiate(sequelize);
Comment.initiate(sequelize);
User.associate(db);
Comment.associate(db);
module.exports = db;
- 생성한 모델 index.js에 연결
1:N 관계 : hasMany, belongsTo 사용
//user.js
static associate(db) {
db.User.hasMany(db.Comment, { foreignKey: "commenter", sourceKey: "id" });
}
//comment.js
static associate(db) {
db.Comment.belongsTo(db.User, { FOREIGNKEYS: "commenter", targetKey: "id" });
}
hasMany에서 sourceKey 속성에 id / belongsTo에서 targetKey 속성에 id / 모두 User 모델의 id
1:1 관계 : hasOne, belongsTo 사용
N:M 관계 : belongsToMany 사용
//로우 생성
insert into values (~~)
=
User.create({
name:'zero',
age: 24,
married: false,
comment: '자기소개1',
});
select * from nodejs.users;
=
User.findAll({});
select name, married from nodejs.users;
=
User.findAll({
attribues: ['name', 'married'],
});
select name, age from nodejs.users where married = 1 and age > 30;
=
User.findAll({
attributes: ['name', 'age'],
where: {
married: true,
age: { [0p.gt]: 30},
},
});
select id, name from users order by age desc limit 1 offset 1;
=
User.findAll({
attributes: ['id', 'name'],
order: ['age', 'DESC'],
limit: 1,
offset: 1,
});
update nodejs.users set comment = '바꿀 내용' where id = 2;
=
User.update({
comment: '바꿀내용',
}, {
where : {id : 2},
});
delete from nodejs.users where id =2;
=
User.destroy({
where: {id:2},
});
관계 쿼리
관계가 맺어져 있는 테이블을 모두 가지고 오고 싶다면 include 속성을 사용한다.
const user = await User.findOne({
include: [{
model: Comment,
}]
});
관계를 설정하고 나면 getComments(조회), setComments(수정), addCommment(하나 생성), addComments(여러 개 생성), removeComments(삭제) 메서드를 지원한다.
SQL 쿼리
시퀄라이즈의 쿼리 사용을 추천하지만 할 수 없는 경우 이와 같이 sql 쿼리 작성할 수 있다.
const [result, metadata] = await sequelize.query('select * from comments');
1. 관련성을 가지며 중복이 없는 데이터들의 집합을 ( 데이터베이스)라고 한다.
2. ( PRIMARY KEY )는 기본 키로 로우를 대표하는 고유한 값을 의미
3. CRUD는 ( create ), ( read ), ( update ), ( delete )의 첫 글자를 모은 두 문자어
4. 특정 조건을 가진 데이터만 조회하기 위해 ( WHERE ) 절을 사용한다.
5. mysql 작업을 쉽게 할 수 있도록 도와주는 라이브러리는 ( 시퀄라이즈 )이다.
6. 1:N 관계를 표현하기 위해 속성 ( hasMany ), ( belongsTo )를 사용한다.
7. 관계 쿼리를 사용하기 전에 ( include ) 속성을 사용한다.
1. 밑에 나온 쿼리를 nodsjs로 나타내보시오.
select * from nodejs.users;
2. nodejs에서 SQL 쿼리를 써야 하는 경우, 빈칸을 채우시오.
const [result, metadata] = [ ]('select * from comments');
1.
User.findAll({});
2.
const [result, metadata] = await sequelize.query('select * from comments');
출처 : 조현영, 『 Node.js 교과서 개정 3판』, 길벗(2022)
Corner Node.js 1
Editor : Krong
[노드 1팀] 8장. 몽고디비 (0) | 2024.12.27 |
---|---|
[노드 1팀] 6장. 익스프레스 웹 서버 만들기 (0) | 2024.11.22 |
[노드 1팀] 5장. 패키지 매니저 (0) | 2024.11.15 |
[노드 1팀] 4장. http 모듈로 서버 만들기 (0) | 2024.11.15 |
[노드 1팀] 3장. 노드 기능 알아보기 (2) (0) | 2024.11.08 |