DB와 SQL 정의 및 Node.js 사용 예시

윤뿔소·2024년 8월 5일
0

CS 지식 / 다양한 팁

목록 보기
18/20

DB는 파일 시스템과 더불어 데이터를 저장하는 도구 중 가장 유용한 도구입니다. 데이터를 탐색, 조작, 관리하는데 탁월합니다. 이와 더불어 SQL 언어까지 사용해 조작할 수도 있습니다.

이 글에서는 이 DB와 SQL을 정의하고, Node.JS를 통해 DB에 접근하는 예시도 보여주겠습니다.

DB란?

체계적으로 구조화된 정보 또는 조직화된 데이터의 집합체.
데이터를 효율적으로 관리하고 검색이 가능함.

보통 DB를 조작할때는 DBMS(데이터베이스 관리 시스템)이라는 소프트웨어로 관리합니다.
대표적인 DBMS로는 MySQL, PostgreSQL, Oracle, SQL Server 등이 있습니다. 참고로 저는 DBMS를 모아놓은 DBeaver를 좋아합니다.

SQL이란?

관계형 DB를 관리하기 위한 표준 언어.
SQL을 사용해 DB에 데이터를 삽입, 조회, 수정, 삭제 가능.

주요 SQL 명령어

CREATE

CREATE 명령어는 새로운 테이블이나 데이터베이스 객체를 생성하는 데 사용됩니다.

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(50) NOT NULL,
  email VARCHAR(100)
);

READ (SELECT)

SELECT 명령어는 데이터베이스에서 데이터를 조회하는 데 사용됩니다.

SELECT * FROM users;
SELECT username, email FROM users WHERE id = 1;

INSERT

INSERT 명령어는 데이터베이스에 새로운 데이터를 삽입하는 데 사용됩니다.

INSERT INTO users (username, password, email) VALUES ('newuser', 'password', 'newuser@example.com');

UPDATE

UPDATE 명령어는 데이터베이스의 데이터를 수정하는 데 사용됩니다.

UPDATE users SET email = 'newemail@example.com' WHERE id = 1;

DELETE

DELETE 명령어는 데이터베이스에서 데이터를 삭제하는 데 사용됩니다.

DELETE FROM users WHERE id = 1;

DROP

DROP 명령어는 테이블이나 데이터베이스 객체를 삭제하는 데 사용됩니다.

DROP TABLE users;

SQL은 트랜잭션과 단짝

트랜잭션(Transaction)은 데이터베이스 관리 시스템(DBMS)에서 하나의 작업 처리를 의미하는 논리적 작업 단위.
트랜잭션은 여러 개의 SQL 명령어를 하나의 작업으로 묶어, 모두 성공하거나 모두 실패하도록 보장.

ACID 속성을 가지게 만들고, 이 기능을 사용해 데이터의 일관성과 무결성을 유지합니다.

트랜잭션의 ACID 속성

  • 원자성(Atomicity): 트랜잭션의 모든 연산이 완전히 수행되거나 전혀 수행되지 않아야 함.
  • 일관성(Consistency): 트랜잭션이 성공적으로 완료되면 일관된 데이터베이스 상태가 되어야 함.
  • 고립성(Isolation): 하나의 트랜잭션이 완료되기 전까지 다른 트랜잭션은 그 결과를 참조 불가능.(순차)
  • 지속성(Durability): 트랜잭션이 성공적으로 완료되면 그 결과는 영구적으로 반영.

트랜잭션 사용 예시

참고로 START TRANSACTION은 트랜잭션이 시작하는 명령어를 뜻합니다.

트랜잭션 COMMIT

START TRANSACTION;

INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

COMMIT;

COMMIT 명령어는 트랜잭션 내의 모든 결과를 DB에 영구적으로 반영합니다.
트랜잭션이 성공적으로 완료되면 DB는 일관된 상태를 유지합니다.

트랜잭션 ROLBACK

만약 오류가 발생하면, 롤백하여 모든 변경을 취소할 수 있습니다.

START TRANSACTION;

INSERT INTO accounts (user_id, balance) VALUES (1, 1000);
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;

-- 오류 발생 시 롤백
ROLLBACK;

ROLLBACK 명령어는 트랜잭션 내의 모든 연산을 취소하고, DB를 트랜잭션 시작 이전 상태로 되돌립니다.
오류가 발생하거나 트랜잭션이 실패하면 유용하게 쓰입니다.

트랜잭션 상태

위의 트랜잭션이 실행되면서 아래 상태를 갖습니다.

  • 활동 상태 (Active): 트랜잭션이 시작돼 실행 중 상태.
  • 부분 완료 상태 (Partially Committed): 트랜잭션이 마지막 연산을 실행했지만, COMMIT 연산이 실행되기 전 상태.
  • 완료 상태 (Committed): 트랜잭션이 성공적으로 완료돼(COMMIT) 모든 변경이 영구적으로 저장된 상태입니다.
  • 실패 상태 (Failed): 트랜잭션이 오류로 인해 더 이상 실행 불가능 상태.
  • 철회 상태 (Aborted): 트랜잭션이 실패해 ROLLBACK 연산을 통해 모든 변경이 취소된 상태.

