콘텐츠로 이동

데이터를 제자리에 두라

28개 언어로도 제공

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

Two identical drawers on a workbench, seen from above: one jammed with everything mixed together, one divided so each kind of thing has its own compartment.
AI로 생성한 이미지

Data Architect 과정 2장인 의미를 위한 데이터 모델링의 모듈 4/6. 각 모듈은 독립적으로 읽을 수 있습니다. 이전: 논리 모델을 만들어라 · 다음: 제3정규형까지 설계하고, 한 발 물러서라

이 모듈이 답하는 질문: 정규화는 데이터가 실제로 어디에 속하는지 알아내는 데 어떻게 도움이 될까요?

이제 논리 모델이 있습니다. 엔터티, 관계, 속성, 키. 이제 데이터 모델링에서 가장 중요한 질문 하나를 던지려 합니다. 이 데이터가 정말 여기에 속하는가?

간단하게 들립니다. 그렇지 않습니다. 저는 누군가 만들 때는 모든 필드가 말이 됐던 시스템을 수없이 보았습니다. 문제는 필드가 터무니없다는 게 아니었습니다. 사실이 엉뚱한 곳에 저장되어 있다는 것이었습니다. 배송이 실제로는 물류 센터를 기술하는 정보를 담고 있습니다. 같은 주소가 수백 개 레코드에 나타납니다. 필드 하나에 쉼표로 구분된 값 세 개가 들어 있습니다. 비즈니스 사실 하나가 바뀌면 레코드 1만 건을 갱신해야 합니다. 그것이 정규화가 풀도록 도와주는 문제이고, 데이터베이스 용어에 파묻히기 전에 전체 아이디어를 먼저 말하겠습니다. 사실을 제자리에 두라. 이 모듈의 나머지는 모두 그것을 더 체계적으로 하도록 돕습니다.

정규화는 각 사실이 한 번, 자기가 속한 곳에 저장되도록 데이터를 구성하는 것입니다. 테이블 하나가 너무 많은 일을 하고 있으면, 각각 한 가지를 기술하는 테이블들로 나누고 키로 연결합니다.

왜 굳이 그럴까요? 한 번 저장된 사실은 한 번만 바꾸면 되기 때문입니다. 정규화는 같은 사실이 여러 레코드에 복사되는 중복을 막고, 그와 함께 사본 하나는 갱신되고 나머지는 갱신되지 않을 때 스며드는 불일치도 막습니다. 그래서 정규화는 레코드가 하루 종일 만들어지고 갱신되는 Salesforce 같은 트랜잭션 시스템에 잘 맞습니다.

정규화는 정규형이라는 단계로 진행하며, 각 단계는 질문 하나를 던집니다.

  • 제1정규형(1NF): 필드마다 값 하나, 그리고 모든 행을 고유하게 식별하는 무언가.
  • 제2정규형(2NF): 모든 사실이 행을 식별하는 것의 일부가 아니라 전체를 기술한다.
  • 제3정규형(3NF): 모든 사실이 이 대상을 기술하지, 그것과 관련된 다른 무언가를 기술하지 않는다.

제3정규형 너머에도 정규형이 더 있습니다. 그것들과, 우리가 보통 제3정규형에서 멈추는 이유는 뒤에서 한마디 하겠습니다. 먼저 세 단계가 실제로 일어나는 것을 지켜봅시다.

이것을 강의실에서 가르칠 때 저는 배송으로 시작하지 않습니다. 개로 시작합니다. 개는 누구나 이해하니 비즈니스 때문에 산만해지는 사람이 없고, 데이터가 자기 집을 찾아가는 모습을 지켜볼 수 있습니다. 그다음 같은 동작을 Steve Trucking에 가져갑니다.

시작: 날것의 스프레드시트. 제가 화면에 개 두어 마리를 올리면, 수강생들이 자기 개를 보탭니다. 몇 분 만에 큰 목록 하나가 생깁니다. 개(Dog), 태어난 해, 주인(Owner), 주인이 사는 곳, 품종(Breed), 그 개를 번식시킨 브리더(Breeder), 그리고 그 개가 아는 재주(Trick).

