# RDB vs NoSQL

## 1. 개념

### 1.1. RDB

**관계를 통해 데이터를 조직화하는 방식**을 사용

* **테이블(Table)**
  * 행(Row)과 열(Column)로 구성된 데이터 저장 구조입니다.
  * 각 테이블은 특정한 유형의 엔터티(예: “사용자”, “주문”, “제품” 등)를 나타내며, 사전에 정의된 스키마(schema)에 따라 생성됩니다.
  * 스키마는 테이블에 들어갈 컬럼의 이름, 데이터 타입, 제약 조건 등을 미리 정의합니다.
* **스키마(Schema)**
  * 테이블 구조, 관계(1:1, 1:N, N:M 등), 제약 조건(Primary Key, Foreign Key, Unique, Not Null 등)을 정의해놓은 설계 구조입니다.
  * 예를 들어, “사용자” 테이블에는 `user_id(PK)`, `username`, `email`, `created_at` 등의 컬럼이 있을 수 있으며, 반드시 이 스키마에 맞춰 데이터를 저장해야 합니다.
* **관계(Relations)**
  * RDB에서 데이터는 각 테이블 간 **관계**를 통해 연결됩니다.
  * Foreign Key(외래 키)를 사용해 다른 테이블의 Primary Key(기본 키)를 참조함으로써, 여러 테이블에 분산된 데이터가 상호 연결됩니다.
  * 이러한 관계를 통해 `JOIN` 같은 연산이 가능해져, 다수의 테이블에서 원하는 형태로 데이터를 조합하여 조회할 수 있습니다.
* **정규화(Normalization)**
  * 중복된 데이터를 최소화하고, 데이터 무결성을 유지하기 위해 테이블을 세분화하는 과정입니다.
  * 예를 들어, 사용자 정보가 주문 테이블에 중복으로 저장되지 않도록, “사용자” 테이블과 “주문” 테이블을 분리하고 외래 키로 연결합니다.
  * 이를 통해 데이터 일관성과 무결성을 유지하기 쉬워집니다.
* **특징 요약**
  * **엄격한 스키마**: 미리 정의된 스키마에 맞춰 데이터가 저장되어야 하므로, 구조적인 일관성이 뛰어납니다.
  * **JOIN 지원**: 관계에 기반한 복잡한 쿼리를 실행할 수 있습니다.
  * **ACID 트랜잭션**: 원자성(Atomicity), 일관성(Consistency), 고립성(Isolation), 지속성(Durability)을 보장함으로써, 금융 및 트랜잭션이 중요한 시스템에서 안전한 데이터 처리를 제공합니다.



### 1.2. NoSQL

**전통적인 관계형 모델에 얽매이지 않고 다양한 데이터 구조**를 지원하는 데이터베이스들을 포괄하는 용어. RDB가 테이블-행-열 구조에 기반한다면, NoSQL은 그 목적과 용도에 따라 크게 **문서(Document)형, 키-값(Key-Value)형, 컬럼 패밀리(Column-Family)형, 그래프(Graph)형** 등으로 나뉩니다.

1. **문서(Document)형 DB**
   * JSON, BSON 등 **반(半)구조화된** 문서 형태로 데이터를 저장합니다.
   * 대표 예시: **MongoDB**, CouchDB 등.
   * 하나의 문서는 “사용자”나 “주문”에 관한 모든 정보를 중첩 구조로 담을 수 있습니다. 예를 들어, “주문” 문서 안에 주문 상세 정보나 배송지 정보를 함께 넣어둘 수 있어, 다수의 테이블을 JOIN해야 하는 RDB보다 데이터를 조회하기가 간단해질 수 있습니다.
   * 스키마가 고정되어 있지 않아, 새로운 필드를 추가하는 것이 간편합니다.
