티스토리 뷰

Node.js

[Node.js 교과서] 섹션7 - MySQL

bearn_soo 2024. 11. 9. 19:16

데이터베이스란?


  • 데이터베이스: 관련성을 가지며 중복이 없는 데이터들의 집합.
  • DBMS(DataBase Management System): 데이터베이스를 관리하는 시스템(데이터베이스 관리 시스템)
  • RDBMS(Relation DBMS): 관계형 DBMS. SQL이라는 언어를 사용해 데이터 를 관리함.

대표적인 RDBMS로 Oracle, MySQL, MSSQL 등이 있습니다. RDBMS에서 데이터를 관리하려면 SQL을 사용합니다.

 

 

맥 MySQL 설치


  • HomeBerew 설치
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • HomeBrew를 이용해 MySQL 설치
brew install mysql
brew services start mysql
mysql_secure_installation
  • MySQL 접속
mysql -h localhost -u root -p

 

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


데이터베이스 생성하기

`CREATE SCHEMA [데이터베이스명] 옵션` 명령어를 이용해 데이터베이스를 생성할 수 있습니다. MySQL에서 데이터베이스와 스키마는 같은 개념입니다.

  • `DEFAULT CHARACTER SET utf8mb4`: 스키마 내에서 생성되는 모든 테이블과 열에 대해 기본 문자 집합을 utf8mb4로 설정합니다.
  • `DEFAULT COLLATE utf8mb4_general_ci`: `COLLATE`는 해당 `CHARACTER SET`을 어떤 형식으로 정렬할지를 의미합니다. 기본 정렬 규칙(collation)을 utf8mb4_general_ci로 설정합니다.
CREATE SCHEMA `nodejs` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;

테이블 생성하기

`CREATE TABLE [데이터베이스 명.테이블 명]`명령어를 사용해 테이블을 생성합니다.

컬럼의 자료형

  • `INT`: 정수를 의미합니다.
  • `VARCHAR(자릿수)`: 자릿수만큼의 문자열을 넣을수 있습니다.
  • `TEXT`: 긴글을 저장할 때 사용합니다. 수백 자 이내의 문자열은 보통 VARCHAR로 많이 처리하고, 그보다 길면 TEXT로 처리합니다.
  • `TINYINT`: -128부터 127까지의 정수를 저장할 때 사용합니다.
  • `DATETIME`: 날짜와 시간에 대한 정보를 담고 있습니다.

옵션

  • `NULL`/`NOT NULL`: 빈칸을 허용할지 여부를 묻는 옵션입니다.
  • `AUTO_INCREMENT`: 숫자를 저절로 올리는 옵션입니다. id컬럼은 기본으로 설정되어 있습니다.
  • `UNSIGEND`: 숫자 자료형에 적용되는 옵션입니다. 숫자 자료형은 기본적으로 음수 범위를 지원합니다.
  • `ZERO FILL`: 비어있는 자리에 모두 0을 넣습니다. 숫자 의 자릿수가 조덩되어 있을 때 사용할 수 있습니다.
  • `DEFAULT 값`: 데이터베이스 저장 시 해당 컬럼에 값이 없을 떄 MySQL이 기본값을 대신 넣습니다.
  • `PRIMARY KEY`: 해당 컬럼을 기본키로 지정합니다.
  • `UNIQUE INDEX`: 해당 값이 고유해야 하는지에 대한 옵션입니다. `PRIMARY KEY`는 자동으로 `UNIQUE INDEX`를 포함합니다.
