Fullstack 48

heo4·2026년 6월 23일

Fullstack

목록 보기
3/70

풀스택

☁️ Cloudflare vs AWS — 무엇이 다를까?

📌 한 줄 요약

CloudflareAWS
정체네트워크 / 보안 플랫폼클라우드 인프라 플랫폼
핵심 역할트래픽 최적화 + 보안서버 / DB / 스토리지 등 인프라 제공
비유건물 앞 경비원 + 도로건물 자체

🔍 개념부터 다르다

Cloudflare

  • 전 세계 300개 이상의 데이터센터를 통해 CDN(콘텐츠 전송 네트워크) 제공
  • 사용자와 서버 사이에 위치해서 트래픽을 중계
  • DDoS 차단, SSL 인증서, DNS 관리, 캐싱이 주력
  • 서버를 직접 소유하지 않아도 쓸 수 있음

AWS (Amazon Web Services)

  • EC2(가상 서버), RDS(데이터베이스), S3(스토리지) 등 직접 인프라를 빌려주는 서비스
  • 서버를 내가 직접 운영하는 개념
  • 컴퓨팅 파워, 네트워크, 스토리지를 종합적으로 제공
  • 전 세계 30개 이상의 리전(Region)에 데이터센터 운영

⚔️ 기능 비교

기능CloudflareAWS
서버 (EC2)❌✅
데이터베이스 (RDS)❌✅
스토리지 (S3)❌✅ (S3)
CDN✅ (핵심)✅ (CloudFront)
DDoS 방어✅ (무료 포함)✅ (Shield, 유료)
DNS 관리✅ (무료)✅ (Route 53, 유료)
SSL 인증서✅ (무료 자동)✅ (ACM, 무료)
서버리스 함수✅ (Workers)✅ (Lambda)
정적 사이트 배포✅ (Pages)✅ (S3 + CloudFront)
가격무료 플랜 강력종량제, 복잡함

💡 각각 언제 쓰나?

Cloudflare를 쓰는 경우

  • 도메인 DNS 관리할 때
  • 무료로 SSL 적용하고 싶을 때
  • DDoS 방어가 필요할 때
  • 정적 사이트(React, Next.js 등) 빠르게 배포할 때 → Cloudflare Pages
  • 서버리스 함수로 가볍게 처리할 때 → Cloudflare Workers

AWS를 쓰는 경우

  • 백엔드 서버(Spring Boot, Node.js 등)를 직접 운영할 때 → EC2
  • 데이터베이스가 필요할 때 → RDS
  • 파일/이미지 저장이 필요할 때 → S3
  • 대규모 인프라를 직접 구성할 때

🤝 같이 쓰면 더 강력하다

실제로 많은 서비스가 AWS + Cloudflare를 함께 사용해:

사용자
  ↓
Cloudflare (DNS + CDN + DDoS 방어 + SSL)
  ↓
AWS EC2 (Spring Boot 서버)
  ↓
AWS RDS (MariaDB)
  ↓
AWS S3 (이미지 저장)
  • Cloudflare: 앞단에서 보안과 속도 담당
  • AWS: 뒷단에서 실제 서버와 데이터 담당

💰 가격 비교

Cloudflare

  • 무료 플랜으로도 CDN, DDoS 방어, SSL, DNS 모두 사용 가능
  • Pro 플랜 $20/월부터 시작

AWS

  • 프리 티어 있지만 1년 후 과금 시작
  • 사용한 만큼 내는 종량제라 예측이 어려움
  • 소규모 서비스도 잘못 설정하면 요금 폭탄 가능성 있음

🏁 결론

Cloudflare = 네트워크 레이어 (앞단)
AWS = 인프라 레이어 (뒷단)
경쟁 관계가 아니라 상호 보완 관계!

개인 프로젝트라면:

  • 정적 사이트 → Cloudflare Pages (무료, 간편)
  • 백엔드 + DB 필요 → AWS EC2 + RDS
  • 둘 다 필요 → Cloudflare + AWS 조합

