7장. MySQL

Doozuu·2023년 5월 9일
0

MySQL

목록 보기
2/5

지금까지는 모든 데이터를 변수에 저장했다.

  • 변수에 저장했다는 것은 컴퓨터 메모리에 저장했다는 뜻이다.
  • 따라서 서버가 종료되면 메모리가 정리되면서 저장했던 데이터도 사라져버린다.
    이를 방지하기 위해서는 데이터베이스를 사용해야 한다.

다양한 데이터베이스가 있지만, 여기서는 MySQL과 몽고디비를 사용한다.

  • MySQL : SQL 언어를 사용하는 관계형 데이터베이스 관리 시스템의 대표 주자
  • 몽고디비 : NoSQL의 대표 주자



7.1 데이터베이스란?

데이터베이스는 관련성을 가지며 중복이 없는 데이터들의 집합이다.
이러한 데이터베이스를 관리하는 시스템을 DBMS라고 한다.

보통 서버의 하드 디스크나 SSD 등의 저장 매체에 데이터를 저장한다.
저장 매체가 고장 나거나 사용자가 직접 데이터를 지우지 않는 이상 계속 데이터가 보존되므로 서버 종료 여부와 상관없이 데이터를 계속 사용할 수 있다.
또한, 서버에 데이터베이스를 올리면 여러 사람이 동시에 사용할 수 있다. 사람들에게 각각 다른 권한을 줘서 어떤 사람은 읽기만 가능하고, 어떤 사람은 모든 작업을 가능하게 할 수 있다.

데이터베이스를 관리하는 DBMS 중에는 RDBMS라고 부르는 관계형 DBMS가 많이 사용된다. 대표적인 RDBMS로 Oracle, MySQL, MSSQL 등이 있다. 이들은 SQL이라는 언어를 사용해 데이터를 관리한다.



7.2 MYSQL 설치하기(Mac)

Homebrew를 통해 설치하기

brew install mysql // 설치
brew services start mysql // mysql 시작
mysql_secure_installation // root 비밀번호 설정
mysql -h localhost -u root -p // 접속하기(비밀번호 입력)



7.3 워크벤치 설치하기

콘솔로는 데이터를 한눈에 보기에 무리가 있으므로 워크벤치라는 프로그램을 사용하면 데이터베이스 내부에 저자오딘 데이터를 시각적으로 관리할 수 있어 편리하다.
(필수적인 것은 아니며 콘솔로도 동일한 작업을 할 수 있다.)

설치

brew install --cask mysqlworkbench

버전 8.0.21로 설치하기!
보안때문에 안열리면 우클릭 -> 열기



7.4 데이터베이스 및 테이블 생성하기

7.4.1 데이터베이스 생성하기

MySQL 프롬프트에 접속

mysql -h localhost -u root -p 

데이터베이스 생성

  • CREATE SCHEMA 데이터베이스명 : 데이터베이스 생성하는 명령어 (스키마는 데이터베이스와 같은 개념)
  • 뒷 부분은 한글과 이모티콘을 사용하기 위해 붙임
    주의 : SQL 구문을 입력할 때는 마지막에 세미콜론을 붙여야 해당 구문이 실행된다.
CREATE SCHEMA `nodejs` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;

7.4.2 테이블 생성하기

테이블이란 데이터가 들어갈 수 있는 틀을 의미하며, 테이블에 맞는 데이터만 들어갈 수 있다.

MySQL 프롬프트에 다음과 같이 입력

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 = '사용자 정보'
    ENGINE = InnoDB;

사용할 데이터베이스 선택

USE nodejs;

만들어진 테이블 확인하기

  • DESC 테이블명
DESC users;


테이블 제거하기

  • DROP TABLE 테이블명
DROP TABLE users;



7.5 CRUD 작업하기

CRUD는 데이터베이스에서 많이 수행하는 네 가지 작업을 일컫는다.

7.5.1 Create

Create는 데이터를 생성해서 데이터베이스에 넣는 작업이다.

명령어 : INSERT INTO 테이블명 (컬럼1, 컬럼2,,) VALUES (값1, 값2,,)

예시

INSERT INTO nodejs.users (name, age, married, comment) VALUES ('zero', 24, 0, '자기소개1');

7.5.2 Read

Read는 데이터베이스에 있는 데이터를 조회하는 작업이다.

명령어 : SELECT * FROM 테이블명

예시

SELECT * FROM nodejs.users;

실행 결과

특정 컬럼만 조회하기

SELECT name, married FROM nodejs.users;

특정 조건을 가진 데이터만 조회하기

  • WHERE 절 사용(AND, OR)
SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;

정렬하기

  • 오름차순 : ASC
  • 내림차순 : DESC
SELECT id, name FROM nodejs.users ORDER BY age DESC;

특정 열만 조회하기

  • LIMIT 숫자
SELECT name, married FROM nodejs.users LIMIT 1;

7.5.3 Update

Update는 데이터베이스에 있는 데이터를 수정하는 작업이다.

명령어 : UPDATE 테이블명 SET 컬럼명='바꿀값' WHERE 조건

예시

UPDATE nodejs.users SET comment = '바꿀 내용' WHERE id = 2;

7.5.4 Delete

Delete는 데이터베이스에 있는 데이터를 삭제하는 작업이다.

명령어 : DELETE FROM 테이블명 WHERE 조건

