차 번호만 알면 내 전여친의 현남친의 포르쉐가 중고인지 신차인지 알 수 있는 것처럼, 정규형을 알면 DB 설계가 가능하다.(1NF, 2NF)
사람들은 보통 쿼리를 짤 때 JOIN 문법을 매우매우매우 어려워합니다.
이걸 왜하는지, 왜 테이블을 애초에 여러개로 나눠놓는거지? 이해도 안가고 세상아 덤벼라 반발심도 생길텐데요.
오늘 배우는 정규화/정규형을 배우면 매우매우 쉬워집니다. 배워두면 손해볼 것 없는 장사이니 잘 알아보도록 합시다.
제 1 정규형(1st normal form)
여러분은 지금부터 종합 운동센터 전산시스템을 만드는 개발자입니다.
일단 센터에 등록한 사람들을 테이블을 정리하고 싶습니다.
후딱 만들어보겠습니다.
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 |
10001 | 국성우 | 수영 |
10002 | 김태준 | 스쿼시 |
10003 | 양홍규 | 탁구 |
이렇게 만들어놨는데
갑자기 홍규가 수영도 재밌어보인다하여 수영을 다음날 추가 신청한겁니다. 그럼 어떻게 데이터를 추가할까요?
🤨 : 하나의 데이터 칸 안에 데이터를 더 추가하면 어떨까요?
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 |
10001 | 국성우 | 수영 |
10002 | 김태준 | 스쿼시 |
10003 | 양홍규 | 탁구,수영 |
이래도 되긴합니다.
근데 보통 이렇게 테이블을 만들어놓으면 성능이슈가 생길확률이 매우 높아집니다.
저렇게 한 칸에 많은 정보를 저장해두면 그 한칸에서 일부만 찾기/수정/삭제 작업이 느려지기 때문입니다.
여러분도 회사에서 사수가 만약 데이터 하나 추가해주세요했는데 저렇게 만들어 놓으면 여러분 맞선임부터 바로 줄빠따입니다.
실은 JSON 데이터 타입이 아니면 array 데이터타입(PostgreSQL에서 가능) 사용하면
[’탁구’, ‘수영’]
이런 식으로 여러개의 문자나 숫자를 한칸에 넣을 수 있는데 이래도 성능의 문제가 생기고 문제가 될 수 있습니다.
왜냐면 그냥 array, json은 문자와 취급이 비슷해 나중에 array 자료 안의 일부 항목만 수정하는게 매우 어렵기 때문입니다.(그래서 수정하고 싶으면 새 값으로 아예 갈아치우는 full refresh 형태로 많이합니다.)
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 |
10001 | 국성우 | 수영 |
10002 | 김태준 | 스쿼시 |
10003 | 양홍규 | 탁구 |
10003 | 양홍규 | 수영 |
⬆️ 그래서 이렇게 만드는게 낫습니다.
자 여러분 도 부 이 결 다 조! 기억나시나요!?
바로 여기서 정규화의 개념이 들어가는데요.
하나의 셀 안에는 무조건 하나의 데이터만 보관합니다. ⭐️ 이거 중요합니다. → 이 작업이 완료된 테이블을 제1정규형/정규화(1st Normal Form)라고 합니다.
이렇게 해두면 성능문제도 없어지고 나중에 다른 컬럼을 추가할때도 문제가 안생길 수 있습니다.
(참고) 비관계형 데이터베이스들은 제1정규화를 안하는 경우가 있습니다. 하지만 관계형 데이터베이스는 제 1정규화 안해놓으면 단점이 많아서 데이터를 저장할때 항상 하는 습관을 들입시다.
제 2정규형(2nd Normal Form)
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 | 가격 | 납부여부 |
10001 | 국성우 | 수영 | 50000 | 0 |
10002 | 김태준 | 스쿼시 | 70000 | 1 |
10003 | 양홍규 | 탁구 | 30000 | 1 |
10003 | 양홍규 | 수영 | 50000 | 0 |
아까 제1정규화 해놓은 테이블인데요.
심심해서 ‘가격’이랑 ‘납부여부’를 기록하는 컬럼도 만들어 놨습니다.
잘 돌아갈 것 같죠? 아닙니다.
Q. ‘수영’ 프로그램의 가격에 오류가 있어서 50000 → 60000 로 변경되어야 하면 어떡하죠?
→ 어떡하긴 멀 어떡해요. 그냥 2개 각각 수정하면 되죠.
Q. 수영에 참여하는 국성우가 잘생겼다고 ‘수영’을 신청한 사람이 갑자기 100명 늘어나면 어쩌죠?
→ 100개 행을 전부 50000→60000 이렇게 바꿔야지 꼼수 그런거 없습니다.
100개행을 고치는 불상사가 생기는게 싫다면
현재 테이블의 주제와 관련없는 컬럼은 다른 테이블로 옮기세요.
[센터 등록 회원 현황]
회원번호 | 이름 | 신청프로그램 | 납부여부 |
10001 | 국성우 | 수영 | 0 |
10002 | 김태준 | 스쿼시 | 1 |
10003 | 양홍규 | 탁구 | 1 |
10003 | 양홍규 | 수영 | 0 |
[프로그램 가격 현황]
프로그램 | 가격 |
수영 | 50000 |
스쿼시 | 70000 |
탁구 | 30000 |
‘가격’ 컬럼은 센터 등록 회원과 별로 상관이 없고 ‘프로그램’ 종류에 따라서 결정됩니다. 그래서 ‘가격’컬럼은 현재 테이블의 주제와 맞지 않기때문에 잘라내버리고 새로운 테이블을 만들어놨습니다.
이 작업이 완료된 테이블을 **제2정규형(2nd Normal Form)**이라고 합니다.
장점은 아까처럼 ‘수영’의 가격이 수정되어야할때 100곳을 수정할 필요가 없어집니다.
물론 이러면 단점도 있는데 나중에 양홍규가 얼마를 내야할지 조회하는게 귀찮아 집니다. 근데 그건 나중에 JOIN 문법을 쓰면됩니다.
제2정규형 심화버전
제2정규형의 교과서적 정의는 다들 정처기에서 보셨쥬?
partial dependency를 제거한 테이블입니다.
쉽게 설명하자면
1. composite primary key 라는게 있습니다.
primary key는 행을 서로 구분할 수 있는 유니크한 데이터 컬럼이라고 알고있습니다. 근데 가끔은 하나의 컬럼만으로 pk를 정할 수 없는 경우가 있습니다. 무엇이냐하면
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 | 가격 | 납부여부 |
10001 | 국성우 | 수영 | 50000 | 0 |
10002 | 김태준 | 스쿼시 | 70000 | 1 |
10003 | 양홍규 | 탁구 | 30000 | 1 |
10003 | 양홍규 | 수영 | 50000 | 0 |
⬆️ 위의 테이블에선 (회원번호 + 신청프로그램) 이렇게 조합해야 pk역할을 수행할 수 있습니다.
‘회원번호’만으로 pk 불가능
‘신청프로그램’만으로 pk 불가능
하지만 둘이 합치면 pk 가능
→ 두 컬럼을 합친 pk를 composite primary key 라고 합니다.
2. composite primary key 중 하나의 컬럼에만 종속되어 있는 따까리 컬럼을 partial dependency가 있다고 표현합니다.
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 | 가격 | 납부여부 |
10001 | 국성우 | 수영 | 50000 | 0 |
10002 | 김태준 | 스쿼시 | 70000 | 1 |
10003 | 양홍규 | 탁구 | 30000 | 1 |
10003 | 양홍규 | 수영 | 50000 | 0 |
⬆️ 예를들어 위 테이블에서 보면 ‘가격’ 컬럼은 ‘신청프로그램’에서만 결정될뿐 ‘회원번호’랑은 땡전한푼 이해관계 없습니다.
그 경우 ‘가격’컬럼은 partial dependency가 있다고 표현합니다.
3. partial dependency가 있는 컬럼을 다른 테이블로 다 뺏버린다면 그게 바로 제2정규화/형 테이블 완-성입니당.(그래서 아까 가격 컬럼을 뺀 것입니다.)
쉽나영?
쉬우니까 연습한번 갈겨봅시다.
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 | 가격 | 준비문 |
10001 | 손흥민 | 축구 | 5000 | 축구공 |
10002 | 이강인 | 헬스 | 6000 | 없음 |
10003 | 황희찬 | 헬스 | 6000 | 없음 |
10003 | 황희찬 | 축구 | 5000 | 축구공 |
Q1. 위 테이블에서는 ‘준비물’ 컬럼은 partial dependency가 있을까요 없을까요
- composite primary key 중 하나인 프로그램에 종속 O
- 그래서 제2정규형 만들려면 다른 테이블로 빼야합니다.
- composite primary key 중 하나인 회원번호에 종속 X
[센터등록회원현황]
회원번호 | 이름 | 신청프로그램 | 가격 | 준비문 |
10001 | 손흥민 | 축구 | 5000 | 축구공 |
10002 | 이강인 | 헬스 | 6000 | 없음 |
10003 | 황희찬 | 헬스 | 6000 | 없음 |
10003 | 황희찬 | 축구 | 5000 | 축구공 |
(아 오 씨찬이형!!!!!)
Q2. 위 테이블에서 ‘납부여부’ 컬럼은 partial dependency가 있을까여?
- 없습니다 ㅋ
- composite primary key 중 하나인 회원번호에 종속 X
- composite primary key 중 하나인 신청프로그램에 종속 X
- But (회원번호 + 신청프로그램)에 종속 O 입니다.
- 그래서 제2정규형 만들려고 다른 테이블로 따로 뺄 필요는 없을 것 같습니당.
🐽Tip
종속관계 판단이 어렵다면 하나의 컬럼을 다른 값으로 바꾸어보십시오…
그 경우 다른 컬럼도 변경되어야한다면 그것이 바로 ‘종속관계’입니다.
하… 나는 진짜 🪨머리라 교과서적인 것도 이해안가고 머라는지 모르겠다 싶으시면 그냥 무지성으로 현재 테이블 주제와 관련이 없다? 그러면 싹 다 다른 테이블로 빼면 제2정규형/화 만들기 끝입니다 ㅋ
'DI(Digital Innovation) > DataBase & SQL 뽀개기' 카테고리의 다른 글
제 3정규형 차렷 (0) | 2024.02.27 |
---|---|
2NF 완벽 이해 MASTER (0) | 2024.02.23 |
컬럼에 안전하게 제약 (Constraints) 주기 (0) | 2024.02.21 |
진정한 알파메일은 테이블과 컬럼 생성할 때 쿼리를 쓴다 (0) | 2024.02.21 |
SQL (IF/CASE) 장인을 꿈꾼다 (0) | 2024.02.21 |