쪼갤수록 안전해지는 데이터
데이터베이스 정규화의 기초 개념을 이해하고, 중복 데이터를 제거하여 구조를 탄탄하게 설계하는 쪼개기 원리를 학습합니다.
데이터베이스를 처음 설계할 때 가장 많이 하는 실수는 엑셀 마인드를 버리지 못하고 "조회하기 편하게 하나의 커다란 테이블에 모든 정보를 다 밀어 넣자!"라고 생각하는 것입니다. 하지만 데이터는 한 곳에 뚱뚱하게 뭉쳐있을수록 썩기 마련이고, 조각조각 잘게 쪼개어 연결해 둘수록 안전하고 건강해집니다. 이번 시간에는 데이터의 중복을 없애고 구조를 탄탄하게 세우는 관계형 데이터베이스의 미학, '정규화(Normalization)'라는 쪼개기 원리에 대해 알아봅니다.
기형적인 거대 테이블의 재앙
여러분이 쇼핑몰의 '주문 내역' 테이블을 설계한다고 해봅시다. 엑셀처럼 편하게 한 테이블에 다 넣어보겠습니다.
거대 테이블의 잘못된 설계 예시
<TableBlock title="모든 정보가 뭉쳐있는 테이블" columns={["주문번호", "주문자 이름", "배송지 주소", "주문한 상품명"]} rows={[ ["1", "홍길동", "서울시 강남구", "나이키 운동화"], ["2", "홍길동", "서울시 강남구", "아디다스 반팔티"], ["3", "홍길동", "서울시 강남구", "검은색 양말"] ]} />
홍길동이 물건을 3개 샀더니, 위와 같이 3줄의 데이터가 생겼습니다. 무언가 이상함을 느끼셨나요? 홍길동이라는 사람의 '이름, 전화번호, 배송지 주소'라는 똑같은 텍스트 덩어리가 데이터베이스에 불필요하게 3번이나 중복되어 저장되었습니다. 만약 홍길동이 물건을 1,000개 샀다면 이 쓸데없는 텍스트 덩어리가 1,000줄로 늘어납니다.
중복 데이터가 불러오는 3가지 비극
오해 또는 실수
용량 낭비
바로잡기
같은 글자를 수천 번 반복 저장하므로, 작고 날렵해야 할 데이터베이스의 용량이 불필요하게 뚱뚱해지고 느려집니다.
오해 또는 실수
수정의 악몽 (가장 치명적)
바로잡기
홍길동이 이사 가서 주소를 '제주도'로 바꾸려고 합니다. 개발자는 1,000개의 과거 주문 내역을 전부 뒤져서 주소를 제주도로 하나하나 다 바꿔주어야 합니다.
오해 또는 실수
데이터 불일치 (모순)
바로잡기
만약 1,000개 중 실수로 999개만 제주도로 바뀌고 1개가 서울로 남아있다면? 시스템은 홍길동의 진짜 주소가 대체 어디인지 확신할 수 없게 되어버립니다.
메스로 깔끔하게 도려내기: 정규화
이 끔찍한 비극을 해결하는 유일한 방법은 겹치는 데이터를 메스로 도려내어 완전히 독립된 방(테이블)으로 쫓아내 버리는 것입니다. 이 과정을 컴퓨터 공학에서는 고상한 말로 정규화(Normalization)라고 부릅니다.
정규화의 핵심 철학은 "하나의 데이터는 우리 서비스 전체를 통틀어 오직 한 곳에만 존재해야 한다"는 것입니다.
1. 쪼개고 분리하기
방금 본 거대 테이블을 정규화의 원리에 따라 두 개의 테이블로 쪼개보겠습니다. 사람 정보가 겹치니 사람을 따로 빼는 것입니다.
[유저 테이블 (Users)]
유저 테이블 (Users)
| 유저 고유번호(id) | 이름 | 전화번호 | 배송지 주소 |
|---|---|---|---|
| 100 | 홍길동 | 010-1111-2222 | 서울시 강남구 |
[주문 내역 테이블 (Orders)]
주문 내역 테이블 (Orders)
| 주문번호(id) | 주문자(user_id) | 주문한 상품명 | 상품 가격 |
|---|---|---|---|
| 1 | 100 (홍길동의 id) | 나이키 운동화 | 100,000 |
| 2 | 100 (홍길동의 id) | 아디다스 반팔티 | 30,000 |
| 3 | 100 (홍길동의 id) | 검은색 양말 | 5,000 |
2. 마법 같은 효과
이렇게 쪼개고 나면 어떤 기적이 일어날까요? 주문 내역 테이블에는 텍스트가 꽉 찬 홍길동의 개인정보 대신, 단 1바이트짜리 아주 가벼운 숫자 `100` (외래키)만 기록됩니다. 저장 공간이 엄청나게 절약됩니다.
더 중요한 것은 '수정'할 때입니다. 홍길동이 제주도로 이사를 가면, 이제 우리는 과거 주문 내역 1,000줄을 건드릴 필요가 아예 없습니다. 오직 유저 테이블(Users)에서 홍길동의 주소 칸 단 1개만 '제주도'로 쓱 바꿔주면 끝납니다. 정보가 오직 한 곳에만 있으니 모순이 생길 일도 없고 안전합니다.
나중에 화면에 주문자와 상품명을 같이 보여줘야 할 때 걱정이 되신다고요? 걱정하지 마세요. 우리는 4회차에서 이 쪼개진 데이터를 0.01초 만에 하나로 엮어주는 마법의 강력한 본드, `JOIN` 명령어를 이미 배웠습니다. 데이터베이스 엔진은 이 `JOIN` 작업에 엄청나게 최적화되어 있습니다.
비개발자를 위한 정규화 실전 체크리스트
- 1AI에게 데이터베이스 스키마(구조)를 짜달라고 했을 때, 회원 이름이나 프로필 사진 URL 같은 똑같은 정보가 여러 테이블에 복사되어 있다면 잘못 짠 것입니다. 분리해달라고 지시하세요.
- 2정규화는 제1정규형, 제2정규형, 제3정규형 등 어려운 수학적 규칙이 있지만 실무에서는 하나만 기억하면 됩니다. '중복된 텍스트 덩어리가 반복해서 나오는가? 그렇다면 따로 테이블을 파서 ID로 연결하라!'
- 3다만 정규화가 너무 지나쳐서 테이블을 10개씩 쪼개놓으면, 화면을 그릴 때 JOIN을 10번씩 해야 하므로 조회가 약간 느려질 수 있습니다. 적당한 쪼개기가 미덕입니다.
개념 퀴즈
퀴즈 답을 맞춰야 학습 완료가 됩니다.게시판 시스템을 구축할 때, '게시글 테이블(posts)' 안에 글 제목, 내용과 함께 '작성자의 이메일 주소'와 '작성자의 나이' 컬럼까지 한꺼번에 넣어서 거대하게 설계했습니다. 이렇게 설계했을 때, 데이터베이스 정규화 관점에서 발생할 수 있는 가장 치명적이고 위험한 문제는 무엇인가요?
3줄 요약
- 1하나의 큰 테이블에 모든 데이터를 뭉쳐 넣으면 내용이 중복되어 용량이 낭비되고, 정보를 수정할 때 오류가 생길 확률이 기하급수적으로 높아집니다.
- 2정규화(Normalization)는 중복되는 데이터 덩어리를 별도의 독립된 테이블로 쪼개어 분리하고, 이를 외래키(ID)로 연결하여 데이터의 일관성을 유지하는 설계 기법입니다.
- 3데이터를 안전하게 보관하기 위해 테이블을 쪼개두었다가(정규화), 나중에 사용자의 화면에 보여줄 때만 JOIN 명령어를 사용하여 다시 합쳐서 가져오는 것이 RDBMS의 핵심 철학입니다.