🎤 면접 대비 Q&A

Q1. Cloudflare와 AWS의 차이점을 설명해주세요.

모범 답안

Cloudflare는 네트워크 레이어 플랫폼으로, 사용자와 서버 사이에 위치해 CDN, DDoS 방어, DNS, SSL 등을 담당합니다. AWS는 클라우드 인프라 플랫폼으로 EC2, RDS, S3 등 실제 서버와 데이터베이스, 스토리지를 제공합니다. 두 서비스는 경쟁 관계가 아니라 상호 보완 관계로, 실무에서는 Cloudflare를 앞단 보안/속도 최적화에, AWS를 뒷단 인프라 운영에 함께 사용하는 경우가 많습니다.


Q2. CDN이 무엇인지, 왜 사용하는지 설명해주세요.

모범 답안

CDN(Content Delivery Network)은 전 세계 여러 곳에 분산된 서버에 콘텐츠를 캐싱해두고, 사용자와 가장 가까운 서버에서 데이터를 전달하는 기술입니다. 예를 들어 한국 사용자가 미국 서버의 이미지를 요청할 때 CDN 없이는 직접 미국 서버까지 요청이 가지만, CDN을 쓰면 한국에 캐싱된 서버에서 바로 응답하므로 응답 속도가 크게 빨라집니다. Cloudflare는 이 CDN을 무료로 제공하고, AWS는 CloudFront라는 유료 CDN 서비스를 제공합니다.


Q3. DDoS 공격이란 무엇이고 어떻게 방어하나요?

모범 답안

DDoS(Distributed Denial of Service)는 수많은 공격자가 동시에 서버에 요청을 보내 서버를 마비시키는 공격입니다. Cloudflare는 이 트래픽을 서버 앞단에서 차단해주는데, 무료 플랜에서도 기본적인 DDoS 방어가 포함됩니다. AWS는 Shield Standard를 무료로 제공하고, 고급 방어는 Shield Advanced(유료)를 사용합니다. 실무에서는 Cloudflare를 앞단에 두는 것만으로도 대부분의 DDoS 공격을 효과적으로 막을 수 있습니다.


Q4. DNS가 무엇인지 설명해주세요.

모범 답안

DNS(Domain Name System)는 사람이 읽기 쉬운 도메인 주소(예: google.com)를 컴퓨터가 이해할 수 있는 IP 주소(예: 142.250.196.110)로 변환해주는 시스템입니다. 전화번호부에 비유할 수 있습니다. Cloudflare는 무료로 DNS 서비스를 제공하며 응답 속도가 매우 빠릅니다. AWS는 Route 53이라는 DNS 서비스를 유료로 제공합니다.


Q5. 프로젝트에서 Cloudflare와 AWS를 어떻게 활용했나요? (실전 경험 답변 예시)

모범 답안 (프로젝트 기반)

스키장 정보 플랫폼(snowbs.life) 프로젝트에서 두 서비스를 함께 사용했습니다. 도메인 DNS 관리와 SSL 인증서는 Cloudflare에서 무료로 처리하고, Next.js 프론트엔드는 Cloudflare Pages에 배포했습니다. 백엔드 API 서버는 AWS EC2(Ubuntu)에 올리고, 데이터베이스는 Neon DB(PostgreSQL)를 사용했습니다. 이 구조 덕분에 프론트엔드 배포 비용은 0원으로 유지하면서 백엔드 인프라만 AWS에서 관리할 수 있었습니다.


Q6. Cloudflare Workers와 AWS Lambda의 차이는?

모범 답안

둘 다 서버 없이 함수 단위로 코드를 실행하는 서버리스 서비스입니다. 가장 큰 차이는 실행 위치입니다. Cloudflare Workers는 전 세계 CDN 엣지 서버에서 실행되어 사용자와 가장 가까운 곳에서 즉시 응답하므로 응답 속도가 매우 빠릅니다. AWS Lambda는 특정 리전의 서버에서 실행되며 콜드 스타트(처음 실행 시 지연)가 발생할 수 있습니다. 단순 API 처리나 미들웨어는 Workers가 유리하고, 복잡한 비즈니스 로직이나 다른 AWS 서비스와 연동이 필요한 경우 Lambda가 적합합니다.


