관리 메뉴

진취적 삶

07 MySQL 본문

개발 도서/Node.js 교과서

07 MySQL

hp0724 2023. 7. 14. 11:44

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