2. **키-값(Key-Value)형 DB**
   * \*\*Key(키)\*\*와 \*\*Value(값)\*\*의 쌍(Pair)으로만 데이터를 저장하는 가장 단순한 형태입니다.
   * 대표 예시: **Redis**, Amazon DynamoDB(키-값 형태로 사용 가능) 등.
   * 대규모 확장이 쉽고, 메모리 기반 연산을 통해 매우 빠른 읽기/쓰기가 가능합니다.
   * 구조가 단순한 대신, 복잡한 쿼리나 조건 검색에는 추가적인 로직을 구현해야 합니다.
3. **컬럼 패밀리(Column-Family)형 DB**
   * RDB의 테이블과 유사해 보이지만, **필요한 컬럼들만 묶어 관리**하는 “컬럼 패밀리”라는 구조를 가집니다.
   * 대표 예시: **Apache Cassandra, HBase** 등.
   * 대용량 데이터 처리에 특화되어 있으며, 분산 환경에서 수평 확장을 쉽게 할 수 있도록 설계되었습니다.
   * 특정 컬럼 그룹에만 접근할 때 매우 빠르게 조회할 수 있고, 스키마가 유연하여 테이블마다 컬럼이 달라도 문제가 없습니다.
4. **그래프(Graph)형 DB**
   * 노드(Node)와 엣지(Edge)를 사용하여 **데이터 간 관계를 그래프로** 표현합니다.
   * 대표 예시: **Neo4j**, Amazon Neptune 등.
   * SNS(소셜 네트워크), 추천 시스템, 경로 탐색 등 **관계 중심**의 쿼리가 빈번한 환경에서 뛰어난 성능을 보입니다.
   * RDB에서 복잡한 조인을 여러 번 거쳐야 하는 상황을 그래프 모델에서는 짧은 탐색(Traversal)로 해결할 수 있습니다.
5. **특징 요약**
   * **유연한 스키마**: 스키마리스(schema-less) 혹은 스키마가 굉장히 유연하여, 데이터 구조 변경에 대한 부담이 적습니다.
   * **수평 확장 용이**: 대부분 분산 환경을 고려하여 설계되었기 때문에, 노드를 쉽게 추가·제거할 수 있습니다.
   * **BASE 모델**: 전통적인 ACID 대신, 가용성과 확장성을 중시하는 BASE(Basically Available, Soft state, Eventually consistent) 원리에 초점을 맞춥니다.

NoSQL 데이터베이스는 2000년대 후반, **빅데이터와 대규모 트래픽 처리를 요구하는 웹 서비스**들이 부상하면서 널리 알려지기 시작했습니다. 트랜잭션 무결성보다는 데이터 양과 속도에 초점을 맞춘 환경에서 특히 강점을 발휘합니다.



## 2. 차이점

* **고정 스키마 vs 유연한 스키마**
  * RDB는 **엄격한 스키마**를 두고, 모든 데이터가 일관된 형식을 가져야 합니다.
  * NoSQL은 대부분 **스키마리스**(또는 매우 유연한 스키마) 접근을 취해, 필드의 존재 유무나 자료형 변화에 빠르게 대처할 수 있습니다.
* **관계 중심 vs 설계 유연성**
  * RDB는 여러 테이블 간의 관계를 **정규화**하여 무결성을 높이는 방식입니다.
  * NoSQL은 **한 문서(혹은 레코드)에 많은 데이터를 중첩 구조로 넣는** 방식을 통해, 조인을 최소화하고 조회 속도를 높이는 패턴을 자주 사용합니다.
* **데이터 액세스 방식**
  * RDB는 **SQL 쿼리**를 통해 원하는 데이터를 다수의 테이블에서 조합해 가져옵니다.
  * NoSQL은 **직접 문서나 키로 접근**하거나, 분산 환경에서 샤드(Shard) 또는 파티션에 따라 데이터를 검색하는 방식을 사용합니다.
  * 복잡한 JOIN 연산은 애플리케이션 레벨에서 직접 구현해야 하는 경우가 많습니다.