Q7. SSL/TLS가 무엇인지 설명해주세요.

모범 답안

SSL/TLS는 인터넷 통신을 암호화하는 프로토콜입니다. 브라우저 주소창의 https://와 자물쇠 아이콘이 SSL이 적용됐다는 표시입니다. SSL이 없으면 사용자가 입력한 비밀번호나 개인정보가 네트워크에서 평문으로 전송돼 탈취될 수 있습니다. Cloudflare는 도메인을 연결하는 것만으로 SSL 인증서를 자동으로 무료 발급해줍니다. AWS는 ACM(Certificate Manager)을 통해 무료로 발급할 수 있지만 EC2에 직접 적용하려면 추가 설정이 필요합니다.


⭐ 면접 핵심 키워드 정리

키워드한 줄 설명
CDN가까운 서버에서 빠르게 콘텐츠 전달
DDoS대량 트래픽으로 서버 마비시키는 공격
DNS도메인 → IP 주소 변환 시스템
SSL/TLS통신 암호화 프로토콜 (https)
엣지 컴퓨팅사용자 가까운 곳에서 연산 처리
서버리스서버 관리 없이 함수 단위 실행
리전 (Region)AWS 데이터센터 지역 단위
오리진 서버CDN 뒤에 있는 실제 서버
캐싱자주 쓰는 데이터를 가까운 곳에 임시 저장
프록시클라이언트와 서버 사이 중계 역할

게시판 스키마 직접 설계하기 (실습)

학습 목표

  • 요구사항을 분석해서 필요한 테이블을 스스로 도출할 수 있다.
  • 테이블 간의 관계(1:N, N:M)를 파악하고 FK로 설계할 수 있다.
  • 지금까지 배운 데이터 타입과 제약조건을 종합적으로 적용할 수 있다.
  • 직접 작성한 SQL로 게시판 전체 스키마를 H2에 구축한다.

1. 오늘 만들 게시판의 요구사항

다음 요구사항을 만족하는 게시판을 설계합니다.

  • 회원은 이름, 이메일, 비밀번호, 가입일을 가진다. 이메일은 중복될 수 없다.
  • 게시글은 제목, 내용, 조회수, 작성일을 가지며, 반드시 작성자(회원)가 있어야 한다.
  • 게시글은 카테고리(예: 자유게시판, 공지사항, 질문)로 구분된다.
  • 댓글은 내용, 작성일을 가지며, 특정 게시글과 특정 회원에 연결된다.
  • 회원은 게시글에 좋아요를 누를 수 있다. 단, 같은 게시글에 좋아요는 한 번만 누를 수 있다.

2. 요구사항 분석 — 어떤 테이블이 필요한가?

요구사항 문장에서 명사를 뽑아보면 테이블의 후보가 보입니다.

요구사항 속 명사테이블 후보
회원member
게시글board
카테고리category
댓글comment
좋아요board_like

각 테이블이 서로 어떤 관계인지 정리합니다.

관계설명
member : board = 1 : N한 회원은 여러 게시글을 쓸 수 있음
category : board = 1 : N한 카테고리는 여러 게시글을 가질 수 있음
board : comment = 1 : N한 게시글에 여러 댓글이 달릴 수 있음
member : comment = 1 : N한 회원은 여러 댓글을 쓸 수 있음
member : board (좋아요) = N : N한 회원은 여러 게시글에 좋아요를 누르고, 한 게시글은 여러 회원에게 좋아요를 받음

💡 N:M(다대다) 관계는 테이블 하나로 표현할 수 없습니다. 중간에 연결 테이블(board_like)을 두어 1:N + N:1 구조로 풀어내야 합니다. 이번 게시판에서는 board_like가 바로 그 연결 테이블입니다.

