1. 데이터베이스 정규화 (Normalization)
DB 설계 단계에서 가장 중요한 건 중복 제거와 이상현상 방지다.
정규화 과정을 통해 구조를 깔끔하게 만들 수 있다.
- 1차 정규화 (1NF)
모든 속성은 원자값만 가져야 한다.
예) 전화번호를 여러 개 넣지 말고, 전화번호 테이블을 분리한다. - 2차 정규화 (2NF)
1NF 만족 + 기본키의 부분집합에만 종속된 속성 제거.
예) (학생ID, 과목ID) → 성적, 여기서 "학생 주소"는 학생ID만으로 결정되므로 분리. - 3차 정규화 (3NF)
2NF 만족 + 기본키가 아닌 속성이 다른 속성에 종속되면 제거.
예) 학생 테이블에서 학과ID → 학과명 관계가 있다면 학과 테이블로 분리.
2. 참조 무결성과 외래키 제약
- 참조 무결성 (Referential Integrity)
자식 테이블의 FK는 반드시 부모 테이블의 PK를 참조해야 한다.
CREATE TABLE tEmployee (
name CHAR(10) PRIMARY KEY
);
CREATE TABLE tProject (
projectID INT PRIMARY KEY,
employee CHAR(10) NOT NULL,
project VARCHAR(30) NOT NULL,
CONSTRAINT FK_emp FOREIGN KEY(employee) REFERENCES tEmployee(name)
);
➡ tProject.employee 값은 반드시 tEmployee.name 중 하나여야 한다.
- 외래키 선언 방식
- 컬럼 레벨 지정
- 테이블 레벨 지정 (실무 권장 – 유지보수 용이)
- 연계 참조 무결성 (Referential Actions)
부모 삭제 시 자식 처리 옵션:- NO ACTION (기본값, 오류 발생)
- CASCADE (자식도 같이 삭제)
- SET NULL (자식 FK NULL 처리)
- 오라클은 ON UPDATE CASCADE 지원 x (트리거로 구현)
3. VARCHAR vs VARCHAR2
- VARCHAR : ANSI 표준, 내부적으로 VARCHAR2로 변환됨
- VARCHAR2 : 오라클 고유, 가변 길이 문자열
- 오라클에서는 VARCHAR2 사용 권장
4. ENUM 타입 대체 방법 (Oracle)
MySQL의 ENUM은 오라클에 없음 → 아래 두 가지로 대체:
- CHECK 제약조건
status NUMBER CHECK (status IN (1,2,3,4))
- 코드 테이블 방식 (실무 권장)
별도 테이블을 만들어 FK로 연결
➡ 상태값 확장/관리 용이
5. SQL 쿼리 동작 순서
많이 헷갈리는 부분인데, SQL 실행 순서는 우리가 작성한 순서와 다르다.
실행 순서 (논리적 처리 순서)
- FROM / JOIN
- WHERE
- GROUP BY
- HAVING
- SELECT
- ORDER BY
➡ 즉, SELECT가 먼저 오는 것 같지만, 실제로는 FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY 순서대로 실행된다.
6. 서브쿼리 (Subquery)
SQL 안에 또 다른 SQL을 넣는 방식.
종류는 크게 단일행 / 다중행 / 다중열 / 연관 서브쿼리 / 인라인뷰로 나뉜다.
6-1) 단일행 서브쿼리
SELECT name
FROM tCity
WHERE popu = (SELECT MAX(popu) FROM tCity);
6-2) 다중행 서브쿼리 – IN
SELECT item
FROM tItem
WHERE item IN (SELECT item FROM tOrder WHERE member='향단');
6-3) ANY / ALL
-- ANY : 조건을 하나라도 만족하면 참
salary > ANY (SELECT salary FROM tStaff WHERE depart='영업부')
-- ALL : 모든 조건을 만족해야 참
salary > ALL (SELECT salary FROM tStaff WHERE depart='영업부')
- > ANY → 최소값보다 크면 OK
- > ALL → 최대값보다 커야 OK
6-4) EXISTS
SELECT *
FROM tMember m
WHERE EXISTS (
SELECT 1
FROM tOrder o
WHERE o.member = m.member
);
➡ 주문이 존재하는 회원만 조회.
➡ EXISTS는 참/거짓만 반환하므로 성능이 좋다.
6-5) 인라인뷰
SELECT *
FROM (SELECT * FROM tCity WHERE metro = 'y') A;
➡ 서브쿼리를 FROM 절에서 사용 → 임시 테이블처럼 활용.
7. SQL 튜닝과 서브쿼리 최적화
- EXISTS vs IN: 큰 테이블일 때는 EXISTS가 더 빠른 경우 많음
- ANY, ALL: 잘못 쓰면 불필요한 Full Scan 발생
- 인라인뷰: 가공된 데이터셋을 활용할 때 성능 최적화 가능
- 정규화: 중복 제거, 이상현상 방지
- 참조 무결성: FK는 반드시 유효한 PK 참조
- VARCHAR2: 오라클 문자열 컬럼은 무조건 VARCHAR2 사용
- ENUM: CHECK 제약조건 or 코드 테이블로 대체
- 쿼리 동작 순서: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
- 서브쿼리: 단일행, 다중행, ANY/ALL, EXISTS, 인라인뷰
- 튜닝 포인트: EXISTS 활용, 불필요한 서브쿼리 최소화
'SQL' 카테고리의 다른 글
| SQL 조인 정리 (INNER, OUTER, 다중조인, 인라인 뷰 조인) (0) | 2025.06.12 |
|---|---|
| LINQPad 로 LINQ 문 , SQL 문 연습하기 (0) | 2025.06.09 |
| JOIN 종류 (0) | 2025.06.09 |