
바야흐로 1년전... 부트캠프 끝나고 뭐하지 고민하던 때에... 쿠팡에 계약직 알바가 떴었는데 그게 데이터 크롤링 및 적재 업무였다. 그래서 오!! 완전하고싶다!!! 는 생각에 지원했었다. 근데 그 때 당시 나는 데이터베이스가 그냥 데이터가 있는 베이스?? 대충 데이터가 있으면 그게 데이터베이스지~~ 라고 생각했었다 ㅋㅋ 그래서 자신감있게 이력서에 데이터베이스를 통해 데이터를 어쩌구저쩌구~~ 라고 적었었고 실제로 면접에서 물어봤었다.
누가봐도 개발자이신 면접관님 : 데이터 베이스 쓰셨다고 했는데.. 어떻게 데이터 가져오셨어요?
감자 : 아 넵! 크롤링을 통해서 데이터를 가져와 판다스를 통해서~...
면접관님 : 아니 어디서 가져오셨냐구여
감자 : 네이버요...
답답한 면접관님 : 아니 그 데이터의 원천소스 즉 어떤 데이터냐구여 혹시 csv에요?
감자 : 앗 넵!! 맞습니다!!
웃긴 면접관님 : 하하... csv가 데이터베이스... ㅎㅎㅎ 넵 알겠습니다~~
큰일남을 감지한 감자 : (망해따 히힛 ^_^)
이런 사건이 있었습죠...(완전 짤이랑 똑같은 상황 ㅋ) 그러고 나서 작년 9월에 백엔드 파트를 맡으면서 mysql를 통해서 데이터베이스에 적재하고 조회하고 하는 작업을 하면서 이때 해탈하신 면접관님의 심정이 이해가 갔다...
무려 6개월만에 알게되다!!!!
하지만 데이터베이스에 대해서 아직도 엄청 자세히 아는 것은 아니라 생각이 들어... 개념을 정리하고자 이렇게 글을 써본다.
(다시는 실수 안하리)
데이터베이스(Database)란?
구조화된 데이터를 저장, 관리, 조작하기 위한 체계화된 집합니다.
일반적으로 데이터 베이스는 컴퓨터 시스템 내에서 사용되며 데이터베이스 관리 시스템(Database Management System, DBMS)에 의해 관리된다.

그림 출처
일반적으로 데이터베이스는 테이블이라는 행과 열로 구성된 구조를 사용하고 데이터를 저장한다. 이러한 테이블은 관련된 데이터를 구조화하고 관계형 데이터베이스 시스템에서는 관계(Relationship)을 통해 여러 테이블 간에 데이터를 연결할 수 있다.
데이터베이스의 다양한 종류가 있는데 주요 유형은 아래와 같다.
- 관계형 데이터베이스(Relational Database): 데이터를 테이블 형식으로 저장하고 관리하는 데이터베이스이다. 관계형 데이터베이스 시스템은 SQL(Structured Query Language)을 사용하여 데이터를 조작한다. 예시로는 Oracle, MySQL, PostgreSQL 등이 있다.
- NoSQL 데이터베이스(Not Only SQL): 관계형 데이터베이스와는 다른 모델을 사용하여 데이터를 저장하고 관리하는 데이터베이스이다. NoSQL 데이터베이스는 스키마가 유연하며, 대량의 분산 데이터를 처리할 수 있다. 예시로는 MongoDB, Cassandra, Redis 등이 있다.
- 객체지향 데이터베이스(Object-Oriented Database): 객체 지향 프로그래밍의 개념을 기반으로 데이터를 저장하고 관리하는 데이터베이스이다. 객체 지향 데이터베이스는 객체를 직접 저장하고 객체 간의 관계를 공유한다.
- 그래프 데이터베이스(Graph Database): 그래프 모델을 사용하여 데이터를 저장하고 관리하는 데이터베이스이다. 그래프 데이터베이스는 노드와 엣지를 사용하여 데이터를 표현하고, 복잡한 관계를 쉽게 표현할 수 있다.
그래서 일반적인 수준에서 사용되는 SQL과 NoSQL에 대해서 알아보자.
SQL(SQL, Structured Query Language)과 NoSQL(Not Only SQL)은 데이터베이스 시스템의 종류를 나타낸다. 이들은 데이터를 저장, 검색, 조작하는 방법과 데이터 모델링에 차이가 있다.

그림 출처
관계형 데이터베이스 시스템(RDBMS): SQL은 주로 관계형 데이터베이스 시스템에서 사용된다. 이러한 데이터베이스는 데이터를 테이블 형식으로 구성하고, 테이블 간의 관계를 정의한다.
정형 데이터 저장: SQL 데이터베이스는 정형 데이터를 저장한다. 데이터는 행과 열의 형태로 구성된 테이블에 저장된다. 테이블은 미리 정의된 스키마를 가지고 있으며, 각 열은 특정 데이터 유형에 해당한다.
SQL 쿼리 사용: 데이터를 검색, 조작, 수정하는 데에는 SQL 쿼리가 사용된다. SQL은 데이터베이스 관리 시스템(DBMS)에게 명령을 내리는 표준화된 언어이다.
ACID 트랜잭션: SQL 데이터베이스는 ACID(원자성, 일관성, 고립성, 지속성) 트랜잭션을 지원하여 데이터 일관성을 보장한다.