Node.js를 사용한 DB 접근

Node.js는 서버 사이드 애플리케이션을 개발하기 위한 자바스크립트 런타임입니다.
Node.js를 사용하여 DB에 접근하고, Node.js 라이브러리를 통해 DB와 통신할 수 있습니다.
MySQL DB를 Node.js express에서 사용해 RESTful API를 구현하는 예시를 보여주겠습니다.

1) Node.js 라이브러리 설치

npm init -y
npm install express mysql

DB 연동 및 돌아가는 서버를 만들기 위해 expressmysqlnpm으로 설치합니다.

2) 데이터베이스 연결

const mysql = require('mysql');
const express = require('express');
const app = express();

app.use(express.json());

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'testdb',
});

connection.connect((err) => {
  if (err) {
    console.error('Error connecting to the database:', err);
    return;
  }
  console.log('Connected to the database.');
});
  • mysql 모듈, express 모듈을 로드.
  • express 애플리케이션을 생성.
    • JSON 요청 본문을 파싱하는 미들웨어 추가.
  • DB 연결 설정.
    • DB 연결에 성공하면 성공 메시지 출력.
    • 실패하면 오류 메시지 출력.

3) 사용자 정보 조회 (GET)

app.get('/users', (req, res) => {
  connection.query('SELECT * FROM users', (err, results) => {
    if (err) {
      return res.status(500).send(err);
    }
    res.json(results);
  });
});

app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  connection.query('SELECT * FROM users WHERE id = ?', [userId], (err, results) => {
    if (err) {
      return res.status(500).send(err);
    }
    res.json(results[0]);
  });
});
  • 모든 사용자 정보를 조회하는 엔드포인트 /users 설정.
  • 특정 사용자 정보를 조회하는 엔드포인트 /users/:id 설정.
  • DB에서 조회된 결과를 JSON 형식으로 응답.

4) 사용자 정보 추가 (POST)

app.post('/users', (req, res) => {
  const newUser = req.body;
  connection.query('INSERT INTO users SET ?', newUser, (err, results) => {
    if (err) {
      return res.status(500).send(err);
    }
    res.status(201).json({ id: results.insertId, ...newUser });
  });
});
  • 새로운 사용자 정보를 추가하는 엔드포인트 /users 설정.
  • 요청 본문에서 새로운 사용자 정보를 추출하고 DB에 삽입.
  • 성공적으로 추가된 사용자 정보를 JSON 형식 응답.

5) 사용자 정보 수정 (PUT)

app.put('/users/:id', (req, res) => {
  const userId = req.params.id;
  const updatedUser = req.body;
  connection.query('UPDATE users SET ? WHERE id = ?', [updatedUser, userId], (err, results) => {
    if (err) {
      return res.status(500).send(err);
    }
    res.json({ id: userId, ...updatedUser });
  });
});
  • 기존 사용자 정보를 수정하는 엔드포인트 /users/:id 설정.
  • 요청 본문에서 수정된 사용자 정보를 추출하고 데이터베이스에서 해당 사용자 정보 업데이트.
  • 성공적으로 수정된 사용자 정보를 JSON 형식 응답.

6) 사용자 정보 삭제 (DELETE)

app.delete('/users/:id', (req, res) => {
  const userId = req.params.id;
  connection.query('DELETE FROM users WHERE id = ?', [userId], (err, results) => {
    if (err) {
      return res.status(500).send(err);
    }
    res.status(204).send();
  });
});
  • 기존 사용자 정보를 삭제하는 엔드포인트 /users/:id 설정.
  • URL에서 사용자 ID를 추출하고 DB에서 해당 사용자 정보 삭제.
  • 성공적으로 삭제된 경우 204 상태 코드 응답.

서버 실행

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
  • 서버를 3000번 포트에서 실행하고 서버 시작 메시지 출력.

참고로 위 API 서버는 RESTful API에 맞게 했습니다.

추가 : RESTful API란?

RESTful API는 Representational State Transfer (REST) 아키텍처 스타일을 따르는 애플리케이션 프로그래밍 인터페이스입니다. RESTful API는 HTTP를 사용하여 클라이언트와 서버 간의 통신을 수행하며, 주로 CRUD(Create, Read, Update, Delete) 작업을 위한 엔드포인트를 제공합니다.

RESTful API의 주요 특징

  • 무상태성: 각 요청은 독립적이며, 요청 간에 서버는 클라이언트의 상태를 저장하지 않습니다.
  • 클라이언트-서버 구조: 클라이언트와 서버는 독립적으로 동작하며, 클라이언트는 사용자 인터페이스를 담당하고 서버는 데이터 저장 및 비즈니스 로직을 처리합니다.
  • 일관된 인터페이스: RESTful API는 리소스를 URI로 식별하며, 표준 HTTP 메서드(GET, POST, PUT, DELETE)를 사용하여 리소스를 조작합니다.
  • 캐시 가능: HTTP 응답은 캐시할 수 있으므로, 서버의 부하를 줄이고 클라이언트의 성능을 향상시킬 수 있습니다.

참고

profile
코뿔소처럼 저돌적으로

0개의 댓글