* **확장성과 분산 처리**
  * 전통적으로 RDB는 **수직 확장(Scale-up)** 방식에 익숙했지만, 최근에는 샤딩(Sharding)을 통한 \*\*수평 확장(Scale-out)\*\*도 지원합니다. 다만 구조가 복잡하고 관리 포인트가 많습니다.
  * NoSQL은 처음부터 **수평 확장**을 염두에 두고 설계된 경우가 많아, 노드 추가를 통한 확장이 상대적으로 용이합니다.



## 3. 스키마 설계

#### 1) RDB의 스키마 설계

관계형 데이터베이스(RDB)에서는 **스키마가 매우 중요**합니다. 스키마(Schema)는 테이블 구조, 컬럼 이름과 타입, 제약 조건(Constraints) 등을 사전에 정의해두는 것을 의미하며, 모든 데이터는 이 스키마에 맞춰 저장됩니다. 아래는 RDB 스키마 설계 시 고려해야 할 핵심 요소들입니다.

1. **정규화(Normalization)**
   * RDB에서 스키마 설계를 할 때 가장 먼저 떠오르는 개념이 **정규화**입니다.
   * 데이터 중복을 최소화하고, 무결성(Integrity)을 높이기 위해 테이블을 세분화하고 관계(관계형 모델)를 통해 연결합니다.
   * 예: `사용자(Users)`, `주문(Orders)`, `제품(Products)`, `주문_상세(OrderItems)` 등을 각각 테이블로 분리하고, `user_id`, `order_id` 등의 외래 키(Foreign Key)로 연결합니다.
2. **관계 설정(참조 무결성, 외래 키 등)**
   * RDB는 PK(Primary Key), FK(Foreign Key), Unique, Not Null 등 **여러 가지 제약 조건**을 통해 데이터 무결성을 엄격히 보장합니다.
   * 예: “주문” 테이블의 `user_id` 컬럼은 반드시 “사용자” 테이블의 `id` 값을 참조해야 하며, 만약 “사용자”가 삭제된다면, 연결된 주문 정보도 어떻게 처리할지(cascade, restrict 등) 설계 시 결정해야 합니다.
3. **데이터 타입 선정**
   * 각 컬럼에 어떤 데이터 타입을 사용할지도 매우 중요합니다.
   * 문자열 컬럼이면 `VARCHAR`인지, 고정 길이 `CHAR`인지, 숫자 컬럼이면 `INT`, `BIGINT`, `DECIMAL` 등을 어떻게 설정할지, 날짜/시간 `DATE`, `TIMESTAMP` 등을 사용할지 등등, 잘못된 타입 선택은 나중에 성능 이슈나 저장소 낭비를 초래할 수 있습니다.
4. **인덱싱(Indexes)**
   * 스키마 설계 시, **인덱스**도 함께 고려해야 합니다.
   * RDB에서 인덱스는 쿼리 성능에 큰 영향을 주므로, 자주 조회되는 칼럼이나 JOIN에 활용되는 FK 컬럼 등에 적절히 인덱스를 생성해야 합니다.
   * 하지만 인덱스를 너무 많이 생성하면 쓰기(Insert/Update) 성능이 떨어질 수 있으므로 균형점을 잡아야 합니다.
5. **장점**
   * 스키마가 명확하고 구조가 엄격하므로, 데이터 무결성 및 품질을 유지하기 쉽습니다.
   * 업무 로직과 데이터 설계가 긴밀하게 연결되어 있으면, 트랜잭션 관리 및 복잡한 비즈니스 규칙 구현이 용이합니다.
6. **단점**
   * 스키마 변경(ALTER TABLE 등)이 빈번하면, 테이블 구조 수정, 마이그레이션 스크립트 작성, 다운타임 고려 등이 필요해 **유연성이 떨어집니다**.
   * 데이터가 매우 자주 바뀌거나, 구조가 명확히 정의되지 않은 데이터를 다룰 경우, 정규화된 설계가 오히려 불편할 수 있습니다.