3. 텍스트로 나타내기

member (1) ----< (N) board
member (1) ----< (N) comment
category (1) ----< (N) board
board (1) ----< (N) comment
member (N) ----< board_like >---- (N) board

코드를 작성하기 전에 이렇게 관계를 먼저 그려보는 습관이 중요합니다. 손으로 그리든, 종이에 쓰든, 표로 정리하든 상관없습니다. 설계를 먼저 끝내고 SQL은 그 다음입니다.

CREATE TABLE MEMBER (
    member_id BIGINT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at DATETIME NOT NULL
);

CREATE TABLE CATEGORY (
    category_id BIGINT PRIMARY KEY,
    category_name VARCHAR(50) NOT NULL
);

CREATE TABLE BOARD (
    board_id BIGINT PRIMARY KEY,
    member_id BIGINT NOT NULL,
    category_id BIGINT NOT NULL,
    title VARCHAR(200) NOT NULL,
    content TEXT NOT NULL,
    view_count INT DEFAULT 0,
    created_at DATETIME NOT NULL,
    FOREIGN KEY (member_id) REFERENCES MEMBER (member_id),
    FOREIGN KEY (category_id) REFERENCES CATEGORY (category_id)
);

CREATE TABLE COMMENT (
    comment_id BIGINT PRIMARY KEY,
    board_id BIGINT NOT NULL,
    member_id BIGINT NOT NULL,
    content TEXT NOT NULL,
    created_at DATETIME NOT NULL,
    FOREIGN KEY (board_id) REFERENCES BOARD (board_id),
    FOREIGN KEY (member_id) REFERENCES MEMBER (member_id)
);

CREATE TABLE BOARD_LIKE (
    board_id BIGINT NOT NULL,
    member_id BIGINT NOT NULL,
    created_at DATETIME NOT NULL,
    PRIMARY KEY (board_id, member_id),
    FOREIGN KEY (board_id) REFERENCES BOARD (board_id),
    FOREIGN KEY (member_id) REFERENCES MEMBER (member_id)
);

4. 컬럼까지 포함한 설계표

member

컬럼명타입제약조건
idBIGINTPK, AUTO_INCREMENT
nameVARCHAR(50)NOT NULL
emailVARCHAR(100)NOT NULL, UNIQUE
passwordVARCHAR(100)NOT NULL
created_atTIMESTAMPDEFAULT CURRENT_TIMESTAMP

category

컬럼명타입제약조건
idBIGINTPK, AUTO_INCREMENT
nameVARCHAR(50)NOT NULL, UNIQUE

board

컬럼명타입제약조건
idBIGINTPK, AUTO_INCREMENT
titleVARCHAR(200)NOT NULL
contentTEXTNOT NULL
view_countINTDEFAULT 0
member_idBIGINTNOT NULL, FK → member(id)
category_idBIGINTNOT NULL, FK → category(id)
created_atTIMESTAMPDEFAULT CURRENT_TIMESTAMP

comment

컬럼명타입제약조건
idBIGINTPK, AUTO_INCREMENT
contentVARCHAR(500)NOT NULL
board_idBIGINTNOT NULL, FK → board(id)
member_idBIGINTNOT NULL, FK → member(id)
created_atTIMESTAMPDEFAULT CURRENT_TIMESTAMP

board_like

컬럼명타입제약조건
board_idBIGINTPK(복합), FK → board(id)
member_idBIGINTPK(복합), FK → member(id)
created_atTIMESTAMPDEFAULT CURRENT_TIMESTAMP

5. 실습 순서

테이블을 만들 때는 참조하는 테이블보다 참조되는 테이블을 먼저 만들어야 합니다. (FK가 가리킬 대상이 먼저 존재해야 하기 때문)

생성 순서: member → category → board → comment → board_like

직접 H2 Console에서 위 순서대로 CREATE TABLE을 작성해봅니다. (정답은 연습 문제에서 확인합니다.)

