조인이 필요한 이유 – 데이터 정규화의 통합

데이터베이스를 설계할 때 정보를 여러 테이블에 나누어 저장하는 것은 데이터의 효율적인 관리와 무결성 유지를 위한 필수적인 과정이다. 이를 정규화(Normalization)라고 하며, 흩어진 데이터를 다시 연결하여 의미 있는 정보를 얻는 기술이 바로 조인(JOIN)이다.

Users Table

Products Table

Orders Table

데이터 분리의 필요성 (정규화)

만약 모든 정보를 하나의 거대한 테이블에 저장한다면 아래와 같은 심각한 문제가 발생한다

  • 데이터 중복 (Redundancy): 동일한 정보(예: 고객 이름, 주소)가 여러 번 반복 저장되어 저장 공간을 낭비한다
  • 갱신 이상 (Update Anomaly): 중복된 정보 중 일부만 수정하고 나머지를 누락하면 데이터의 일관성이 깨진다 (예: 고객 이메일 변경 시 모든 주문 기록에서 수정해야 함)
  • 삽입 이상 (Insertion Anomaly): 특정 정보(예: 새 상품 정보)를 추가하기 위해 다른 정보(예: 주문 내역)가 반드시 존재해야 하는 비논리적인 상황이 발생한다(예: 주문 없는 상품 등록 불가)
  • 삭제 이상 (Deletion Anomaly): 특정 정보(예: 주문 기록)를 삭제할 때, 의도치 않게 다른 중요한 정보(예: 고객 정보)까지 손실될 수 있다

이러한 문제들을 방지하기 위해 데이터를 논리적인 단위로 분리하여 저장하는 과정이 정규화이다. users, products, orders 테이블로 데이터를 나눈 것이 바로 정규화의 결과물이다

정규화 간략 소개 (테이블 기준)

정규화는 김영한 님의 강의 김영한의 실전 데이터베이스 – 기본편에 자세히 나오지만 훑어보는 식으로 정리해보았다. users. products, orders 테이블 구조는 이미 정규화가 적용된 형태이다.

유튜브 쉬운코딩님의 채널에도 정규화에 대한 내용이 자세히 나와있다

1차 정규화 (1NF – First Normal Form)

  • 모든 컬럼이 원자적 값(더 이상 나눌 수 없는 단일 값)을 가져야 한다
  • 반복되는 그룹(Repeating Groups)이 없어야 한다
    • address 컬럼에 여루 주소가 콤마로 구분되어 있으면 1NF 위반
  • 제공된 테이블들을 이 기준으로 만족한다. 각 셀에 하나의 값만 저장되어 있다

2차 정규화 (2NF – Second Normal Form)

  • 1차 정규화를 만족해야 한다
  • 복합 기본 키(Composite Primary Key)를 가진 테이블에서, 기본 키의 일부에만 종속되는 비기본 키(Non-Key) 컬럼이 없어야 한다
  • 즉, 모든 비기본 키 컬럼은 기본 키 전체에 완전 함수 종속(Full Functional Dependency)이어야 한다
  • users, products 테이블은 user_id, product_id 라는 단일 키를 가지고 있으므로, 이 시점에서 이미 2NF를 만족한다. orders 테이블의 기본 키는 order_id이고 user_id와 product_id는 외래 키로 참조되므로, 비기본 키 컬럼인 order_date, quantity, status는 order_id 전체에 종속된다. 따라서 2NF를 만족한다

3차 정규화 (3NF – Third Normal Form)

  • 2차 정규화를 만족해야 한다
  • 기본 키가 아닌 컬럼이 다른 비기본 키 컬럼에 종속되는 이행적 함수 종속(Transitive Functional Dependency)이 없어야 한다
    • products 테이블에 category_name과 함께 category_description이 있고 category_description이 category_name에 종속된다면, category_description을 별도 테이블로 분리해야 3NF를 만족
  • users, products, orders는 3NF에 대채로 만족하는 구조로 보인다. users 테이블에서 address가 user_id외 다른 컬럼에 종속되지 않고, products 테이블에서 category가 product_id 외 다른 컬럼에 종속되지 않는다

정규화는 데이터의 중복을 최소화하고 데이터 무결성을 유지하는 데 필수적이지만, 때로는 너무 많은 테이블 분리가 쿼리 성능 저하로 이어질 수 있어, 실제 시스템에서는 트레이드오프를 고려하여 비정규화(Denormalization)를 적용하기도 한다

조인(JOIN)의 필요성

정규화를 통해 데이터는 효율적으로 관리되지만, “최근 주문 현황을 고객 이름과 상품명을 포함해서 보고서로 만들어 줘”와 같은 요청에는 단일 테이블만으로는 필요한 정보를 얻을 수 없다. orders 테이블에는 user_id와 product_id만 있을 뿐, 실제 고객 이름이나 상품명은 각각 users 테이블과 products 테이블에 별도로 저장되어 있기 때문이다. 이처럼 분리된 테이블에서 의미 있는 통합된 정보를 얻기 위해 사용하는 기술이 바로 조인(JOIN)이다

조인(JOIN)

조인은 두 개 이상의 테이블을 특정 컬럼(주요 기본 키(Promary Key)와 와래 키(Foreign Key) 관계)을 기준으로 연결하며, 마치 처음부터 하나의 테이블이었던 것처럼 데이터를 결합하여 보여주는 기능이다

  • orders 테이블의 user_id (외래 키)는 users 테이블의 user_id (기본 키)와 연결된다
  • orders 테이블의 product_id (외래 키)는 products 테이블의 product_id (기본 키)와 연결된다

조인은 데이터 정규화의 장점(데이터 중복 방지, 일관성 유지)를 그대로 유지하면서,원하는 통합된 정보를 유연하게 조회할 수 있게 해준다

출처 – 김영한님 강의 중 김영한의 실전 데이터베이스 – 기본편