800===Dev Docs and License/소프트웨어 아키텍쳐

AICC 콜센터 채팅 시스템의 데이터베이스 정규화 📌

블로글러 2025. 2. 15. 09:37

오늘은 AICC 콜센터 채팅 서비스를 설계한다고 가정하고, 데이터베이스 정규화(Database Normalization)를 단계별(1차 정규형, 2차 정규형, 3차 정규형 등)로 살펴보겠습니다. 콜센터 시스템에서도 채팅 로그, 상담사, 고객, 문의 정보 등이 서로 밀접하게 관련되어 있는데, 이를 효율적으로 저장하고 관리하기 위해 정규화 개념이 필수적으로 활용됩니다.


1. 1차 정규형(1NF)이란? 🤔

1.1 기본 개념

1차 정규형(1NF)반복되는 컬럼이나 컬럼 안에 여러 값이 들어 있는 상태를 제거하고, 각 컬럼을 원자값(Atomic value)만 갖도록 구성하는 것입니다.

  • 🔹 반복 컬럼 예시: ‘chat_message1’, ‘chat_message2’, ‘chat_message3’처럼 동일한 의미를 가진 컬럼이 여러 개 있는 경우.
  • 🔹 컬럼 안에 여러 값이 들어있는 예시: ‘chat_message’라는 칼럼 하나에 “(채팅 메시지, 전송 시간, 상담사 번호)”를 콤마(,)로 구분해 전부 넣어두는 경우.

1.2 AICC 콜센터 케이스

잘못된 설계 예시

아래처럼 “챗봇 로그” 테이블에 상담과 관련된 여러 정보를 한 컬럼에 몰아넣은 경우를 가정해봅시다.

chat_id messages
1 “(안녕하세요,2025-01-01 10:00,agentA);(무엇을 도와드릴까요?,2025-01-01 10:02,agentA);(계좌조회 문의입니다,2025-01-01 10:03,customer)”
2 “(…);(…); …”
  • messages 칼럼에 여러 메시지와 전송 시각, 보낸 사람 정보가 한꺼번에 들어 있습니다.
  • 메시지를 추가하거나 수정할 때 어디서부터 어디까지가 메시지 내용인지, 전송 시간인지, 상담사 정보인지 헷갈리기 쉽습니다.

1차 정규형 적용

  1. 반복되는 메시지 정보를 별도 테이블로 분리합니다.
  2. 각 칼럼이 하나의 원자값만 가지도록 설계합니다.

예시 테이블 구조:

CREATE TABLE ChatSession (
    chat_id INT PRIMARY KEY,        -- 채팅 세션 ID
    customer_id VARCHAR(50),        -- 고객 ID
    start_time DATETIME,            -- 채팅 시작 시간
    end_time DATETIME               -- 채팅 종료 시간
);

CREATE TABLE ChatMessage (
    message_id INT PRIMARY KEY,
    chat_id INT,                    -- 어떤 채팅 세션에 속하는지
    sender_type VARCHAR(10),        -- 'agent' 또는 'customer' 등
    message_content TEXT,           -- 실제 메시지 텍스트
    sent_time DATETIME,
    FOREIGN KEY (chat_id) REFERENCES ChatSession(chat_id)
);
  • 이제 각 메시지는 ChatMessage 테이블의 한 행(row)으로 표현되며, 메시지 내용, 보낸 주체(sender), 전송 시간 등을 각각의 칼럼에서 구분하여 보관합니다.
  • 1차 정규형을 통해 컬럼에 원자값만 저장하고, 반복 구간(메시지들)을 따로 테이블로 분리하여 관리가 훨씬 편리해집니다.

2. 2차 정규형(2NF)이란? 🤔

2.1 기본 개념

2차 정규형(2NF)은 1차 정규형을 만족하면서, 테이블이 복합 키(예: (A, B) 두 컬럼이 합쳐서 기본 키가 되는 경우)를 사용할 때, 부분 함수 종속(Partial Dependency)을 제거하는 단계입니다.

  • 부분 함수 종속이란? 복합 키(예: A, B) 중 일부 칼럼(A만)으로 다른 일반 칼럼(C)을 결정할 수 있는 종속성을 말합니다.

2.2 AICC 콜센터 케이스

콜센터 시스템에서는 예를 들어, (customer_id, chat_id)를 복합 키로 쓰는 테이블이 있을 수 있습니다. 만약 chat_id 하나로도 다른 일반 칼럼(예: 상담 시작 시간, 상담사 ID 등)을 결정할 수 있다면, 불필요하게 customer_id가 키에 묶여 있을 수 있습니다.

잘못된 설계 예시

아래 테이블에서 (customer_id, chat_id)가 복합 키라고 가정해봅시다.

customer_id chat_id chat_start_time agent_id 기타 칼럼들 …
cust001 10 2025-02-01 10:00 agentA ...
cust001 11 2025-02-01 11:00 agentB ...
  • 사실상 chat_id 하나만으로도 chat_start_time이나 agent_id 등은 유일하게 결정됩니다.
  • 하지만 복합 키 전체를 기본 키로 설정해 놓으면, customer_id라는 불필요한 종속성(부분 함수 종속)이 발생합니다.

2차 정규형 적용

테이블을 분리하거나, 진짜 PK(Primary Key)가 무엇인지 재조정합니다. 예를 들면, ChatSession 테이블에서 chat_id만 기본 키로 사용하고, customer_id는 일반 칼럼으로 두는 형태입니다.

