데이터베이스 이해하기1(ft.이론편)

shooting star·2024년 5월 8일
0
post-thumbnail

들어가며

현대 애플리케이션에서 데이터베이스는 핵심적인 역할을 합니다. 이번 블로그에서는 데이터베이스란 무엇이며, Node.js와 MongoDB를 활용해 데이터베이스를 다루는 방법을 소개하겠습니다.

데이터베이스란?

데이터베이스는 여러 사람이 공유하여 사용할 목적으로 통합 및 관리되는 데이터의 집합입니다. 여러 응용 시스템들의 통합된 정보들을 저장하여 운영할 수 있는 공용 데이터들의 묶음입니다.

데이터베이스의 장점

  1. 데이터 중복 최소화
  2. 데이터 공유
  3. 일관성, 무결성, 보안성 유지
  4. 최신의 데이터 유지
  5. 데이터 표준화 가능
  6. 데이터 논리적, 물리적 독립성
  7. 용이한 데이터 접근
  8. 데이터 저장 공간 절약

데이터베이스의 단점

  1. 전문가 필요
  2. 많은 비용 부담
  3. 백업과 복구 어려움
  4. 시스템 복잡성
  5. 대용량 데이터 액세스 시 과부하 발생

데이터베이스의 필요성

앱을 만들 때 POST 요청을 통해 서버에 데이터를 추가할 수 있습니다. 하지만 서버를 다시 시작하면 생성된 데이터가 사라집니다. 데이터베이스는 이러한 문제를 해결하기 위해 사용됩니다. 영구적으로 데이터를 저장하여 클라이언트가 필요할 때 언제든지 접근할 수 있도록 합니다.

데이터베이스 관리 시스템(DBMS)

데이터베이스는 데이터의 집합이고, DBMS는 이를 관리하고 운영하는 소프트웨어입니다. DBMS를 이용해 데이터를 저장하고 검색하는 기능을 제공합니다.

DBMS 종류

  • 계층형
  • 네트워크형
  • 관계형 (RDBMS) : Oracle, MySQL, PostgreSQL
  • 객체형

현재 주로 사용되는 DBMS는 관계형 데이터베이스(RDBMS)입니다.

RDBMS 특징

RDBMS는 데이터를 테이블로 저장합니다. 테이블은 관련 데이터 항목의 모음이며, 행과 열로 구성됩니다.

  • 테이블: 관계(relation)
  • 행: 레코드(record) 또는 튜플(tuple)
  • 열: 필드(field) 또는 속성(attribute)

예시: User 테이블

IDNameAgeEmail
1John22john@abc.com
2Han23han@abc.com
3Don24don@abc.com

기본 키와 외부 키

  • 기본 키 (Primary Key): 테이블의 각 행을 고유하게 식별하는 키
  • 외부 키 (Foreign Key): 다른 테이블의 행을 식별할 수 있는 키

SQL vs NoSQL

SQL 데이터베이스

  • 정적 스키마: 사전에 테이블 구조 정의
  • 관계형 모델: 테이블 간 관계 정의
  • ACID: 일관성, 격리성 등 보장
  • 예시: MySQL, PostgreSQL, SQLite

NoSQL 데이터베이스

  • 동적 스키마: 사전에 구조 정의 불필요
  • 다양한 데이터 모델: 문서형, 키-값 등
  • BASE: 가용성 우선, 일관성 보장
  • 예시: MongoDB, Redis, Amazon DynamoDB

MongoDB 소개

MongoDB는 문서 지향 NoSQL 데이터베이스로, JSON과 유사한 문서 구조를 사용하여 데이터를 저장합니다.

MongoDB의 특징

  • 동적 스키마: 데이터 구조 사전 정의 불필요
  • 수평 확장: 분산 저장 및 확장 가능
  • BSON: 바이너리 JSON으로 효율적인 저장

MongoDB와 Mongoose

Mongoose는 Node.js에서 MongoDB를 더 쉽게 사용하기 위해 제공되는 ODM(Object Data Modeling) 라이브러리입니다. Mongoose를 이용해 데이터를 관리하려면 먼저 스키마를 정의하고, 이를 바탕으로 모델을 생성합니다.

  1. 스키마: 문서 구조 및 유효성 검사 정의
  2. 모델: 스키마를 이용해 데이터베이스와 상호작용

