DB 개념 / SQL 기본 문법 정리 (복습용)
이 글은 웹서버-WAS-DB 구조 중에서 DB 쪽에서 무슨 일이 일어나는가를 감 잡기 위한 정리다.
1. DB를 엑셀로 비유해서 이해하기
우리가 보통 말하는 데이터베이스(DB)를 엑셀 기준으로 단순 비교하면 이렇게 볼 수 있다:
- 엑셀 파일 전체 = 데이터베이스(Database)
- 엑셀 파일 안의 각 시트 = 테이블(Table)
- 시트의 열(가로 첫 줄 제목들) = 컬럼(Column) / 필드(field)라고도 부름
- 시트의 행(데이터 한 줄) = 로우(Row) / 레코드(record)라고도 부름
중요:
DB에서 "테이블"은 구조(컬럼 이름/타입 등)까지 포함한 하나의 시트라고 생각하면 된다.
그리고 "행(row)의 개수"라고 하면 실제 데이터 줄 수를 말한다. (엑셀에서 맨 위 컬럼 제목 줄은 보통 데이터 개수에 안 친다.)
DB에서 "테이블"은 구조(컬럼 이름/타입 등)까지 포함한 하나의 시트라고 생각하면 된다.
그리고 "행(row)의 개수"라고 하면 실제 데이터 줄 수를 말한다. (엑셀에서 맨 위 컬럼 제목 줄은 보통 데이터 개수에 안 친다.)
즉 데이터베이스는 여러 테이블의 묶음이고, 각 테이블은 같은 컬럼 구조를 공유하는 많은 행들의 집합이다.
2. 애플리케이션(WAS)과 DB는 어떻게 대화하나?
웹 서비스의 단순화된 흐름은 보통 이렇게 본다:
브라우저(사용자 화면) ↓ 요청 WAS(Web Application Server: PHP, Spring, Django 등) ↓ SQL 쿼리 DB 서버(MySQL, PostgreSQL, Oracle 등)
핵심 포인트: WAS랑 DB는 SQL이라는 언어로만 얘기한다.
예를 들어 로그인:
- 사용자가 아이디/비번 입력 → 브라우저가 WAS로 전송
- WAS가 DB에게 묻는다: "이 아이디+비번이 맞는 유저 있냐?" (SQL로 SELECT 날림)
- DB가 결과를 돌려줌
- WAS가 "로그인 성공/실패" 페이지를 만들어서 브라우저에 응답
즉 요약:
DB랑 직접 말하는 건 사람(사용자)이 아니라 WAS다.
우리는 그 대화 내용을 이해하려면 SQL 문법을 알아야 한다.
DB랑 직접 말하는 건 사람(사용자)이 아니라 WAS다.
우리는 그 대화 내용을 이해하려면 SQL 문법을 알아야 한다.
3. SQL은 크게 DDL / DML / DCL로 나뉜다
3.1 DDL (Data Definition Language)
DDL = 구조(틀)를 정의/변경/삭제하는 명령어. 즉 "테이블 자체를 건드리는" 쿼리.
- CREATE : 새 테이블 만들기
CREATE TABLE users (...); - ALTER : 기존 테이블 구조 바꾸기(컬럼 추가/삭제 등)
ALTER TABLE users ADD COLUMN phone VARCHAR(20); - DROP : 테이블 자체 삭제 (데이터 포함 다 날아감)
DROP TABLE users;
주의 (운영 환경):
DROP이나 잘못된 ALTER는 진짜로 서비스에 직접 영향 준다.
DDL은 데이터 한 줄 수정이 아니라 테이블의 존재 자체를 건드리는 거라 사고 나면 복구 빡셈.
DROP이나 잘못된 ALTER는 진짜로 서비스에 직접 영향 준다.
DDL은 데이터 한 줄 수정이 아니라 테이블의 존재 자체를 건드리는 거라 사고 나면 복구 빡셈.
3.2 DML (Data Manipulation Language)
DML = 테이블 "안의 데이터"를 다루는 명령어. 실제 비즈니스 로직 대부분이 여기에 해당한다.
- SELECT : 데이터 조회 (읽기)
- INSERT : 데이터 추가 (회원가입, 글쓰기 등)
- UPDATE : 데이터 수정 (이메일 변경 등)
- DELETE : 데이터 삭제
보안/감사에서 중요한 건 거의 항상 DML이다.
예: 누가 SELECT로 고객정보를 많이 뽑아갔나? / 누가 DELETE로 기록을 지웠나?
이런 게 그대로 "사고 분석" 포인트가 된다.
예: 누가 SELECT로 고객정보를 많이 뽑아갔나? / 누가 DELETE로 기록을 지웠나?
이런 게 그대로 "사고 분석" 포인트가 된다.
3.3 DCL (Data Control Language)
DCL = 권한과 접근 통제 관련 명령어. "누가 뭘 할 수 있는가?"를 결정한다.
- GRANT : 권한 주기
GRANT SELECT ON users TO analyst_user; - REVOKE : 권한 회수
REVOKE UPDATE ON users FROM analyst_user;
실무 관점:
- 운영 DB에서는 계정을 나눈다.
예: 읽기 전용(read-only) 계정 / 수정 가능한 계정 / DBA 계정 등
- 최소권한 원칙(Least Privilege)이 핵심이다.
- 모든 계정이 DROP 가능하면 그건 그냥 폭탄이다.
- 운영 DB에서는 계정을 나눈다.
예: 읽기 전용(read-only) 계정 / 수정 가능한 계정 / DBA 계정 등
- 최소권한 원칙(Least Privilege)이 핵심이다.
- 모든 계정이 DROP 가능하면 그건 그냥 폭탄이다.
4. SELECT 기본형
SELECT = 조회(읽기)다. 기본 문법은 이렇다:
SELECT 컬럼이름 FROM 테이블이름;
예시:
SELECT username FROM users;
여러 컬럼 가져오기:
SELECT username, email, created_at FROM users;
모든 컬럼(전체)을 다 달라고 할 수도 있다:
SELECT * FROM users;
주의:
- 불필요하게 모든 컬럼을 다 가져오면 DB/네트워크 부하 ↑
- 민감정보(예: 주민번호, 비번 해시 등)까지 실수로 나갈 수 있다
- 테이블 구조가 바뀌면(컬럼 추가 등) 앱 동작이 깨질 수도 있다
→ 실무에서는 정말 필요한 컬럼만 명시적으로 적는다.
SELECT * 는 연습할 땐 편하지만, 운영 환경에서는 권장되지 않는 경우가 많다.- 불필요하게 모든 컬럼을 다 가져오면 DB/네트워크 부하 ↑
- 민감정보(예: 주민번호, 비번 해시 등)까지 실수로 나갈 수 있다
- 테이블 구조가 바뀌면(컬럼 추가 등) 앱 동작이 깨질 수도 있다
→ 실무에서는 정말 필요한 컬럼만 명시적으로 적는다.
5. WHERE 조건절 (필터링)
현실의 테이블은 데이터가 수천, 수백만 행 단위로 쌓인다. 전부 긁어오는 건 비효율이고 위험하다. 그래서 WHERE로 필요한 행만 가져온다.
SELECT 컬럼1, 컬럼2 FROM 테이블 WHERE 조건;
예시 1: 특정 사용자 한 명 찾기
SELECT user_id, username, last_login FROM users WHERE username = 'alice';
예시 2: 로그인 검증 같은 흐름
SELECT user_id FROM users WHERE username = 'alice' AND password_hash = '해시된비번값...';
예시 3: 기간 한정 조회
SELECT * FROM login_history WHERE login_time >= '2025-10-01' AND login_time < '2025-11-01';
WHERE는 보안에도 중요하다.
- WHERE 없이 SELECT 하면 전체 개인정보 긁힐 수도 있음
- WHERE 없이 UPDATE/DELETE 하면 전체가 날아갈 수도 있음 (아래 참고)
→ 그래서 운영 DB에서 WHERE는 안전벨트 같은 존재다.
- WHERE 없이 SELECT 하면 전체 개인정보 긁힐 수도 있음
- WHERE 없이 UPDATE/DELETE 하면 전체가 날아갈 수도 있음 (아래 참고)
→ 그래서 운영 DB에서 WHERE는 안전벨트 같은 존재다.
6. INSERT / UPDATE / DELETE 간단 요약
6.1 INSERT (새 데이터 추가)
INSERT INTO users (username, email, password_hash) VALUES ('alice', 'alice@example.com', '...해시...');
→ 회원가입, 글쓰기, 주문 생성 같은 "신규 등록" 상황에서 쓰이는 패턴.
6.2 UPDATE (기존 데이터 수정)
UPDATE users SET email = 'new_email@example.com' WHERE user_id = 10;
진짜 핵심:
WHERE 없이 UPDATE 하면 전체가 바뀐다.
운영DB에서 이거 한 방이면 전사용자 이메일이 한꺼번에 "new_email@example.com" 같은 참사 가능.
→ 실무자들이 UPDATE/DELETE 쿼리 날리기 전에 WHERE 확인을 집착적으로 하는 이유.
WHERE 없이 UPDATE 하면 전체가 바뀐다.
운영DB에서 이거 한 방이면 전사용자 이메일이 한꺼번에 "new_email@example.com" 같은 참사 가능.
→ 실무자들이 UPDATE/DELETE 쿼리 날리기 전에 WHERE 확인을 집착적으로 하는 이유.
6.3 DELETE (데이터 삭제)
DELETE FROM users WHERE user_id = 10;
이건 "행 자체를 지워라"라는 의미다.
운영에서는 실제 삭제 대신 '삭제 표시'만 하는 방식도 흔하다.
예: 테이블에
이렇게 하면 기록 추적이 쉽고, 사고 났을 때 복구가 가능하다.
예: 테이블에
is_deleted 컬럼을 두고 1로 바꾸는 식.이렇게 하면 기록 추적이 쉽고, 사고 났을 때 복구가 가능하다.
7. 권한 제어(DCL)과 보안 관점
DB에는 계정이 여러 개일 수 있다. 예:
- app_user : 서비스(WAS)가 접속하는 계정 → SELECT/INSERT/UPDATE 정도만 허용
- read_only_user : 감사/리포트용 계정 → SELECT만 가능
- admin_user (DBA) : DDL까지 가능 (CREATE, DROP 등)
보안 관점에서 보는 것들:
- 불필요하게 강한 권한 가진 계정이 있는가?
- 여러 사람이 같은 관리자 계정(ID/PW 공유) 쓰는가?
- 서비스 계정(app_user)이 정말 필요한 권한만 갖는가?
- DB 포트가 외부(인터넷)에서 바로 접근 가능한가? (있으면 거의 바로 레드 플래그)
- 불필요하게 강한 권한 가진 계정이 있는가?
- 여러 사람이 같은 관리자 계정(ID/PW 공유) 쓰는가?
- 서비스 계정(app_user)이 정말 필요한 권한만 갖는가?
- DB 포트가 외부(인터넷)에서 바로 접근 가능한가? (있으면 거의 바로 레드 플래그)
8. 최종 요약 (외워둘 것)
- DB = 엑셀 파일, 테이블 = 시트, 컬럼 = 열 제목, 로우 = 데이터 한 줄
→ 그냥 표 구조라고 생각하면 된다. - WAS ↔ DB = SQL
→ 사용자의 모든 행위(로그인, 글쓰기 등)는 결국 SQL 쿼리로 변환돼서 DB한테 간다. - SQL은 3종류
- DDL: 테이블 뼈대 정의/변경/삭제 (CREATE, ALTER, DROP)
- DML: 데이터 조회/추가/수정/삭제 (SELECT, INSERT, UPDATE, DELETE)
- DCL: 권한 제어 (GRANT, REVOKE) - SELECT * 남발 금지
→ 성능낭비 + 민감정보 과다조회 + 구조변경 시 리스크 - UPDATE / DELETE 할 때 WHERE는 생명줄
WHERE 없이 날리면 전체 데이터가 싹 바뀌거나 날아갈 수 있다. - 권한(DCL)은 보안과 직접 연결
최소권한 원칙이 안 지켜지면, 내부자/공격자 모두에게 DB가 그대로 노출되는 거랑 다를 게 없다.
다음 글에서는 이번 과제인 로그인 페이지를 직접 생성(입력)한 DB와 연결하여 구현!해보겠음
(php myadmin 써도 된다고 한다)
'해킹스터디' 카테고리의 다른 글
| [Normaltic 웹해킹 입문] 3강 관련 복습&리뷰-②(세션) (0) | 2025.11.04 |
|---|---|
| [Normaltic 웹해킹 입문] 3강 관련 복습&리뷰-①(DB) (0) | 2025.11.04 |
| [Normaltic 웹해킹 입문] 2강 관련 복습&리뷰-① (3) | 2025.10.29 |
| [Normaltic 웹해킹 입문] 1강 주요 과제-APM 환경에서 로그인 페이지 만들기(php 이용, DB 연동X) (0) | 2025.10.28 |
| [Normaltic 웹해킹 입문] 1강 주요 과제-APM 웹 개발 환경 세팅(VBox 이용) (1) | 2025.10.24 |