개출생 연도주인우편번호도시품종브리더재주
벨라2017마커스80202덴버래브라도메이플 리지앉아, 기다려, 손
마일로2019마커스80202덴버푸들골든 메도앉아, 굴러
맥스2022아나64105캔자스시티믹스앉아, 죽은 척
루나2020켄지98101시애틀허스키캐스케이드앉아, 기다려, 돌아
로키2024프리야30301애틀랜타비글메이플 리지앉아
코코2014아나64105캔자스시티치와와리틀 포즈손, 돌아

작동합니다. 모든 스프레드시트는 첫날엔 작동합니다. 하지만 이미 무엇이 잘못됐는지 보십시오. “손”을 아는 개를 전부 어떻게 찾을까요? 아나의 우편번호가 두 행에 있고, 마커스의 것도 그렇습니다. 누군가 하나는 고치고 다른 하나는 안 고치면 어떻게 될까요? 메이플 리지가 두 번 나오고, 캔자스시티도 두 번 나옵니다. 그리고 맥스는 유기견 보호소에서 왔으니 브리더가 아예 없습니다.

1단계: 제1정규형. 규칙은 둘입니다. 각 필드는 값 하나만 담는다. 그러니 쉼표로 나열한 재주 목록은 없어져야 합니다. 그리고 각 행에는 그것을 고유하게 식별하는 무언가가 필요하다. 개 이름은 아닙니다. 맥스라는 개는 정말 많습니다. ID입니다. 자동 생성된 ID나 GUID. 재주는 각자의 행으로 빠져나와, 개와 재주 하나마다 행이 하나씩 생깁니다. 그리고 재주에 자기 행이 생기면, 쉼표 목록으로는 결코 말할 수 없던 것을 담을 자리가 생깁니다. 그 재주가 얼마나 어려운지, 이 개가 얼마나 잘하는지, 언제 배웠는지.

개 (개 ID로 식별)

개 ID이름출생 연도주인우편번호도시품종브리더
D-001벨라2017마커스80202덴버래브라도메이플 리지
D-002마일로2019마커스80202덴버푸들골든 메도
D-003맥스2022아나64105캔자스시티믹스
D-004루나2020켄지98101시애틀허스키캐스케이드
D-005로키2024프리야30301애틀랜타비글메이플 리지
D-006코코2014아나64105캔자스시티치와와리틀 포즈

개 재주(Dog Trick) (개 ID + 재주로 식별)

개 ID재주난이도숙련도배운 시기
D-001앉아쉬움능숙2017-11
D-001기다려쉬움능숙2018-01
D-001손보통잘함2018-06
D-002앉아쉬움능숙2020-02
D-002굴러어려움배우는 중2023-05
D-003앉아쉬움잘함2022-06
D-003죽은 척어려움배우는 중2024-03
D-004앉아쉬움능숙2020-11
D-004기다려쉬움잘함2021-01
D-004돌아보통능숙2021-06
D-005앉아쉬움배우는 중2025-02
D-006손보통능숙2015-06
D-006돌아보통배우는 중2025-04

이제 “손을 아는 개 전부”는 간단한 질문입니다. 하지만 개 재주를 무엇이 식별하는지 보십시오. 하나가 아니라 두 가지를 합친 것, 개와 재주입니다. 이걸 기억해 두십시오.

2단계: 제2정규형. 제2정규형은 행이 조합으로 식별될 때만 의미가 있고, 개 재주가 바로 그렇습니다. 그래서 모든 열에 묻습니다. 이것은 조합 전체를 기술하는가, 일부만 기술하는가? 숙련도는 이 개가 이 재주를 하는 것을 기술합니다. 벨라는 “앉아”에 능숙하고, 로키는 아직 배우는 중입니다. 배운 시기도 마찬가지입니다. 그런데 난이도는요? “앉아”는 어느 개가 하든 쉽습니다. 난이도는 키의 일부인 재주만 기술하고, 그래서 “쉬움”이 “앉아” 행마다 반복됩니다. 그러니 재주는 자기 테이블을 갖고, 남는 것은 그 쌍입니다.

재주

