Backend
프론트엔드 개발자를 위한 데이터베이스 기초
풀스택 개발을 위한 데이터베이스 기본 지식. SQL과 NoSQL의 차이, 기본 쿼리 작성법을 알아봅니다.
프론트엔드 개발자도 데이터베이스 기초를 알면 백엔드와 소통이 수월해지고, 풀스택 개발도 가능해집니다.
SQL vs NoSQL
SQL (관계형 데이터베이스)
데이터를 테이블 형태로 저장합니다. MySQL, PostgreSQL, SQLite 등이 있습니다.
-- 테이블 생성
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE posts (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
content TEXT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
장점은 데이터 무결성이 보장되고, 복잡한 조인 쿼리가 가능합니다. 단점은 스키마 변경이 어렵고, 수평 확장이 복잡합니다.
NoSQL (비관계형 데이터베이스)
유연한 스키마로 데이터를 저장합니다. MongoDB, Redis, DynamoDB 등이 있습니다.
// MongoDB 문서 예시
{
_id: ObjectId("..."),
name: "홍길동",
email: "hong@email.com",
posts: [
{ title: "첫 번째 글", content: "..." },
{ title: "두 번째 글", content: "..." }
],
createdAt: ISODate("2026-01-01")
}
장점은 스키마가 유연하고, 수평 확장이 쉽습니다. 단점은 조인이 어렵고, 트랜잭션 지원이 제한적입니다.
기본 SQL 쿼리
SELECT (조회)
-- 전체 조회
SELECT * FROM users;
-- 특정 컬럼만
SELECT name, email FROM users;
-- 조건 조회
SELECT * FROM users WHERE age > 20;
-- 정렬
SELECT * FROM users ORDER BY created_at DESC;
-- 제한
SELECT * FROM users LIMIT 10 OFFSET 20;
-- 중복 제거
SELECT DISTINCT category FROM products;
INSERT (삽입)
INSERT INTO users (name, email) VALUES ('홍길동', 'hong@email.com');
-- 여러 행
INSERT INTO users (name, email) VALUES
('홍길동', 'hong@email.com'),
('김영희', 'kim@email.com');
UPDATE (수정)
UPDATE users SET name = '홍길순' WHERE id = 1;
-- 여러 컬럼
UPDATE users SET name = '홍길순', email = 'new@email.com' WHERE id = 1;
DELETE (삭제)
DELETE FROM users WHERE id = 1;
-- 주의: WHERE 없으면 전체 삭제
DELETE FROM users; -- 위험!
JOIN (테이블 연결)
-- 사용자와 게시물 함께 조회
SELECT users.name, posts.title
FROM users
INNER JOIN posts ON users.id = posts.user_id;
-- LEFT JOIN: 게시물 없는 사용자도 포함
SELECT users.name, posts.title
FROM users
LEFT JOIN posts ON users.id = posts.user_id;
집계 함수
-- 개수
SELECT COUNT(*) FROM users;
-- 합계, 평균, 최대, 최소
SELECT SUM(price), AVG(price), MAX(price), MIN(price) FROM products;
-- 그룹화
SELECT category, COUNT(*) as count
FROM products
GROUP BY category
HAVING count > 5;
ORM 사용하기
SQL을 직접 작성하는 대신 ORM(Object-Relational Mapping)을 사용하면 JavaScript 코드로 데이터베이스를 다룰 수 있습니다.
Prisma 예시
// 스키마 정의 (schema.prisma)
model User {
id Int @id @default(autoincrement())
name String
email String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
author User @relation(fields: [authorId], references: [id])
authorId Int
}
// 쿼리
const users = await prisma.user.findMany();
const user = await prisma.user.findUnique({
where: { email: 'hong@email.com' }
});
const newUser = await prisma.user.create({
data: { name: '홍길동', email: 'hong@email.com' }
});
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true }
});
인덱스
자주 조회하는 컬럼에 인덱스를 추가하면 성능이 향상됩니다.
-- 인덱스 생성
CREATE INDEX idx_users_email ON users(email);
-- 복합 인덱스
CREATE INDEX idx_posts_user_date ON posts(user_id, created_at);
인덱스는 조회를 빠르게 하지만, 삽입/수정이 느려집니다. 적절히 사용해야 합니다.
트랜잭션
여러 쿼리를 하나의 작업 단위로 묶습니다. 전부 성공하거나 전부 실패합니다.
// Prisma 트랜잭션
await prisma.$transaction([
prisma.account.update({
where: { id: 1 },
data: { balance: { decrement: 100 } }
}),
prisma.account.update({
where: { id: 2 },
data: { balance: { increment: 100 } }
})
]);
마무리
프론트엔드 개발자라도 기본적인 데이터베이스 지식은 알아두면 좋습니다. 특히 Next.js 같은 풀스택 프레임워크를 사용한다면 데이터베이스를 직접 다루게 됩니다.
Prisma 같은 ORM을 사용하면 SQL을 깊이 몰라도 데이터베이스를 다룰 수 있지만, 기본 개념은 이해하고 있어야 합니다.