***

#### 2) NoSQL의 스키마 설계(또는 스키마리스)

NoSQL은 ‘Not only SQL’이라는 이름처럼, **관계형 모델을 벗어나 다양한 스키마 방식을 채택**합니다. 대표적으로 문서(Document)형 DB(MongoDB 등)를 예로 들어 살펴보겠습니다.

1. **스키마리스(Schema-less) 혹은 유연한 스키마**
   * 문서형 DB의 경우, 각 \*\*문서(Document)\*\*가 JSON 혹은 BSON 형태로 저장되며, 테이블 구조와 유사한 “컬렉션(Collection)”에 문서를 넣지만, 각 문서마다 필드가 달라도 에러가 발생하지 않습니다.
   * 예: “사용자” 컬렉션 안에 `username`, `email` 필드를 갖는 문서가 있는가 하면, 다른 문서에는 `phone_number` 필드만 있을 수도 있습니다.
2. **비정규화(Denormalization)**
   * RDB와 달리, NoSQL은 **JOIN 연산이 제한적**이거나 비용이 크게 드는 경우가 많습니다.
   * 따라서 자주 함께 조회되는 데이터를 **한 문서 안에 중첩(Nested)시켜두거나, 필요한 정보를 중복 저장**하는 비정규화 전략을 흔히 사용합니다.
   * 예: “주문” 문서에 “사용자 정보”와 “주문 상세(제품 목록, 가격, 수량, 옵션 등)”를 **모두** 넣어서, 한 번의 조회로 필요한 정보를 다 가져오도록 설계할 수 있습니다.
3. **스키마 제약은 애플리케이션 레벨에서**
   * NoSQL이라고 해서 “무조건 아무 구조나 넣어도 된다”는 것은 아닙니다.
   * 실제로 서비스 운영 시에는 문서 구조가 서로 달라지면 애플리케이션 레벨에서 처리 로직이 복잡해질 수 있으므로, “어떤 필드는 필수, 어떤 필드는 옵션” 같은 룰을 **애플리케이션 레벨**에서 관리해야 합니다.
   * 일부 NoSQL(예: MongoDB의 schema validation)에서는 컬렉션 단위로 스키마를 정의할 수도 있습니다.
4. **장점**
   * 데이터 구조가 자주 바뀌거나, 일정하지 않은 반정형/비정형 데이터를 다룰 때 **매우 유연**합니다.
   * 비정규화를 통해 **JOIN 없이 빠른 조회**가 가능합니다.
   * 확장성이 좋아, 분산 환경에서 컬렉션(또는 다른 스토리지 단위)를 샤딩하고 노드를 쉽게 추가할 수 있습니다.
5. **단점**
   * 스키마가 자유롭다는 것은 곧 **무결성 확보를 위해 개발자가 더 많은 책임**을 져야 함을 의미합니다.
   * 비정규화된 데이터는 중복이 많아, 업데이트 시 여러 곳을 수정해야 할 수 있고, 잘못 관리하면 데이터 불일치가 발생할 위험이 있습니다.
   * JOIN, 트랜잭션 등의 전통적인 RDB 기능을 그대로 기대하기 어려울 수 있습니다(일부 NoSQL은 트랜잭션 지원을 제한적으로 제공).



## 4. 정규화, 비정규화

#### 1) 정규화(Normalization)의 개념 및 목적

**1. 정의**

* 정규화(Normalization)는 **데이터 중복을 최소화**하고, 데이터 무결성(Integrity)과 일관성(Consistency)을 **보장**하기 위해 테이블(또는 스키마)을 체계적으로 구조화하는 과정입니다.
* 전통적으로 **관계형 데이터베이스(RDB)** 설계에서 매우 중요한 설계 패턴이며, 1차 정규형(1NF)부터 5차 정규형(5NF)까지 다양한 단계가 있습니다.