재주 ID재주난이도
T-01앉아쉬움
T-02기다려쉬움
T-03손보통
T-04굴러어려움
T-05죽은 척어려움
T-06돌아보통

개 재주 (개 ID + 재주 ID)

개 ID재주 ID숙련도배운 시기
D-001T-01능숙2017-11
D-001T-02능숙2018-01
D-001T-03잘함2018-06
D-002T-01능숙2020-02
D-002T-04배우는 중2023-05
D-003T-01잘함2022-06
D-003T-05배우는 중2024-03
D-004T-01능숙2020-11
D-004T-02잘함2021-01
D-004T-06능숙2021-06
D-005T-01배우는 중2025-02
D-006T-03능숙2015-06
D-006T-06배우는 중2025-04

그 개 재주 테이블은 모듈 2에서 찾았던 바로 그것이고, 데이터 모델링에서는 이름이 있습니다. 연결(junction), 제 표현으로는 논리적 연결 개체입니다. 개 한 마리는 여러 재주를 알고, 재주 하나는 여러 개가 압니다. 연결 개체는 그 사이에 있고, 속이 빈 배관이 아닙니다. 관계 자체에 속하는 사실, 즉 숙련도와 날짜를 담습니다. 모듈 6에서 다시 만나고, 3장에서는 Salesforce가 “junction object”라는 말을 더 좁게 쓴다는 것을 보게 됩니다. **Salesforce 연결 개체(Salesforce Junction Object)**는 마스터-세부 사항 관계 두 개를 가진 사용자 정의 개체입니다(3장, 모듈 7).

3단계: 제3정규형. 이제 개 테이블로 돌아갑니다. 여기 있는 모든 것은 개 ID로 식별되니, 제2정규형은 할 말이 없습니다. 제3정규형은 다른 질문을 던집니다. 이 사실은 개를 기술하는가, 개와 관련된 다른 무언가를 기술하는가? 품종은 그 자체로 하나의 대상입니다. 래브라도는 어느 개든 래브라도이고, 크기 같은 품종에 대한 사실은 벨라가 아니라 품종에 속합니다. 우편번호와 도시는 개가 아니라 주인을 기술합니다. 어느 개를 보든 그것은 아나가 사는 곳입니다. 브리더의 정보는 브리더를 기술합니다. 이것들은 각각 다른 사실에 대한 사실이므로, 각자 자기 테이블로 옮기고, 개는 외래 키로 그것을 가리킵니다.

  • 개: 개 ID, 이름, 출생 연도, 주인 ID, 품종 ID, 브리더 ID
  • 주인: 주인 ID, 이름, 우편번호, 도시
  • 품종: 품종 ID, 품종, 크기
  • 브리더: 브리더 ID, 이름, 도시
  • 2단계에서 만든 재주와 개 재주

이제 아나는 한 번만 저장되고, 그녀의 두 개가 모두 그녀를 가리킵니다. 메이플 리지도 한 번만 저장되고, 품종 테이블은 스프레드시트에는 둘 곳이 없던 각 품종에 대한 사실, 예를 들어 크기를 담을 집이 되어 줍니다. 외래 키는 비어 있을 수 있습니다. 맥스에게는 브리더 ID가 없고, 그것은 빈칸이 아니라 정직한 답입니다. 그다음 저는 수강생들에게 함정 질문을 던집니다. 주인이 개를 데려온 날짜는 어디에 둘까요? 개에 둡니다. 이 모델에서 개는 한 번에 주인이 한 명이니, 그 날짜는 개와 주인의 관계를 기술합니다.

한 단계 더 나아가 도시를 우편번호에서 떼어 낼 수도 있습니다. 교과서는 그렇게 합니다. 실무에서는 주소를 한데 묶어 두고, 어차피 캔자스시티는 두 주에 걸쳐 있습니다. 현실 세계는 우리 교과서를 읽지 않는다는 좋은 상기입니다.

그것이 진행 과정입니다. 스프레드시트 하나, 그다음 질문 세 개, 그리고 모든 사실이 한곳에 자리 잡습니다. 한 발 물러서서 우리가 만든 것을 보십시오. 지저분한 목록 하나가 각각 한 가지를 기술하고 키로 연결된 테이블 여섯 개가 되었습니다.