-- ChatSession 테이블
CREATE TABLE ChatSession (
    chat_id INT PRIMARY KEY,
    customer_id VARCHAR(50),
    agent_id VARCHAR(50),
    chat_start_time DATETIME,
    chat_end_time DATETIME
    -- 기타 필요한 정보
);
  • 이렇게 하면, 복합 키 대신 chat_id만으로 다른 정보를 결정할 수 있으니, 부분 함수 종속이 사라집니다.
  • 2차 정규형은 주로 복합 키가 있는 테이블에서 등장하므로, “진짜 키가 무엇인가?”를 신중히 설계해야 합니다.

3. 3차 정규형(3NF)이란? 🤔

3.1 기본 개념

3차 정규형(3NF)2차 정규형을 만족하면서, 이행적 종속(Transitive Dependency)을 제거하는 단계입니다.

  • 이행적 종속: A → B이고 B → C가 성립할 때, A → C인 경우를 말합니다. 예: 키가 아닌 칼럼(B)이 또 다른 키가 아닌 칼럼(C)을 결정하는 상황.

3.2 AICC 콜센터 케이스

예를 들어, 상담사 테이블(Agent 테이블)에서 agent_id상담사 이름, 상담사 소속부서 등을 찾을 수 있다고 합시다. 그런데 소속부서가 다시 부서 정보(부서명, 부서장, 부서 위치 등)를 결정한다면, 이때가 이행적 종속이 발생하기 쉬운 구조입니다.

잘못된 설계 예시

하나의 테이블에 상담사 정보와 부서 정보를 전부 넣어놓은 경우:

agent_id agent_name department_name department_location department_contact
agentA 홍길동 고객지원부 서울 본사 02-1234-5678
agentB 김영희 고객지원부 서울 본사 02-1234-5678
  • 여기서 agent_iddepartment_namedepartment_location 구조가 생길 수 있습니다.
  • 만약 “고객지원부”의 위치가 바뀌면 해당 부서에 속한 모든 상담사 행을 수정해야 합니다.

3차 정규형 적용

이런 경우에는 부서 테이블을 따로 만들어서 관리하고, 상담사 테이블에서는 부서에 대한 참조(Foreign Key)만 갖도록 구성합니다.

CREATE TABLE Department (
    department_id INT PRIMARY KEY,
    department_name VARCHAR(50),
    department_location VARCHAR(100),
    department_contact VARCHAR(20)
);

CREATE TABLE Agent (
    agent_id VARCHAR(50) PRIMARY KEY,
    agent_name VARCHAR(50),
    department_id INT,   -- 부서 정보에 대한 FK
    FOREIGN KEY (department_id) REFERENCES Department(department_id)
);
  • 이제 상담사(Agent) 정보와 부서(Department) 정보가 이행적 종속 관계를 벗어나 독립적으로 관리됩니다.
  • 3차 정규형을 충실히 적용하면, 데이터 변경 시 중복 수정을 피하고, 데이터 무결성을 더욱 높일 수 있습니다.

4. BCNF(Boyce-Codd Normal Form) 🤔

4.1 기본 개념

BCNF는 3차 정규형보다 조금 더 엄격한 형태로, 모든 결정자(Determinant)가 후보 키(Candidate Key)여야 한다는 조건을 만족해야 합니다.

  • 즉, 키가 아닌 칼럼이 다른 칼럼을 결정하지 않도록 설계하는 것이라고 볼 수 있습니다.
  • 일반적으로 3NF만으로도 충분한 경우가 많지만, 특정한 복합키나 조합으로 인해 예상치 못한 종속성이 생기는 경우 BCNF를 고려합니다.

4.2 AICC 콜센터 케이스

  • 예를 들어, 콜센터에서 특정 ‘고객그룹’과 ‘상담유형’의 조합이 되면 자동으로 할당되는 상담사가 정해져 있다고 합시다.
  • “이 조합 → 상담사ID”라는 결정이 생기는데, 그 상담사ID가 또 다른 정보를 결정할 수 있다면 BCNF 위반이 발생할 수 있습니다.
  • 이 경우 중간 관계 테이블을 명확히 만들어서, “고객그룹, 상담유형”이 하나의 복합 후보 키가 되도록 설계하는 등의 방법을 쓸 수 있습니다.

5. 마치며 🎁

AICC 콜센터 채팅 서비스를 설계할 때,

  1. 1차 정규형으로 컬럼 원자화반복 구간 분리
  2. 2차 정규형으로 복합 키의 부분 종속 제거
  3. 3차 정규형으로 이행적 종속 제거
  4. 필요한 경우 BCNF까지 고려

를 통해, 데이터 중복갱신 이상, 삭제 이상, 삽입 이상 등의 문제를 방지할 수 있습니다. 물론 정규화를 지나치게 추구하면 JOIN 연산이 많아져 시스템 성능이 저하될 수 있으므로, 실제 콜센터 트래픽 특성(동시 접속자 수, 조회 vs. 입력 비율 등)을 면밀히 분석해 적절한 수준의 정규화를 적용하는 것이 중요합니다.

정리하면,

  • 정규화를 통해 데이터 구조가 명확해지고, 유지보수가 쉬워집니다.
  • 콜센터같이 실시간 조회가 많은 환경이라면, 상황에 따라 부분적인 비정규화(Denormalization)도 고려하여 성능을 최적화해야 합니다.

이처럼 데이터베이스 정규화를 잘 적용해두면, AICC 콜센터 서비스가 확장되더라도 채팅 로그, 상담사 정보, 부서 정보, 고객 정보 등의 스키마를 혼란 없이 관리하고, 시스템 안정성과 일관성을 높일 수 있을 것입니다.


참고 자료 및 출처

728x90