**2. 목적 및 효과**

1. **데이터 중복 제거**
   * 같은 데이터를 여러 테이블에 중복해서 저장하지 않고, 하나의 사실(Fact)은 하나의 테이블에만 저장하려고 합니다.
   * 예: “사용자 정보”는 “사용자” 테이블에만 저장하고, “주문” 테이블에는 사용자 ID(FK)만 참조하는 식입니다.
   * 중복 데이터가 줄어들면, 저장 공간이 절약되고, 수정 시 여러 곳을 고칠 필요가 없어 **정합성 문제**가 줄어듭니다.
2. **무결성(Integrity) 보장**
   * PK(Primary Key), FK(Foreign Key), UNIQUE, NOT NULL 등 **제약 조건**과 함께 정규화를 진행하면, 잘못된 데이터(중복, 불일치)가 들어올 여지를 최소화할 수 있습니다.
3. **업데이트 이상(Anomaly) 방지**
   * 삽입 이상(Insertion Anomaly), 갱신 이상(Update Anomaly), 삭제 이상(Deletion Anomaly) 등을 막는 효과가 있습니다.
   * 예: 갱신 이상은 특정 데이터가 여러 곳에 중복되어 있을 때, 한 곳만 업데이트되어 나머지는 예전 정보를 유지해 **데이터 불일치**가 생기는 상황을 의미합니다.
4. **데이터 모델 단순화**
   * 명확하게 테이블을 나누고, 각 테이블이 담당하는 역할을 분리함으로써, 전체적으로 구조가 이해하기 쉬워집니다.

**3. 예시 (간단한 시나리오)**

* **사용자(Users)** 테이블: `user_id (PK), username, email, phone` 등
* **제품(Products)** 테이블: `product_id (PK), product_name, price, category` 등
* **주문(Orders)** 테이블: `order_id (PK), user_id (FK), order_date, total_amount` 등
* **주문\_상세(OrderItems)** 테이블: `order_id (FK), product_id (FK), quantity, unit_price` 등

위 구조는 정규화가 잘된 전형적인 RDB 스키마 예시입니다. “주문”과 “제품” 정보가 서로 다른 테이블에 있고, “주문\_상세”는 다(N)대다(M) 관계를 연결해주는 중간 테이블로 작동합니다.

**4. 장단점**

* **장점**
  1. **데이터 품질 향상**: 중복 제거로 데이터 정합성이 높아집니다.
  2. **변경 용이성**: 특정 테이블(영역)의 데이터 구조만 변경해도 전체 DB 구조에 큰 영향이 없습니다.
  3. **무결성 강화**: RDB에서 트랜잭션 및 제약 조건과 함께 안전하게 데이터 관리 가능.
* **단점**
  1. **JOIN이 많아질 수 있음**: 데이터가 여러 테이블에 나눠져 있으니 조회 시 복잡한 JOIN이 필요합니다.
  2. **쓰기 성능 저하**: 관계가 복잡해질수록 INSERT/UPDATE할 때 참조 무결성 등 제약을 확인해야 하므로 부담이 증가할 수 있습니다.
  3. **분산 환경(샤딩 등)에서 복잡성 증가**: 여러 테이블에 데이터를 분산 저장하다 보니 샤딩된 환경에서 JOIN 처리 등이 어려워집니다.

***

#### 2) 비정규화(Denormalization)의 개념 및 목적

**1. 정의**

* 비정규화(Denormalization)는 **조회(쿼리) 성능 최적화** 또는 **분산/확장성 요구사항** 때문에, **의도적으로 테이블(또는 문서)에 중복된 데이터를 허용**하거나 **정규화를 일부 포기**하는 전략입니다.
* 주로 **NoSQL** 환경(문서형 DB, 컬럼 패밀리 DB)에서 많이 언급되지만, 관계형 DB에서도 특정 상황(고성능 요구)에서 적용하기도 합니다.