제3정규형 이후의 개 모델 상자 여섯 개가 선으로 이어져 있습니다. 주인은 개를 1마리 이상 소유합니다. 개는 주인이 하나이고, 하나의 품종에 속하며, 0명 또는 1명의 브리더가 번식시켰습니다(브리더는 개를 1마리 이상 번식시킵니다). 개와 재주 사이에 개 재주가 있습니다. 개는 개 재주를 0개 이상 알고, 재주는 0개 이상의 개 재주에서 습득되며, 각 개 재주는 정확히 하나의 개와 하나의 재주에 속합니다. 소유 번식 속함 앎 습득됨 주인 브리더 개 품종 개 재주 재주 정확히 하나 0개 또는 1개 1개 이상 0개 이상 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

그것을 따라오는 데 Salesforce 용어는 단 하나도 필요하지 않았습니다. 그저 개들과, 그 주변 사람들과, 개들이 아는 것뿐입니다.

이제 Steve Trucking에 적용해 보자

섹션 제목: “이제 Steve Trucking에 적용해 보자 ”

개는 그 동작들을 쉽게 보여 줍니다. 실제 비즈니스는 그것들을 중요하게 만듭니다. 같은 실수가 규모가 커지면 실제 돈이 들기 때문입니다. 그러니 같은 세 질문을 Steve Trucking에 가져갑시다. Steve Trucking이 배송을 이렇게 관리한다고 상상해 보십시오.

배송리테일 파트너물류 센터DC 도시배송팀트럭
1001KeystoneKeystone Phoenix DC피닉스배송팀 12117
1002KeystoneKeystone Phoenix DC피닉스배송팀 8122
1003KeystoneKeystone Phoenix DC피닉스배송팀 12117

얼핏 보면 복잡한 건 하나도 없습니다. 하지만 물류 센터를 보십시오. 그 DC에서 출발하는 배송마다 “Keystone Phoenix DC, 피닉스”를 반복합니다. Steve Trucking은 DC 아홉 곳에서 하루에 약 3,300건을 배송하니, DC마다 하루 수백 건입니다. 그 DC가 이전하면 어떻게 될까요? 레코드를 몇 건이나 바꿔야 하고, 하나를 놓치면 어떻게 될까요? 이제 데이터는 DC가 동시에 두 도시에 있다고 말합니다. 그것이 갱신 이상입니다. 첫 배송 전에 새 DC를 등록하고 싶다면요? DC의 마지막 배송을 삭제하면, 그 DC에 대해 저장했던 유일한 곳을 방금 지워 버린 걸까요?

이것들은 같은 문제의 서로 다른 증상입니다. 서로 다른 대상에 대한 사실을 섞어 놓았습니다. 물류 센터에 대한 사실은 물류 센터에 속합니다. 배송에 대한 사실은 배송에 속합니다. 배송팀에 대한 사실은 배송팀에 속합니다. 그것이 실무적으로 말한 정규화입니다.

제1정규형: 반복 구조를 숨기지 마라

섹션 제목: “제1정규형: 반복 구조를 숨기지 마라 ”

제1정규형, 즉 1NF부터 시작합시다. 사람들이 정규화를 필요 이상으로 어렵게 만들곤 하는 곳입니다.

배송에 품목(Items)이라는 필드가 있다고 해 봅시다. “냉장고, 제빙기 키트, 헌 제품 수거.” 필드 하나에 정보 세 가지를 넣었습니다. 편리해 보입니다. 누군가 “지난달 헌 제품 수거를 몇 건 했나요?”라고 묻기 전까지는요. 아니면 품목 1, 품목 2, 품목 3이라는 필드를 상상해 보십시오. 작동합니다. 품목이 네 개인 배송이 오기 전까지는요. 문제는 품목 필드 개수를 잘못 고른 게 아닙니다. 반복 구조를 알아보지 못한 것이 문제입니다. 배송에는 품목이 여러 개 있을 수 있습니다. 그것은 모델링해야 할 데이터입니다. 모듈 2에서 찾은 배송 품목입니다.

