[Node.js – 기초 강좌] 6. Database 연동하기(Feat. MongoDB 소개 및 연동)

데이터베이스는 애플리케이션의 핵심 구성 요소 중 하나입니다.

특히 NoSQL 데이터베이스인 MongoDB는 유연한 스키마와 높은 성능으로 많은 개발자들에게 사랑받고 있습니다.

이번 포스팅에서는 Node.js에서 Database를 연동하는 방법을 소개하려고 하는데, 그중에서 특히 NoSQL 데이터베이스인 MongoDB를 소개하고, Mongoose를 이용하여 Node.js 애플리케이션에서 MongoDB와 연동하는 방법을 알아보겠습니다.

또한, CRUD 작업(생성, 읽기, 업데이트, 삭제)을 구현하는 방법도 살펴보겠습니다.

Node.js에서 데이터 베이스 연동

개요

웹 애플리케이션은 사용자 데이터, 세션 정보, 애플리케이션 상태 등을 저장하고 관리하기 위해 데이터베이스를 사용합니다.

데이터베이스는 관계형 데이터베이스와 비관계형 데이터베이스로 나뉘며, 각각의 장단점이 있습니다.

관계형 데이터베이스 (RDBMS)

관계형 데이터베이스는 데이터를 테이블 형태로 구조화하여 저장합니다.

각 테이블은 행(row)과 열(column)로 구성되며, 테이블 간의 관계를 정의하여 데이터를 관리합니다.

대표적인 RDBMS로는 MySQL, PostgreSQL, Oracle, MSSQL등이 있습니다.

관계형 데이터베이스는 트랜잭션, ACID 특성(Atomicity, Consistency, Isolation, Durability) 등을 지원하여 데이터의 무결성과 일관성을 보장합니다.

비관계형 데이터베이스 (NoSQL)

NoSQL 데이터베이스는 유연한 데이터 모델을 제공하며, 고정된 스키마가 없습니다.

이는 대규모 데이터 처리와 빠른 읽기/쓰기 성능이 요구되는 환경에서 유리합니다.

대표적인 NoSQL 데이터베이스로는 MongoDB, CouchDB, Cassandra, 그리고 Redis 등이 있습니다.

NoSQL 데이터베이스는 다양한 데이터 모델(문서 지향, 키-값, 열 지향, 그래프)을 지원합니다.

nodejs-database-integration

MongoDB 소개

개요

MongoDB는 고성능, 고가용성, 그리고 자동 스케일링 기능을 갖춘 오픈 소스 NoSQL 데이터베이스입니다.

전통적인 관계형 데이터베이스(RDBMS)와 달리, MongoDB는 유연한 데이터 모델을 제공하여 다양한 데이터 구조를 저장할 수 있습니다.

이는 JSON과 유사한 BSON(Binary JSON) 형식으로 데이터를 저장하며, 스키마가 고정되지 않아 데이터 구조의 변경이 쉽습니다