샘플 데이터도 넣어봅니다.

INSERT INTO category (name) VALUES ('자유게시판');
INSERT INTO category (name) VALUES ('공지사항');

INSERT INTO member (name, email, password) VALUES ('홍길동', 'hong@test.com', '1234');
INSERT INTO member (name, email, password) VALUES ('김철수', 'kim@test.com', '1234');

INSERT INTO board (title, content, member_id, category_id) VALUES ('첫 게시글', '안녕하세요', 1, 1);

INSERT INTO comment (content, board_id, member_id) VALUES ('좋은 글이네요', 1, 2);

INSERT INTO board_like (board_id, member_id) VALUES (1, 2);

같은 회원이 같은 게시글에 좋아요를 한 번 더 누르면 어떻게 될까요? 직접 실행해서 에러를 확인해봅니다.

INSERT INTO board_like (board_id, member_id) VALUES (1, 2); -- 에러 발생 확인

정리

  • 요구사항에서 명사를 뽑아내면 테이블 후보가 보인다.
  • 테이블 간 관계는 1:N, N:M으로 분류하고, N:M은 연결 테이블로 풀어낸다.
  • SQL을 작성하기 전에 ERD(관계도)와 컬럼 설계표를 먼저 만든다.
  • 테이블 생성 순서는 참조되는 테이블(부모) → 참조하는 테이블(자식) 순이다.

DML — INSERT, UPDATE, DELETE

학습 목표

  • INSERT로 데이터를 다양한 방식으로 등록할 수 있다.
  • UPDATE로 조건에 맞는 데이터를 수정할 수 있다.
  • DELETE로 조건에 맞는 데이터를 삭제할 수 있다.
  • WHERE 조건 없이 UPDATE/DELETE를 실행하면 어떤 위험이 있는지 이해한다.

1. DML이란?

DML(Data Manipulation Language)은 테이블 안에 들어있는 데이터의 내용을 다루는 명령어입니다. SECTION03에서 배운 DDL(테이블 구조)과 구분됩니다.

명령어역할
INSERT새로운 데이터(행) 추가
UPDATE기존 데이터 수정
DELETE기존 데이터 삭제

이번 SECTION에서는 SECTION04에서 설계한 member, category, board, comment, board_like 테이블을 계속 사용합니다.

2. INSERT — 데이터 등록

2-1. 기본 문법

INSERT INTO 테이블명 (컬럼1, 컬럼2, ...) VALUES (값1, 값2, ...);
INSERT INTO member (name, email, password) VALUES ('이영희', 'lee@test.com', '1234');

id, created_at처럼 AUTO_INCREMENT나 DEFAULT가 걸려있는 컬럼은 값을 직접 넣지 않아도 자동으로 채워집니다.

2-2. 여러 행을 한 번에 등록

INSERT INTO member (name, email, password) VALUES
    ('박민수', 'park@test.com', '1234'),
    ('정수진', 'jung@test.com', '1234'),
    ('최동혁', 'choi@test.com', '1234');

2-3. 컬럼명을 생략하는 방식 (권장하지 않음)

INSERT INTO category VALUES (3, '질문');

테이블의 모든 컬럼 순서에 맞춰 값을 적어야 합니다. 컬럼이 추가되거나 순서가 바뀌면 바로 에러가 나기 때문에, 실무에서는 컬럼명을 명시하는 방식을 사용하는 것이 안전합니다.

3. UPDATE — 데이터 수정

3-1. 기본 문법

UPDATE 테이블명 SET 컬럼1 = 값1, 컬럼2 = 값2 WHERE 조건;
UPDATE member SET name = '이영희2' WHERE id = 3;

3-2. 여러 컬럼 동시 수정

UPDATE board SET title = '수정된 제목', content = '수정된 내용' WHERE id = 1;

3-3. 기존 값을 기반으로 수정 (조회수 증가 등)

UPDATE board SET view_count = view_count + 1 WHERE id = 1;

3-4. ⚠️ WHERE 없이 UPDATE 하면?