**2. 목적 및 효과**

1. **빠른 조회성능**
   * 정규화된 테이블 구조에서는 여러 JOIN을 해야 하는 상황을, 비정규화로 인해 **한 테이블(또는 문서)에 필요한 데이터가 이미 중첩**되어 있어, **단일 쿼리**로 빠르게 가져올 수 있습니다.
   * 특히 NoSQL 문서형 DB(MongoDB 등)에서 한 문서에 많은 정보를 담아두면, JOIN 없이도 즉시 조회가 가능해집니다.
2. **분산 시스템 적합성**
   * 데이터가 여러 노드에 분산된 환경에서, JOIN 연산을 최소화하여 **노드 간 통신**을 줄일 수 있습니다.
   * 예: Cassandra나 DynamoDB 등에서는, 자주 조회되는 데이터를 **테이블(또는 컬럼 패밀리)을 복제**해 두기도 합니다.
3. **쓰기 부하 분산**
   * 일부 시나리오에서는 중복된 데이터를 여러 테이블에 나눠 써서, 특정 테이블이나 노드에만 부하가 몰리지 않도록 하는 전략을 쓰기도 합니다.

**3. 예시 (간단한 시나리오)**

* **주문(Orders)** 문서(또는 테이블)에 “사용자 정보”와 “주문 상세”를 모두 넣는 경우
  *   예:

      ```json
      {
        "order_id": 12345,
        "user": {
          "user_id": 1,
          "username": "John",
          "email": "john@example.com"
        },
        "items": [
          {"product_id": 10, "product_name": "Shoes", "quantity": 2, "price": 50000},
          {"product_id": 12, "product_name": "Socks", "quantity": 5, "price": 2000}
        ],
        "order_date": "2025-01-31",
        "total_amount": 110000
      }
      ```
  * 이렇게 하면 주문 문서만 조회해도 사용자 정보와 아이템 정보 등을 **모두** 얻을 수 있어, RDB처럼 JOIN을 수행할 필요가 없습니다.

**4. 장단점**

* **장점**
  1. **조회 성능 향상**: 여러 테이블/컬렉션을 조회하는 대신, 한 번에 데이터를 가져올 수 있음.
  2. **분산 처리 최적화**: 노드 간 JOIN이나 복잡한 쿼리를 최소화해 확장성을 높임.
  3. **개발 단순화**: 애플리케이션 로직에서 JOIN 로직을 구현할 필요가 줄어듦(또는 아예 사라짐).
* **단점**
  1. **데이터 무결성 유지 어려움**: 같은 정보가 여러 곳에 복제되어 있기 때문에, 수정 시 동기화가 잘 안 되면 데이터 불일치가 발생할 수 있음.
  2. **저장 공간 증가**: 중복이 발생하므로 스토리지 사용량이 늘어날 수 있음.
  3. **복잡한 업데이트 로직**: 어떤 필드를 변경할 때, 관련된 모든 비정규화된 위치를 찾아서 업데이트해야 하는 부담이 생김.

***

#### 3) RDB vs NoSQL에서의 정규화/비정규화 활용

1. **RDB**
   * 전통적으로 **정규화**가 기본입니다.
   * 다만 대규모 트래픽 환경에서 특정 테이블 조회 빈도가 높아지는 경우, \*\*의도적으로 비정규화 테이블(또는 인덱싱, Materialized View 등)\*\*을 두기도 합니다.
   * 예: “사용자 + 부가 정보”를 자주 조회한다면, 정규화된 테이블 외에 “사용자+부가정보 뷰” 또는 “캐싱 테이블”을 만들어 관리하기도 합니다.