공식 홈페이지 (https://www.mongodb.com/)

특징

문서 지향 저장

  • 데이터를 BSON 형식으로 문서 단위 저장
  • 문서들은 컬렉션으로 그룹화

유연한 스키마

  • 고정된 스키마가 없음
  • 데이터 모델을 유연하게 변경 가능

고성능

  • 인덱싱, 복제, 샤딩 기능 제공
  • 읽기/쓰기 성능 최적화

분산 데이터베이스

  • 샤딩으로 여러 서버에 데이터 분산 저장
  • 수평적 확장 가능

복제본 세트

  • 고가용성을 위한 복제본 세트 지원
  • 기본 노드 장애 시 보조 노드 승격

강력한 쿼리 언어

  • SQL 유사한 쿼리 언어 제공
  • 복잡한 쿼리 및 데이터 분석 가능

개발자 친화적

  • 다양한 언어(JavaScript, Python, Java 등) 지원
  • 익숙한 언어로 애플리케이션 개발 가능

Editions

MongoDB Community Edition
  • 개요: 무료로 제공되는 오픈 소스 버전.
  • 주요 특징: CRUD 작업, 인덱싱, 복제, 샤딩 기능 제공.
  • 요금: 무료.
MongoDB Enterprise Advanced
  • 개요: 기업 환경을 위한 고급 기능과 보안 제공.
  • 주요 특징: LDAP 통합, Kerberos 인증, Ops Manager 등 제공.
  • 요금: 구독 기반, 사용자 수와 기능 요구 사항에 따라 결정.
MongoDB Atlas
  • 개요: 클라우드 기반 관리형 데이터베이스 서비스.
  • 주요 특징: 자동 확장, 보안, 백업, 다중 지역 및 다중 클라우드 지원.
  • 요금:
    • 프리 티어: 무료.
    • Shared Clusters: 월 $9부터.
    • Dedicated Clusters: 월 $57부터.
    • Serverless: 사용량에 따라 요금 부과.

더 자세한 정보는 MongoDB 가격 페이지에서 확인할 수 있습니다​

Mongoose 소개

Mongoose는 MongoDB와의 상호작용을 쉽게 해주는 ODM 라이브러리입니다.

스키마 정의, 유효성 검사, 데이터 변환 등의 기능을 제공하여 MongoDB와의 연동을 간편하게 합니다.

Node.js에서 MongoDB 연동

MongoDB 설치

MongoDB 다운로드 페이지에서 운영체제에 맞는 MongoDB 버전을 다운로드합니다.다

운로드한 파일을 실행하여 설치합니다.

1. Node.js 프로젝트 설정 및 Mongoose 설치

Node.js 프로젝트 초기화

Node.js 프로젝트를 초기화하려면 다음 명령어를 실행합니다:

$ mkdir 06_database_mongo
$ cd 06_database_mongo
$ npm init -y
필요한 패키지 설치

Typescript, Mongoose 등 필요 패키지를 다음 명령어를 통해 설치합니다.

$ npm install typescript ts-node @types/node mongoose @types/mongoose
$ npm install typescript ts-node ts-node-dev @types/node @types/express --save-dev
$ tsc --init

2. MongoDB 연결 설정

MongoDB와 연결하기 위해 mongoose.connect 메서드를 사용합니다.

다음은 기본적인 연결 설정 예제입니다:

import mongoose from "mongoose";

const connectDB = async () => {
  try {
    await mongoose.connect("mongodb://localhost:27017/devitworld_database");
    console.log("MongoDB connected");
  } catch (err) {
    console.error("Connection error", err);
    process.exit(1);
  }
};

connectDB();

Mongoose 스키마 및 모델 생성

User 모델 생성

src/models 폴더를 만들고, 그 안에 User.ts 파일을 생성합니다.

다음과 같이 User 스키마와 모델을 정의합니다:

import { Schema, model, Document } from 'mongoose';

interface IUser extends Document {
  name: string;
  age: number;
  email: string;
}

const userSchema = new Schema<IUser>({
  name: { type: String, required: true },
  age: { type: Number, required: true },
  email: { type: String, required: true, unique: true }
});

const User = model<IUser>('User', userSchema);

export default User;

CROUD 구현

Create

src/app.ts 파일에 다음 코드를 다음과 같이 수정하여 새로운 사용자를 생성합니다:

(앞선 Connection 코드에 추가합니다.)

import User from './models/User';

// MongoDB 연결 설정 코드 위에 추가
const createUser = async () => {
  const newUser = new User({
    name: 'John Doe',
    age: 30,
    email: 'john.doe@example.com'
  });

  try {
    const user = await newUser.save();
    console.log('User created:', user);
    return user._id;
  } catch (err) {
    console.error('Creation error', err);
    return null;
  }
};

// MongoDB 연결 설정 코드 아래에 추가
connectDB().then(async () => {
  const userId = await createUser();

  console.log("userId:", userId, typeof userId);

  if (userId) {
    // CRUD 작업 호출
    await getUsers();
    await updateUser(userId.toString());
    await deleteUser(userId.toString());
  }
});
Read
const getUsers = async () => {
  try {
    const users = await User.find();
    console.log('Users:', users);
  } catch (err) {
    console.error('Read error', err);
  }
};
Update
const updateUser = async (userId: string) => {
  try {
    const user = await User.findByIdAndUpdate(userId, { age: 31 }, { new: true });
    console.log('User updated:', user);
  } catch (err) {
    console.error('Update error', err);
  }
};
Delete
const deleteUser = async (userId: string) => {
  try {
    const user = await User.findByIdAndDelete(userId);
    console.log('User deleted:', user);
  } catch (err) {
    console.error('Delete error', err);
  }
};

총 예제는 다음 참고 링크의 저장소를 참조해주세요.

참고 링크

Leave a Comment