-- 위험! 모든 행의 view_count가 0으로 바뀜
UPDATE board SET view_count = 0;

WHERE 조건을 빼면 테이블의 모든 행이 수정됩니다. 실무에서 매우 자주 발생하는 실수이자 사고이므로, UPDATE 문을 작성할 때는 항상 WHERE 조건부터 먼저 떠올리는 습관을 들여야 합니다.

💡 안전하게 작업하는 습관: UPDATE 전에 같은 조건으로 SELECT를 먼저 실행해서 “내가 수정하려는 행이 정확히 이거 맞다”를 확인한 다음 UPDATE로 바꿔서 실행합니다.

SELECT * FROM board WHERE id = 1;   -- 먼저 확인
UPDATE board SET title = '수정된 제목' WHERE id = 1;  -- 확인 후 실행

4. DELETE — 데이터 삭제

4-1. 기본 문법

DELETE FROM 테이블명 WHERE 조건;
DELETE FROM comment WHERE id = 2;

4-2. ⚠️ WHERE 없이 DELETE 하면?

-- 위험! 테이블의 모든 행이 삭제됨 (테이블 구조는 남음)
DELETE FROM comment;

UPDATE와 마찬가지로 WHERE를 빠뜨리면 전체 데이터가 삭제됩니다. SECTION03에서 배운 TRUNCATE TABLE과 결과가 비슷하지만, DELETE는 조건을 걸 수 있다는 점이 가장 큰 차이입니다.

4-3. FK 관계가 있는 데이터 삭제 시 주의점

-- board의 id=1을 참조하는 comment, board_like가 있는 상태에서 board를 삭제하면?
DELETE FROM board WHERE id = 1;  -- 에러 발생 (참조 무결성 위반)

board를 참조하고 있는 comment, board_like가 남아있는 상태로는 board를 삭제할 수 없습니다. 삭제하려면 참조하는 데이터(comment, board_like)를 먼저 지우거나, 비즈니스 로직에서 연관 데이터를 함께 처리해야 합니다.

-- 올바른 순서
DELETE FROM board_like WHERE board_id = 1;
DELETE FROM comment WHERE board_id = 1;
DELETE FROM board WHERE id = 1;

추후 JPA를 다시 학습하는 단계에서 연관 관계 설정(CascadeType.REMOVE 등)으로 이 과정을 자동화할 수 있습니다. 지금은 SQL로 직접 순서를 맞춰보는 연습이 중요합니다.

5. INSERT, UPDATE, DELETE 한 흐름으로 연습

-- 1. 새 회원 등록
INSERT INTO member (name, email, password) VALUES ('강지훈', 'kang@test.com', '1234');

-- 2. 등록한 회원이 게시글 작성 (member_id는 방금 등록된 회원의 id로 가정, 예: 6)
INSERT INTO board (title, content, member_id, category_id) VALUES ('가입 인사', '안녕하세요!', 6, 1);

-- 3. 다른 회원이 댓글 작성
INSERT INTO comment (content, board_id, member_id) VALUES ('환영합니다', 1, 2);

-- 4. 게시글 내용 수정
UPDATE board SET content = '안녕하세요! 잘 부탁드립니다.' WHERE member_id = 6;

-- 5. 댓글 삭제
DELETE FROM comment WHERE board_id = 1 AND member_id = 2;

정리

  • INSERT는 새로운 행을 추가하고, 컬럼명을 명시하는 방식을 권장한다.
  • UPDATE는 기존 값을 기반으로 계산해서 수정할 수도 있다. (view_count = view_count + 1)
  • UPDATE/DELETE에서 WHERE를 빠뜨리면 테이블 전체가 영향을 받으므로 항상 주의해야 한다.
  • FK로 참조되고 있는 데이터는 참조하는 쪽을 먼저 삭제해야 한다.
  • UPDATE/DELETE 전에 같은 조건으로 SELECT를 먼저 실행해서 확인하는 습관이 중요하다.

0개의 댓글