CREATE TABLE nodejs.users (
	id INT NOT NULL AUTO_INCREMENT,
    name VARCHR(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;

만들어진 테이블 확인하기

`DESC 테이블명` 명령어를 사용해 만들어진 테이블을 확인합니다.

DESC users;

만들어진 테이블 삭제하기

`DROP TABLE [테이블명]` 명령어를 사용해 만들어진 테이블을 삭제합니다.

DROP TABLE users;

외래키를 가지는 테이블 생성하기

다른 테이블의 기본키를 저장하는 컬럼을 외래 키(foreign key)라고 합니다. `CCONSTRAINT [제약조건명] FOREIGN KEY [컬럼명] REFERENCES [참고하는 컬럼명]`으로 외래 키를 지정할 수 있습니다.

`ON UPDATE`와 `ON DELETE`를 `CASCADE`로 설정하면 참고하는 부모 테이블 데이터가 수정되거나 삭제되면 그것과 연결된 자식 테이블도 같이 수정하거나 삭제합니다.

 

CREATE TABLE nodejs.comments (
	id INT NOT NULL AUTO_INCREMENT,
    commenter INT NOT NULL,
    comment VARCHAR(100) NOT NULL,
    created_at DATETIME NOT NULL DEFAULT now(),
    PRIMARY KEY(id),
    INDEX commenter_idx (commenter ASC),
    CONSTRAINT commenter
    FOREIGN KEY (commenter)
    REFERENCES nodejs.users (id)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
COMMENT = '댓글'
ENGINE=InnoDB;

만들어진 테이블들을 확인하기

SHOW TABLES;

 

CRUD 작업하기


Create(생성)

데이터를 생성해 데이터베이스에 넣는 SQL명령어는 `INSERT ONTO [테이블명] ([컬럼1], [컬럼2], ...) VALUES ([값1], [값2], ...)` 입니다.

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

READ(조회)

데이터베이스에 있는 데이터를 조회하는 SQL명령어는 `SELECT * FROM [테이블명]`입니다. 특정 컬럼만 조회하려면 `SELECT` 절 다음에 조회할 컬럼을 넣으면 됩니다. 특정 조건을 가진 데이터만 조회하려면 `WHERE` 절을 사용하면 됩니다. `AND`와 `OR`를 사용해 조건을 줄 수 있습니다.

SELECT name, age FROM nodejs.users WHRE married = 1 AND age > 30;

`ORDER BY [컬럼명] [ASC|DESC]` 키워드를 사용해 정렬이 가능합니다. DESC는 내림차순 ASC는 오름차순입니다.

SELECT id, name FROM nodejs.users ORDER BY age DESC;

`LIMIT [숫자]` 키워드를 이용해 조회할 로우 개수를 설정할 수 있습니다.

SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1;

`OFFSET [건너뛸 숫자]` 키워드를 사용해 로우 개수를 설정하면서 몇 개를 건너 뛸지 설정할 수 있습니다.

SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1 OFFSET 1;

UPDATE(수정)

`UPDATE [테이블명] SET [컬럼명 = 바꿀 값] WHERE [조건]` 명령어를 사용해 데이터에비으세 있는 데이터를 수정할 수 있습니다.

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

DELETE(삭제)

`DELETE FROM [테이블명] WHRE [조건]` 명령어를 사용해 데이터베이스에 있는 데이터를 삭제할 수 있습니다.

DELETE FROM nodejs.users WHERE id = 2;

 

시퀄라이즈 사용하기


  • ORM(Object-realational Mapping): 객체와 데이터에비스의 릴레이션을 매핑해주는 도구
  • 시퀄라이즈: 자바스크립트 ORM

시퀄라이즈를 이용하면 SQL을 직접 사용하지 않고도 자바스크립트 만으로 MySQL을 조작할 수 있습니다.

프로젝트 설정

  • sequelize-cli: 시퀄라이즈 명령어를 실행하기 위한 패키지입니다.
  • mysql2: MySQL과 시퀄라이즈를 이어주는 드라이버입니다. mysql2 자체는 데이터베이스 프로그램이 아닙니다.
npm install sequelize sequelize-cli mysql2

시퀄라이즈 초기화

npx sequelize-cli init

MySQL 연결 설정

MySQL과 연동할 때는 `config`폴더 안의`config/config.json` 정보가 사용됩니다.

{
  "development": {
    "username": "root",
    "password": "password",
    "database": "database_development",
    "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),
          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/comment.js`
const Sequelize = require("sequelize");

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, { foreignKey: "commenter", targetKey: "id" });
  }
}

module.exports = Comment;
  • `models/index.js`

`Sequelize`는 시퀄라이즈 패키지이자 생성자입니다. `config/config.json`에서 데이터베이스 설정을 불러온 후 `new Sequelize`를 통해 MySQL 연결 객체를 생성합니다. 연결 객체를 나중에 재사용하기 위해 `db.sequelize`에 넣어놓습니다. 앞으로 `db`객체를 `require`해서 `User`와`Comment` 모델에 접근할 수 있습니다. `모델.init`이 실행되어야 테이블이 모델로 연결됩니다. `모델.associate`을 실행하면 다른 테이블과의 관계를 연결합니다.

const Sequelize = require("sequelize");
const User = require("./user");
const Comment = require("./comment");

const env = process.env.NODE_ENV || "development";
const config = require(__dirname + "/../config/config.json")[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;

 

모델 관계 정의


일대다 (One-to-Many) 관계

User.hasMany(Comment);
Comment.belongsTo(User);

일대일 (One-to-One) 관계

User.hasOne(Info);
Info.belongsTo(User);

다대다 (Many-to-Many) 관계

Post.belongsToMany(Hashtag);
Hashtag.belongsToMany(Post);

 

쿼리 알아보기


  • 테이블의 모든 데이터를 조회
// SELECT * FROM nodejs.users;
User.findAll({});
  • 테이블 데이터에서 원하는 컬럼만 조회
// SELECT name, age FROM nodejs.users;
User.findAll({
	attributes:['name', 'married'],
});
  • where 조건 나열
// SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
User.findAll({
	attrubutes:['name', 'age'],
    where:{
    	married: true,
        age: { [Op.gt]: 30 },
    }
});
  • `OFFSET` 과 `LIMIT` 설정
// 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 },
});

관계 쿼리

  • 조회
const user = await User.findOne({
	include: [{
    	model: Comment,
    }]
});

console.log(user.Comments); // 사용자 댓글

const user = await User.findOne({});
const comments = await user.getComments();

console.log(user.Comments); // 사용자 댓글
  • 생성
const user = await User.findOne({});
const comment = await Comment.create();
await user.addComment(comment);
// 또는
await user.addComment(comment.id);
  • 여러개 추가
const user = await User.findOne({});
const comment1 = await Comment.create();
const comment2 = await Comment.create();
await user.addComment([comment1, comment2]);

시퀄라이즈로 SQL 쿼리하기

const [result, metadata] = await sequelize.query('SELECT * from comments');
console.log(result);

 

참고


 

Node.js 교과서 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

 

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지 강의 | 제로초(조현영) - 인프런

제로초(조현영) | 노드가 무엇인지부터, 자바스크립트 최신 문법, 노드의 API, npm, 모듈 시스템, 데이터베이스, 테스팅 등을 배우고 5가지 실전 예제로 프로젝트를 만들어 나갑니다. 클라우드에 서

www.inflearn.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함