배송 품목을 담는 세 가지 방법 카드 세 장이 같은 배송의 품목을 세 가지 방식으로 저장한 모습을 보여 줍니다. 필드 하나: 배송 1001에 “냉장고, 제빙기 키트, 헌 제품 수거”라고 적힌 품목 필드가 있어, 지난달 헌 제품 수거가 몇 건이었는지 답하지 못합니다. 반복 필드: 품목 1 냉장고, 품목 2 제빙기 키트, 품목 3 헌 제품 수거로, 품목이 네 개인 배송을 담지 못합니다. 강조된 하위 레코드: 배송 1001에 배송 품목 세 개, 즉 냉장고, 제빙기 키트, 헌 제품 수거가 있고, 다음 품목은 새 필드가 아니라 새 레코드가 됩니다. 아래 메모: 무언가가 여러 번 일어날 수 있다면, 밖으로 나오려는 엔터티가 하나 더 있을 수 있습니다. 필드 하나 값 하나에 숨은 사실 세 가지 배송 1001 품목: 냉장고, 제빙기 키트, 헌 제품 수거 답하지 못하는 질문 지난달 헌 제품 수거는 몇 건? 반복 필드 품목 1, 품목 2, 품목 3 배송 1001 품목 1: 냉장고 품목 2: 제빙기 키트 품목 3: 헌 제품 수거 담지 못하는 배송 품목이 네 개인 배송 하위 레코드 품목마다 배송 품목 하나 배송 1001 배송 품목: 냉장고 배송 품목: 제빙기 키트 배송 품목: 헌 제품 수거 다음 품목 새 필드가 아니라 새 레코드 무언가가 여러 번 일어날 수 있다면, 밖으로 나오려는 엔터티가 하나 더 있을 수 있습니다. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

1NF의 실무 교훈은 이것입니다. 반복 구조를 필드 안에 숨기지 마십시오. 비즈니스가 무언가가 여러 번 일어날 수 있다고 말하면 귀 기울이십시오. 밖으로 나오려는 엔터티가 하나 더 있을 수 있습니다.

실제 org에서 늘 보게 될 겁니다. 누군가 설명을 여러 언어로 담아야 해서 Description_English라는 필드를 만들고, 그다음 Description_French, 그다음 Description_German을 만듭니다. 아니면 승인에 몇 사람이 필요해서 승인자 1, 승인자 2, 승인자 3이 생깁니다. 검토에서 그걸 발견하면, 손등 한 대 맞고 데이터 모델을 고치라고 합니다. 비즈니스에 정말 한두 개뿐이라면 한두 개는 괜찮을 수도 있습니다. 그 이상은 하위 개체여야 합니다. 언어를 가진 번역(Translation), 승인자를 가진 승인 단계(Approval Step). 다음 언어나 네 번째 승인자는 새 필드와 배포가 아니라 새 레코드가 됩니다.

제2정규형, 즉 2NF는 레코드가 여러 것의 조합으로 식별될 때 의미가 있습니다. 배송 품목을 보십시오. 자기 레코드 ID가 있지만, 각각은 배송 + 제품으로 고유합니다. 배송, 제품, 수량, 그리고 제품 설명을 저장한다고 해 봅시다.

수량은 여기서 말이 됩니다. 이 배송에 실린 이 제품을 기술하니까요. 하지만 제품 설명은 조합을 기술하지 않습니다. 제품을 기술합니다. 그것을 모든 배송 품목에 넣으면, 그 냉장고 모델이 다른 트럭에 실려 나갈 때마다 반복하게 됩니다. 그 사실이 다른 곳에 속한다는 단서입니다.

그래서 2NF의 질문은 이것입니다. 이 속성은 내가 식별하는 대상 전체를 기술하는가, 일부만 기술하는가? 제품만 기술한다면 제품에 둡니다. 이 특정 배송에서 그 제품이 차지하는 자리(수량, 설치 여부)를 기술한다면 배송 품목에 속합니다. 많은 관리자는 “지금 제2정규형을 적용하고 있어”라고 의식적으로 말할 일이 결코 없을 겁니다. 괜찮습니다. 저는 여러분이 이 질문을 던지는 법을 배우는 것이 훨씬 더 중요합니다. 이 사실은 실제로 무엇을 기술하는가?