예시

DELETE FROM nodejs WHERE id = 2;



7.6 시퀄라이즈 사용하기

시퀄라이즈는 MySQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리이다.
시퀄라이즈는 ORM(Object-relational Mapping)으로 분류된다.
ORM은 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다.

시퀄라이즈를 쓰는 이유는 자바스크립트 구문을 알아서 SQL로 바꿔주기 때문이다. 따라서 SQL 언어를 직접 사용하지 않고도 자바스크립트만으로 MySQL을 조작할 수 있으며, SQL을 몰라도 MySQL을 어느 정도 다룰 수 있게 된다.

설치
sequelize, sequelize-cli(시퀄라이즈 명령어를 실행하기 위한 패키지), mysql2(MySQL과 시퀄라이즈를 이어주는 드라이버) 패키지 설치

npm i express morgan nunjucks sequelize sequelize-cli mysql2
npm i -D nodemon

설치 완료 후 sequelize init 명령어 호출.
전역 설치 없이 명령어로 사용하려면 앞에 npx 붙이기

npx sequelize init

7.6.1 MySQL 연결하기

app.js

const express = require('express');
const path = require('path');
const morgan = require('morgan');
const nunjucks = require('nunjucks');

const { sequelize } = require('./models');

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 })
  .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'), '번 포트에서 대기 중');
});

MySQL과 연동할 때는 config 폴더 안의 config.json 정보가 사용된다. 다음과 같이 수정한다.
config/config.json

{
  "development": {
    "username": "root",
    "password": "root 비밀번호", // 내 MySQL 비밀번호
    "database": "nodejs", 
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
}

7.6.2 모델 정의하기

시퀄라이즈는 모델과 MySQL의 테이블을 연결해주는 역할을 한다.

User 모델을 만들어 users 테이블에 연결해보기

(시퀄라이즈는 기본적으로 모델 이름은 단수로, 테이블 이름은 복수형으로 사용한다.)
static initiate 메서드에는 테이블에 대한 설정을 하고, static associate 메서드에는 다른 모델과의 관계를 적는다.

models/user.js

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) {
    db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id' });
  }
};

module.exports = User;

모델을 생성했다면 models/index.js와 연결한다.

const Sequelize = require('sequelize');
const User = require('./user');

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에 모델담기

User.initiate(sequelize); // static initiate 메서드 호출

User.associate(db); // 다른 테이블과의 관계 연결

module.exports = db;

7.6.3 관계 정의하기

  1. 일대다 관계(1:N)
    사용자 한 명은 댓글을 여러 개 작성할 수 있지만, 댓글 하나에 사용자가 여러 명일 수는 없다. 이러한 관계를 일대다 관계라고 한다.
  2. 일대일 관계(1:1)
    일대일 관계로는 사용자와 사용자에 대한 정보 테이블을 예로 들 수 있다. 사용자 한 명은 자신의 정보를 담고 있는 테이블과만 관계가 있다. 정보 테이블도 한 사람만을 가리킨다.
  3. 다대다 관계(N:M)
    다대다 관계로는 게시글 테이블과 해시태그 테이블 관계를 예로 들 수 있다. 한 게시글에는 해시태그가 여러 개 달릴 수 있고, 한 해시태그도 여러 게시글에 달릴 수 있다.

MySQL에서는 JOIN이라는 기능으로 여러 테이블 간의 관계를 파악해 결과를 도출한다. 시퀄라이즈는 JOIN 기능도 알아서 구현한다. 대신 테이블 간에 어떠한 관계가 있는지 시퀄라이즈에 알려야 한다.

일대다 관계

시퀄라이즈는 일대다 관계를 hasMany라는 메서드로 표현한다. 반대로 belongsTo 메서드도 있다.
(다른 모델의 정보가 들어가는 테이블에는 belongsTo를 사용한다.)

모델 각각의 static associate 메서드에 넣는다.
models/user.js

static.associate(db){
	db.User.hasMany(db.Comment, {foreginKey: 'commenter' sourceKey: 'id'})
}

models/comment.js

static.associate(db){
	db.Comment.belongsTo(db.User, {foreginKey: 'commenter' targetKey: 'id'})
}

일대일 관계

1:1 관계에서는 hasMany 메서드 대신 hasOne 메서드를 사용한다.


다대다 관계

N:M 관게를 표현하기 위한 belongsToMany 메서드가 있다.


7.6.4 쿼리 알아보기

시퀄라이즈로 CRUD 작업을 하려면 먼저 시퀄라이즈 쿼리를 알아야 한다.

Create

models 모듈에서 User 모델을 불러와 create 메서드를 사용하면 된다.

const {User} = require('../models');

User.create({
	name : 'zero',
    age: 24,
    married: false,
    comment: '자기소개1',
})

Read

findAll / findOne 메서드 사용

User.findAll({}); // users 테이블의 모든 데이터 조회
User.findOne({}); // users 테이블의 데이터 하나만 가져옴
User.findAll({
  attributes: ['name', 'married'] // 원하는 컬럼만 가져오기
})

Update

update 메서드 사용

User.update({
	comment: '바꿀 내용', // 수정할 내용
},{
	where: {id: 2}, // 어떤 로우를 수정할지에 대한 조건
})

Delete

destroy 메서드 사용

User.destroy({
	where: {id:2}
})
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글