스냅샷기능도 있는데 데이터의 특정 시점의 상태를 캡처하고 저장하는 기술이다. 일종의 백업느낌?? 그래서 aws의 rds 서비스를 이용하고 프로젝트가 끝났을 때 자꾸 과금이 돼서 어디서 나오는건가... 했더니 스냅샷 db가 남아있어서 그랬었었다... 이처럼 스냅샷의 라이프사이클도 관리해주어야된다.
근데 SQL에 이미지를 저장하려면 어떻게 해야될까? 주로 두가지 방식이 있다. 디스크방식과 데이터베이스 내장 방식이다.
1. 디스크 방식:
import mysql.connector
# MySQL 연결 설정
connection = mysql.connector.connect(
host="localhost",
user="username",
password="password",
database="mydatabase"
)
# 이미지를 파일 시스템에 저장
file_path = "/path/to/image.jpg"
# 데이터베이스에 파일 경로 저장
cursor = connection.cursor()
sql = "INSERT INTO images (image_path) VALUES (%s)"
val = (file_path,)
cursor.execute(sql, val)
connection.commit()
2. 데이터베이스 내장 방식:
import mysql.connector
# MySQL 연결 설정
connection = mysql.connector.connect(
host="localhost",
user="username",
password="password",
database="mydatabase"
)
# 이미지 파일을 읽어와서 이진 데이터로 변환
with open("/path/to/image.jpg", "rb") as file:
image_binary = file.read()
# 데이터베이스에 이진 데이터 저장
cursor = connection.cursor()
sql = "INSERT INTO images (image_data) VALUES (%s)"
val = (image_binary,)
cursor.execute(sql, val)
connection.commit()
비관계형 데이터베이스 시스템: NoSQL은 관계형 데이터베이스가 아닌 다양한 형태의 데이터를 저장하는 데이터베이스 시스템이다. NoSQL 데이터베이스는 다양한 데이터 모델을 지원하며, 스키마가 자유롭거나 유연하다.
다양한 데이터 모델: NoSQL 데이터베이스는 다양한 데이터 모델을 지원한다. 키-값 스토어, 문서형 데이터베이스, 열 지향 데이터베이스, 그래프 데이터베이스 등의 다양한 형태의 데이터 모델을 활용할 수 있다.
비정형 데이터 저장: NoSQL 데이터베이스는 정형 데이터뿐만 아니라 반정형 또는 비정형 데이터를 저장하는 데 적합하다. 이러한 데이터는 JSON, XML, BSON 등의 형식으로 저장될 수 있다.
분산 시스템: NoSQL 데이터베이스는 대규모의 데이터를 처리하기 위한 분산 시스템을 기반으로 작동한다. 이는 확장성과 가용성을 향상시키며, 대규모의 데이터를 처리할 수 있도록 한다.
NoSQL 데이터베이스에서 이미지를 저장하는 방법은 일반적으로 이미지 파일 자체를 저장하는 것이 아니라 이미지의 메타데이터를 포함한 파일 경로 또는 이미지 데이터를 저장하는 방식이 주로 사용된다.
MongoDB는 NoSQL 데이터베이스의 한 종류로, 이미지를 저장하기 위해 GridFS라는 기능을 제공한다. 이를 사용하면 이미지 파일을 작은 청크(chunk)로 나누어 MongoDB 컬렉션에 저장할 수 있다. 이렇게 하면 대용량의 이미지 파일도 효율적으로 관리할 수 있다.
const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const fs = require('fs');
// MongoDB 연결 설정
mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });
const conn = mongoose.connection;
// GridFS 스트림 연결
let gfs;
conn.once('open', () => {
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection('images'); // 이미지를 저장할 컬렉션 이름
});
// 이미지 저장 함수
const saveImage = (filePath, fileName) => {
const writestream = gfs.createWriteStream({ filename: fileName });
fs.createReadStream(filePath).pipe(writestream);
};
// 이미지 조회 함수
const getImage = (fileName) => {
gfs.files.find({ filename: fileName }).toArray((err, files) => {
if (!files || files.length === 0) {
return console.log('File not found');
}
const readstream = gfs.createReadStream({ filename: fileName });
readstream.pipe(fs.createWriteStream(`./downloaded_images/${fileName}`));
});
};
// 이미지 저장 예시
saveImage('./sample_image.jpg', 'sample_image.jpg');
// 이미지 조회 예시
getImage('sample_image.jpg');
Couchbase는 NoSQL 데이터베이스로, 이미지를 저장할 때는 일반적으로 Base64 인코딩된 이미지 데이터를 JSON 문서에 포함하여 저장하는 방식이 많이 사용된다.
const couchbase = require('couchbase');
// Couchbase 클러스터 연결 설정
const cluster = new couchbase.Cluster('couchbase://localhost');
const bucket = cluster.openBucket('mybucket', 'mypassword');
// 이미지 저장 함수
const saveImage = (imageName, imageData) => {
bucket.insert(`image::${imageName}`, { image: imageData }, (err, result) => {
if (err) {
console.error(err);
} else {
console.log('Image saved successfully');
}
});
};
// 이미지 조회 함수
const getImage = (imageName) => {
bucket.get(`image::${imageName}`, (err, result) => {
if (err) {
console.error(err);
} else {
const imageData = result.value.image;
// 이미지 처리 또는 다운로드 등의 작업 수행
}
});
};
// 이미지 저장 예시
const sampleImage = 'Base64 encoded image data';
saveImage('sample_image.jpg', sampleImage);
// 이미지 조회 예시
getImage('sample_image.jpg');
오라클 (Oracle)
MySQL
마리아DB (MariaDB)
PostgreSQL
몽고DB (MongoDB)
Redis