제3정규형: 다른 사실에 대한 사실을 저장하지 마라

섹션 제목: “제3정규형: 다른 사실에 대한 사실을 저장하지 마라 ”

이제 일상적인 모델링에서 제가 가장 중요하게 여기는 것입니다. 제3정규형, 즉 3NF.

각 물류 센터에는 리테일 파트너 쪽 관리자가 있고, 그 사람은 파트너 포털을 씁니다. DC 관리자 이름을 모든 배송에 직접 넣는다고 해 봅시다. DC에 새 관리자가 오면 어떻게 될까요? 그 DC의 모든 배송을 갱신합니다. 또 그 냄새입니다. 다른 곳에 속하는 사실을 반복하고 있습니다. 배송은 DC에서 출발하고, DC에는 관리자가 있습니다. 관계가 두 개이고, 관리자 이름은 DC에 속합니다.

고전적인 교과서 버전은 주소입니다. 도시와 주는 보통 우편번호에서 정해지는데도, 우편번호, 도시, 주를 모든 레코드에 함께 저장합니다. 같은 모양, 같은 질문입니다.

다른 사실에 대한 사실: DC 관리자 두 패널입니다. 모든 배송에: 배송 레코드에 레코드 ID, 배송일, 물류 센터, 그리고 DC의 도시와 관리자가 있으며, 둘 다 반복된다고 표시되어 있습니다. DC에 한 번만 저장: 배송은 레코드 ID, 배송일, 물류 센터 ID를 가지고 물류 센터에서 출발하며, 물류 센터는 자기 레코드 ID, 이름, 도시, 관리자를 가집니다. 아래 메모: DC 관리자가 바뀌면 왼쪽은 수백 건을 갱신하고 오른쪽은 한 건을 갱신합니다. 모든 배송에 DC에 한 번만 저장 출발지 배송 배송 ID 레코드 ID 배송일 물류 센터 DC 도시 반복 DC 관리자 반복 배송 배송 ID 레코드 ID 배송일 물류 센터 ID 물류 센터 물류 센터 ID 레코드 ID 이름 도시 관리자 DC 관리자가 바뀌면 왼쪽은 수백 건을 갱신하고, 오른쪽은 한 건을 갱신합니다. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

3NF의 실무 질문은 이것입니다. 이 사실은 이 대상을 기술하는가, 이 대상과 관련된 다른 무언가를 기술하는가? 이 질문을 끊임없이 던지기를 바랍니다.

이제 개에서 했던 것처럼 한 발 물러서 보십시오. 처음 시작한 배송 테이블이 각자 자기 사실을 담은 다섯 가지가 되었습니다. 배송 품목은 제1정규형에서, 제품은 제2정규형에서 빠져나왔고, 물류 센터의 도시와 관리자는 제3정규형에서 물류 센터로 옮겨 갔습니다.

정규화 이후의 Steve Trucking 상자 다섯 개가 선으로 이어져 있습니다. 리테일 파트너는 물류 센터를 0개 이상 운영합니다. 배송은 정확히 하나의 물류 센터에서 출발하고 배송 품목을 1개 이상 포함합니다. 각 배송 품목은 정확히 하나의 제품이며, 제품은 0개 이상의 배송 품목에 등장합니다. 운영 출발지 포함 등장 리테일 파트너 배송 배송 품목 제품 물류 센터 정확히 하나 0개 또는 1개 1개 이상 0개 이상 © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

같은 세 질문, 같은 결과. 모든 사실이 한곳에.

1NF, 2NF, 3NF를 생각하는 간단한 방법

섹션 제목: “1NF, 2NF, 3NF를 생각하는 간단한 방법 ”

