진취적 삶
07 MySQL 본문
MySQL 은 SQL 언어를 사용하는 관계형 데이터베이스 관리 시스템의 대표 주자
몽고디비는 NoSQL의 대표 주자이다 .
7.1 데이터 베이스란
데이터베이스 : 관련성을 가지며 중복이 없는 데이터들의 집합이다 . 이러한 데이터 베이스를 관리하는 시스템을 DBMS (데이터 베이스 관리 시스템) 라고 한다 .
RDBMS 관계형 DBMS가 많이 사용된다.
7.4 데이터 베이스 및 테이블 생성하기
7.4.1 데이터 베이스 생성하기
워크벤치에서 데이버테이스 모양 버튼 누르고
Charset/Collection 을 각각 utf8mb4 와 utf8mb4_general_ci 로 바꾼다.
7.4.2 테이블 생성하기
- CREATE TABLE [데이터베이스명.테이블명]
- ID (고유 식별자 )
컬럼 : 세로 필드의 집합
로우 :가로 필드의 집합
필드 :컬럼과 로우가 교차하는 칸 하나
컬럼 자료형
- INT 정수 FLOAT ,DOBULE 소수
- VARCHAR(자릿수) CHAR(자릿수) 자료형 VARCHAR 는 가변 길이 CHAR 는 고정 길이 VARCHAR(10)은 0~10 CHAR(10)은 10인 문자열
- TEXT 는 긴 글 저장
- TINYINT -128 부터 127 정수
- DATETIME 날짜와 시간 정보
자료형 뒤에 옵션
- ID 컬럼에는 AUTO_INCREMENT 자동으로 1씩 올림
- UNSIGNED 숫자 자료형
- 기본 키인 경우에 PRIMARY KEY 옵션 고유의 값
- UNIQUE INDEX 해당 값이 고유해야 하는지에 대한 옵션
CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int unsigned NOT NULL,
`married` tinyint(1) NOT NULL,
`comment` text,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='사용자 정보 '
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT,
`commenter` int NOT NULL,
`comment` varchar(100) NOT NULL,
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`commentscol` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `commenter_idx` (`commenter`),
CONSTRAINT `commenter` FOREIGN KEY (`commenter`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='댓글'
7.5 CRUD 작업하기
CRUD : Create, Read, Update, Delete 의 첫 글자를 모은 두문자어
7.5.1 CREATE
데이터 넣기
7.5.2 READ
SELECT * FROM nodejs.users;
7.5.3 UPDATE
UPDATE nodejs.users SET comment = '하이' WHERE id=2 ;
워크벤치에서 수정하면됨
7.5.4 DELETE
DELETE FROM nodejs.users WHERE id=2;
7.6 시쿼라이즈 사용하기
노드에서 MySQL 데이터베이스에 접속
시퀄라이즈는 ORM 으로 분류된다. ORM은 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다.
시퀄라이즈는 자바스크립트 구문을 알아서 SQL로 바꿔준다.
npm i express morgan sequelize sequelize-cli mysql2
sequelize-cli 은 시퀄라이즈 명령어를 실행하기 위한 패키지
mysql2는 MYSQL 과 시퀄라이즈를 이어주는 드라이버
npx sequelize init
전역 설치 없이 명령어로 사용 하기 위해 npx
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;
7.6.1 MySQL 연결하기
const Sequelize = require("sequelize");
class User extends Sequelize.Model {
static initiate(sequelize) {
User.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) {}
}
module.exports = User;
User 델 Sequelize.Model 을 확장한 클래스 모델은 크게 static initiate 메서드와 static associate 메서드로 나누어진다.
static initiate 메서드에는 테이블에 대한 설정
static associate 메서드에는 다른 모델과의 관계를 적는다.
시퀄라이즈의 자료형은 MySQL 자료형과는 조금 다르다
- VARCHAR → STRING
- INT →INTEGER
- TINYINT → BOOLEAN
- DATETIME → DATE
- NOT NULL → allowNull
모델 init 메서드의 두번째 인수는 테이블 옵션
- sequelize :static initiate 메서드의 매개변수와 연결되는 옵션
- timestamps : true 속성이면 시퀄라이즈는 createdAt 과 updatedAt 컬럼을 추가
- underscored : camel case 에서 스네이크 케이스로 바꾸는 옵션 (createdAt → created_at)
- paranoid : true로 설정하면 deletedAt 컬럼이 생긴다.
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.initiate(sequelize);
Comment.initiate(sequelize);
User.associate(db);
User.associate(db);
module.exports = db;
7.6.3 관계 정의하기
사용자 한명은 여러개의 댓글을 작성할수 있다. 그러나 댓글 하나에 여러명일수는 없다.
이러한 관계를 1:N
7.6.3.1 1:N
시퀄라이즈는 1:N을 hasMany 라는 메서드로 표현
7.6.3.2 1:1
1:1 은 hasOne 메서드를 사용한다.
db.User.hasOne(db.Info, { foreignKey: "UserId", sourceLey: "id" });
db.User.belongsTo(db.User, { foreignKey: "UserId", sourceLey: "id" });
7.6.3.3. N:M
N:M 은 belongsToMany
게시글과 태그로 생각하면 좋다 .
db.Post.belongsToMany(db.Hashtag, { through:'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, {through:'PostHashtag')} ;
7.6.4 쿼리 알아보기
쿼리는 프로미스를 반환하므로 then 을 붙여 결괏값을 받을수 있다.
INSERT INTO nodejs.users(name,age,married,comment)VALUES('suha',26,0,'자기소개')
const {User} =require('../models')
User.create({
name:'suha',
age:26,
married:false,
comment:'자기소개',});
데이터 조회
SELECT * FROM nodejs.users ;
User.findAll({});
SELET *FROM nodejs.users LIMIT 1 ;
User.findOne{()};
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},
},
});
Op.get (초과) ,Op.get(이상) Op.lt(미만) Op.lte(이하) Op.ne(같지 않음) Op.or(또는)
Op.in(배열 요소중 하나) Op.notIn(배열 요소와 모두 다름)
SELECT name ,age FROM nodejs.users WHERE married=0 or age>30 ;
const {Op} =require('sequelize')
const {User} = require('../models');
User.findAll ({
attributes :['name','age'],
where : {
[Op.or]:[{ married:false},{age:{[Op.gt]:30}}],
},
});
SELETCT id,name FROM users ORDER BY age DESC LIMIT 1 OFFSET 1 ;
User.findAll [ {
attributes:['id','name'],
order:['age','DESC'],
limit:1,
offseg:1,
});
DELETE FROM nodejs.users WHERE id=2;
User.destory ({
where:{id:2}
});
7.6.4.1 관계 쿼리
현재 User 모델은 Comment 모델과 hasMany-belongsTo 관계이다 . 특정 사용자를 가져오면서 그 사람의 댓글까지 모두 가져오고 싶다면 include 속성을 사용하자
const user = await User.findOne ({
include: [{
model:Comment ,
}]
});
console.log(user.Comments)
const user = await User.findOne({});
const comments = await user.getComments();
console.log(comments) //사용자 댓글
a관계를 설정했으면 메서드를 지원한다. getComments (조회) ,setComments(수정) addComment(하나 생성) ,addComments(여러개 생성)
const user = await User.findOne({});
const comment1 =await Comment.create();
const comment2 = await Comment.create();
await user.addComment ([comment1,comment2]);
7.6.4.2 SQL 쿼리하기
const [result,metadata] = await sequelize.query ('SELECT * from comments')
console.log(result) ;
몽고디비는 NoSQL의 대표 주자이다 .
7.1 데이터 베이스란
데이터베이스 : 관련성을 가지며 중복이 없는 데이터들의 집합이다 . 이러한 데이터 베이스를 관리하는 시스템을 DBMS (데이터 베이스 관리 시스템) 라고 한다 .
RDBMS 관계형 DBMS가 많이 사용된다.
7.4 데이터 베이스 및 테이블 생성하기
7.4.1 데이터 베이스 생성하기
워크벤치에서 데이버테이스 모양 버튼 누르고
Charset/Collection 을 각각 utf8mb4 와 utf8mb4_general_ci 로 바꾼다.
7.4.2 테이블 생성하기
- CREATE TABLE [데이터베이스명.테이블명]
- ID (고유 식별자 )
컬럼 : 세로 필드의 집합
로우 :가로 필드의 집합
필드 :컬럼과 로우가 교차하는 칸 하나
컬럼 자료형
- INT 정수 FLOAT ,DOBULE 소수
- VARCHAR(자릿수) CHAR(자릿수) 자료형 VARCHAR 는 가변 길이 CHAR 는 고정 길이 VARCHAR(10)은 0~10 CHAR(10)은 10인 문자열
- TEXT 는 긴 글 저장
- TINYINT -128 부터 127 정수
- DATETIME 날짜와 시간 정보
자료형 뒤에 옵션
- ID 컬럼에는 AUTO_INCREMENT 자동으로 1씩 올림
- UNSIGNED 숫자 자료형
- 기본 키인 경우에 PRIMARY KEY 옵션 고유의 값
- UNIQUE INDEX 해당 값이 고유해야 하는지에 대한 옵션
CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`age` int unsigned NOT NULL,
`married` tinyint(1) NOT NULL,
`comment` text,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='사용자 정보 '
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT,
`commenter` int NOT NULL,
`comment` varchar(100) NOT NULL,
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`commentscol` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `commenter_idx` (`commenter`),
CONSTRAINT `commenter` FOREIGN KEY (`commenter`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='댓글'
7.5 CRUD 작업하기
CRUD : Create, Read, Update, Delete 의 첫 글자를 모은 두문자어
7.5.1 CREATE
데이터 넣기
7.5.2 READ
SELECT * FROM nodejs.users;
7.5.3 UPDATE
UPDATE nodejs.users SET comment = '하이' WHERE id=2 ;
워크벤치에서 수정하면됨
7.5.4 DELETE
DELETE FROM nodejs.users WHERE id=2;
7.6 시쿼라이즈 사용하기
노드에서 MySQL 데이터베이스에 접속
시퀄라이즈는 ORM 으로 분류된다. ORM은 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다.
시퀄라이즈는 자바스크립트 구문을 알아서 SQL로 바꿔준다.
npm i express morgan sequelize sequelize-cli mysql2
sequelize-cli 은 시퀄라이즈 명령어를 실행하기 위한 패키지
mysql2는 MYSQL 과 시퀄라이즈를 이어주는 드라이버
npx sequelize init
전역 설치 없이 명령어로 사용 하기 위해 npx
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;
7.6.1 MySQL 연결하기
const Sequelize = require("sequelize");
class User extends Sequelize.Model {
static initiate(sequelize) {
User.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) {}
}
module.exports = User;
User 델 Sequelize.Model 을 확장한 클래스 모델은 크게 static initiate 메서드와 static associate 메서드로 나누어진다.
static initiate 메서드에는 테이블에 대한 설정
static associate 메서드에는 다른 모델과의 관계를 적는다.
시퀄라이즈의 자료형은 MySQL 자료형과는 조금 다르다
- VARCHAR → STRING
- INT →INTEGER
- TINYINT → BOOLEAN
- DATETIME → DATE
- NOT NULL → allowNull
모델 init 메서드의 두번째 인수는 테이블 옵션
- sequelize :static initiate 메서드의 매개변수와 연결되는 옵션
- timestamps : true 속성이면 시퀄라이즈는 createdAt 과 updatedAt 컬럼을 추가
- underscored : camel case 에서 스네이크 케이스로 바꾸는 옵션 (createdAt → created_at)
- paranoid : true로 설정하면 deletedAt 컬럼이 생긴다.
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.initiate(sequelize);
Comment.initiate(sequelize);
User.associate(db);
User.associate(db);
module.exports = db;
7.6.3 관계 정의하기
사용자 한명은 여러개의 댓글을 작성할수 있다. 그러나 댓글 하나에 여러명일수는 없다.
이러한 관계를 1:N
7.6.3.1 1:N
시퀄라이즈는 1:N을 hasMany 라는 메서드로 표현
7.6.3.2 1:1
1:1 은 hasOne 메서드를 사용한다.
db.User.hasOne(db.Info, { foreignKey: "UserId", sourceLey: "id" });
db.User.belongsTo(db.User, { foreignKey: "UserId", sourceLey: "id" });
7.6.3.3. N:M
N:M 은 belongsToMany
게시글과 태그로 생각하면 좋다 .
db.Post.belongsToMany(db.Hashtag, { through:'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, {through:'PostHashtag')} ;
7.6.4 쿼리 알아보기
쿼리는 프로미스를 반환하므로 then 을 붙여 결괏값을 받을수 있다.
INSERT INTO nodejs.users(name,age,married,comment)VALUES('suha',26,0,'자기소개')
const {User} =require('../models')
User.create({
name:'suha',
age:26,
married:false,
comment:'자기소개',});
데이터 조회
SELECT * FROM nodejs.users ;
User.findAll({});
SELET *FROM nodejs.users LIMIT 1 ;
User.findOne{()};
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},
},
});
Op.get (초과) ,Op.get(이상) Op.lt(미만) Op.lte(이하) Op.ne(같지 않음) Op.or(또는)
Op.in(배열 요소중 하나) Op.notIn(배열 요소와 모두 다름)
SELECT name ,age FROM nodejs.users WHERE married=0 or age>30 ;
const {Op} =require('sequelize')
const {User} = require('../models');
User.findAll ({
attributes :['name','age'],
where : {
[Op.or]:[{ married:false},{age:{[Op.gt]:30}}],
},
});
SELETCT id,name FROM users ORDER BY age DESC LIMIT 1 OFFSET 1 ;
User.findAll [ {
attributes:['id','name'],
order:['age','DESC'],
limit:1,
offseg:1,
});
DELETE FROM nodejs.users WHERE id=2;
User.destory ({
where:{id:2}
});
7.6.4.1 관계 쿼리
현재 User 모델은 Comment 모델과 hasMany-belongsTo 관계이다 . 특정 사용자를 가져오면서 그 사람의 댓글까지 모두 가져오고 싶다면 include 속성을 사용하자
const user = await User.findOne ({
include: [{
model:Comment ,
}]
});
console.log(user.Comments)
const user = await User.findOne({});
const comments = await user.getComments();
console.log(comments) //사용자 댓글
a관계를 설정했으면 메서드를 지원한다. getComments (조회) ,setComments(수정) addComment(하나 생성) ,addComments(여러개 생성)
const user = await User.findOne({});
const comment1 =await Comment.create();
const comment2 = await Comment.create();
await user.addComment ([comment1,comment2]);
7.6.4.2 SQL 쿼리하기
const [result,metadata] = await sequelize.query ('SELECT * from comments')
console.log(result) ;
'개발 도서 > Node.js 교과서' 카테고리의 다른 글
09 익스프레스로 SNS 서비스 만들기 (0) | 2023.07.14 |
---|---|
08 몽고디비 (0) | 2023.07.14 |
06 익스프레스 웹 서버 만들기 (0) | 2023.07.14 |
05 패키지 매니저 (0) | 2023.07.14 |
04 http 모듈로 서버 만들기 (0) | 2023.07.14 |