2. **NoSQL**
   * 태생적으로 **비정규화** 전략을 선호합니다. 특히 문서형 DB에서는 “1:N 관계”를 문서 내 **배열(array) 또는 중첩(nested) 구조**로 넣어 한 번에 조회하는 경우가 많습니다.
   * 컬럼 패밀리 DB(Cassandra 등)에서도 “넓은 행(Wide Row)” 구조로 여러 데이터를 한 행에 몰아넣거나, 읽기 패턴별로 테이블을 중복 생성하기도 합니다.
   * 중요한 점은 **트랜잭션이나 정합성** 이슈를 어떻게 애플리케이션 레벨에서 처리하느냐입니다.

***

#### 4) 실무 시 고려해야 할 사항

1. **업데이트 빈도와 조회 패턴 분석**
   * 어떤 데이터가 얼마나 자주 바뀌는가? 자주 바뀌는 필드를 여러 곳에 중복해두면, 업데이트 비용이 급증할 수 있습니다.
   * 어떤 데이터가 얼마나 자주 조회되는가? 조회 패턴이 집중되는 부분은 비정규화를 통해 속도 향상을 도모할 수 있습니다.
2. **데이터 일관성 전략**
   * 비정규화로 인해 발생할 수 있는 **데이터 불일치**를 어떻게 해소할지 미리 설계가 필요합니다.
   * RDB에서 트리거(Trigger)나 저장 프로시저(Stored Procedure)로 업데이트를 자동화하는 방안, NoSQL에서 애플리케이션 레벨 로직으로 여러 문서를 동시에 수정하는 방안 등이 있습니다.
3. **운영/유지보수 난이도**
   * 정규화로 인해 JOIN이 많으면, 쿼리가 복잡해지고 성능 튜닝이 필요해집니다.
   * 비정규화가 많아지면, 업데이트 및 유지보수 로직이 복잡해질 수 있습니다.
   * “어디까지 정규화하고, 어디까지 비정규화할지”는 \*\*프로젝트 성격(트래픽 규모, 업데이트 패턴, 개발 인력의 경험, 운영 환경 등)\*\*에 따라 트레이드오프를 고려해 결정해야 합니다.
4. **클라우드/분산 환경에서의 접근**
   * 클라우드 DB 서비스(AWS DynamoDB, Azure Cosmos DB 등)은 기본적으로 NoSQL 비정규화가 권장되는 경우가 많습니다.
   * 클라우드 RDB(예: AWS Aurora, Azure SQL 등)에서도, 특정한 성능 요구가 있다면 **물리적 파티셔닝**이나 **비정규화된 인덱싱/머티리얼라이즈드 뷰** 등을 활용할 수 있습니다.

***

#### 5) 결론 및 요약

* **정규화(Normalization)**
  * **데이터 무결성, 중복 제거, 체계적 스키마**가 목표
  * RDB에서 기본적으로 권장되는 설계 방식
  * JOIN 연산 증가, 대규모 분산 환경에서 구조가 복잡해질 수 있음
* **비정규화(Denormalization)**
  * **조회 성능 향상**, **분산 시스템 최적화** 등의 목적
  * NoSQL에서 흔히 사용하며, RDB에서도 특정 상황(캐싱 테이블, 머티리얼라이즈드 뷰)에서 적용
  * 데이터 중복으로 인한 무결성, 업데이트 복잡도 이슈를 관리해야 함

면접에서 이 주제를 다룰 경우, “정규화를 어디까지 적용하고, 비정규화를 어느 정도로 허용할 것인가?”라는 질문에는 **케이스 바이 케이스**로 답변하는 것이 중요합니다. 예컨대, 트랜잭션 성격이 강하고 변경이 빈번하지 않은 업무(금융, 회계 등)는 정규화가 중요하고, 로그/세션/콘텐츠처럼 조회 빈도가 매우 높고 구조가 자주 바뀌는 데이터는 비정규화(혹은 NoSQL) 접근이 유리하다는 식으로 **구체적 예시를 들어** 설명하면 설득력이 높아집니다.