정규화만으로 데이터베이스 과정 하나를 통째로 채울 수도 있습니다. 우리는 그러지 않을 겁니다. 이 과정에서는 현업 아키텍트의 이해를 갖추기를 바랍니다.

  • 1NF: 필드나 레코드 안에 여러 값이나 반복 구조를 숨기고 있는가?
  • 2NF: 이 사실은 내가 식별하는 대상 전체를 기술하는가?
  • 3NF: 이 사실은 정말 이 엔터티를 기술하는가, 아니면 그것과 관련된 무언가를 기술하는가?

이것들은 데이터베이스 교과서용 정의가 아닙니다. 설계하면서 실제로 쓸 수 있는 질문입니다.

네, 정규화는 더 나아갑니다. **보이스-코드 정규형(BCNF)**은 더 복잡한 키를 가진 모델을 위해 3NF 주변의 규칙을 조이고, 제4, 제5, 심지어 제6정규형도 있습니다. 그것들은 더 드문 종류의 반복을 다루는데, 일상적인 비즈니스 레코드보다는 특이한 키 구조에서 생기는 반복입니다. 이론이 많고, 제 경험으로는 Salesforce 위에 짓는 종류의 시스템에서는 골치를 앓을 가치가 없습니다. 비즈니스 시스템에서는 압력이 보통 반대쪽으로 작용합니다. 제3정규형을 넘어서기보다는 사용자, 보고, 성능을 위해 제3정규형에서 물러설 가능성이 훨씬 큽니다. 그것이 다음 모듈입니다. 더 높은 정규형이 있다는 것은 알아 두되, 우리가 하는 일 대부분에는 1NF부터 3NF까지가 필요한 사고 도구를 줍니다.

제 입장은 이렇습니다. 비즈니스를 이해하고 그 논리 모델을 설계하려 할 때, 저는 깔끔하게 시작하고 싶습니다. 배송 사실은 배송에, 물류 센터 사실은 DC에, 트럭 사실은 트럭에, 반복되는 개념은 개념으로 모델링. 화면이나 보고서를 더 쉽게 만들지도 모른다는 이유만으로 비즈니스 사실을 모델 곳곳에 복사하고 싶지 않습니다. 아직은요.

하지만 정규화는 종교가 아닙니다. 목표는 학문적으로 가장 순수한 모델이 아닙니다. 저는 순수성에 너무 몰두한 나머지 그 모델을 써야 하는 모든 사람에게 고통이 되어 버린 아키텍트들을 보았습니다. 우리는 정규화 대회에서 이기려는 것이 아닙니다. 시스템을 만들고 있고, 그 시스템에는 사용자, 보고서, 연동, 성능 요구, 규모, 그리고 점점 더 데이터를 읽는 AI가 있습니다. 그것들은 데이터를 다른 모양으로 원할 수 있습니다.

그래서 제 출발점은 가능한 곳에서는 제3정규형까지 설계하고, 필요할 때 한 발 물러서라입니다. 먼저 각 사실이 어디에 속하는지 이해하십시오. 그다음, 거기서 벗어난다면 저는 이유를 알고 싶습니다. 답이 “필드를 달리 어디에 둘지 몰라서”라면 충분하지 않습니다. 답이 “파트너 성과표를 단순하게 만들려고 이 값을 일부러 복사했고, 동기화를 유지할 믿을 만한 방법이 있다”라면, 이제 아키텍처 대화를 하고 있는 겁니다.

아키텍트가 여기서 결정하는 것

섹션 제목: “아키텍트가 여기서 결정하는 것 ”

논리 모델을 정규화할 때, 저는 이런 것을 찾습니다.

  • 따로 모델링해야 할 반복 값이나 구조.
  • 저장된 곳과 다른 엔터티를 기술하는 속성.
  • 여러 레코드에 불필요하게 중복된 사실과, 그것들을 불일치하게 만드는 종속성.
  • 필드 안에 숨은 비즈니스 개념.
  • 구현상의 타협 이전에 진실을 표현하는 깔끔한 모델.

모든 물리 시스템이 완벽하게 정규화된 채로 있어야 해서가 아닙니다. 오히려 정반대입니다. 다음 모듈에서는 사용자, 보고, 규모, 분석, AI를 위해 깔끔한 모델에서 일부러 벗어날 것이고, 무엇을 맞바꾸는지 정확히 알고서 그렇게 할 것입니다.