스키마 예시

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    age: { type: Number, required: true },
    email: { type: String, required: true }
});

const User = mongoose.model('User', userSchema);

Node.js와 MongoDB 연동하기

MongoDB 연결

  1. MongoDB Atlas에서 클러스터 생성
  2. MongoDB 유저 생성
  3. Mongoose 설치 및 MongoDB 연결
npm install mongoose
const mongoose = require('mongoose');

const MONGO_URL = 'your_mongo_db_connection_string';
mongoose.connect(MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
    .then(() => console.log('MongoDB connected'))
    .catch(err => console.error('MongoDB connection error:', err));

CRUD 기능 구현

1. Create

const createUser = async (name, age, email) => {
    const user = new User({ name, age, email });
    await user.save();
    console.log('User created:', user);
};

2. Read

const getUsers = async () => {
    const users = await User.find();
    console.log('All users:', users);
};

3. Update

const updateUser = async (id, newData) => {
    const user = await User.findByIdAndUpdate(id, newData, { new: true });
    console.log('User updated:', user);
};

4. Delete

const deleteUser = async (id) => {
    const user = await User.findByIdAndDelete(id);
    console.log('User deleted:', user);
};

Express와 함께 활용하기

Express 프레임워크와 함께 MongoDB를 사용해 API를 구축할 수 있습니다.

Express 서버 생성

npm install express
const express = require('express');
const app = express();
app.use(express.json());

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

MongoDB 모델 정의

const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    age: { type: Number, required: true },
    email: { type: String, required: true }
});

const User = mongoose.model('User', userSchema);

RESTful API 라우팅

1. POST /users (Create)

app.post('/users', async (req, res) => {
    try {
        const user = new User(req.body);
        await user.save();
        res.status(201).json(user);
    } catch (err) {
        res.status(400).json({ error: err.message });
    }
});

2. GET /users (Read)

app.get('/users', async (req, res) => {
    try {
        const users = await User.find();
        res.status(200).json(users);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

3. PUT /users/:id (Update)

app.put('/users/:id', async (req, res) => {
    try {
        const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
        if (!user) return res.status(404).json({ error: 'User not found' });
        res.status(200).json(user);
    } catch (err) {
        res.status(400).json({ error: err.message });
    }
});

4. DELETE /users/:id (Delete)

app.delete('/users/:id', async (req, res) => {
    try {
        const user = await User.findByIdAndDelete(req.params.id);
        if (!user) return res.status(404).json({ error: 'User not found' });
        res.status(200).json(user);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

전체 코드

const express = require('express');
const mongoose = require('mongoose');

const app = express();
app.use(express.json());

const MONGO_URL = 'your_mongo_db_connection_string';
mongoose.connect(MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
    .then

(() => console.log('MongoDB connected'))
    .catch(err => console.error('MongoDB connection error:', err));

const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    age: { type: Number, required: true },
    email: { type: String, required: true }
});

const User = mongoose.model('User', userSchema);

app.post('/users', async (req, res) => {
    try {
        const user = new User(req.body);
        await user.save();
        res.status(201).json(user);
    } catch (err) {
        res.status(400).json({ error: err.message });
    }
});

app.get('/users', async (req, res) => {
    try {
        const users = await User.find();
        res.status(200).json(users);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

app.put('/users/:id', async (req, res) => {
    try {
        const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
        if (!user) return res.status(404).json({ error: 'User not found' });
        res.status(200).json(user);
    } catch (err) {
        res.status(400).json({ error: err.message });
    }
});

app.delete('/users/:id', async (req, res) => {
    try {
        const user = await User.findByIdAndDelete(req.params.id);
        if (!user) return res.status(404).json({ error: 'User not found' });
        res.status(200).json(user);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});

마치며

이번 글에서는 데이터베이스의 필요성과 MongoDB를 이용해 Node.js에서 CRUD 기능을 구현하는 방법을 알아보았습니다. 사실 저는 MySQL과 PostgreSQL을 많이 사용하고 있습니다.

참고 자료

0개의 댓글