ERD에서 자주 본 PK, FK의 정확한 의미를 알아봅시다.
⚠️ 이 글은 시리즈로 앞 글과 내용이 이어집니다. 이전 글을 읽어보고 와주세요.
알아두면 쓸데있는 데이터 모델링 모아보기
- 정규화
- 여러 종류의 Key 이해하기 (feat. PK, FK는 무엇인가?)
- ER 모델의 구성 요소 - 엔티티, 속성, 관계 [✨ 로그인 전용]
앞 글에서 후보 키(Candidate Key)라는 단어에 대해서 잠깐 언급했습니다. 저는 처음 이 용어를 처음 들었을 때 고개를 갸우뚱 했습니다.
‘후보(Candidate)? 뭔가의 후보가 된다는 말인가? 그러면 후보가 결국 뭐가 되는 거지?’
여러 명의 대통령 후보 중에서 한 명이 대통령이 되잖아요. 모델링 나라에서 후보 키가 대통령 후보라면, 대통령은 뭘까 궁금했습니다. 살짝 스포를 하자면 대통령이 되는 키는 기본 키(Primary Key)입니다. 흔히 PK, ‘피키’라고 줄여서 부릅니다. 후보 중에 대통령이 되지 못한 키를 부르는 말도 있습니다. 이를 대체 키(Alternate Key)라고 부릅니다.
이번 글에서는 여러가지 종류의 Key에 대해서 얘기해보겠습니다.
슈퍼 키는 각 데이터를 유일하게 식별할 수 있는 속성의 집합입니다. 말이 좀 어렵지요? 아래 <주문> 테이블로 예를 들어보겠습니다.
주문 테이블은 속성을 3개 가지고 있고, 이 속성들을 조합한 모든 경우의 수는 7개입니다. 속성 조합 각각의 슈퍼키 여부는 아래와 같습니다.
주문 번호가 슈퍼 키이기 때문에, 주문 번호를 포함한 모든 조합도 슈퍼 키라고 할 수 있습니다.
후보 키는 각 데이터를 유일하게 식별할 수 있는 “최소한의” 속성 집합입니다. 슈퍼 키는 각 데이터를 유일하게 식별할 수 있는 속성의 집합이었죠. 여기에 “최소한의”라는 조건이 추가되었습니다. 슈퍼 키가 후보 키보다 좀 더 넓은 개념입니다.
각 데이터를 유일하게 식별할 수 있는 “최소한의” 속성 집합이라는건 그럼 무슨 말일까요? 좀 편하게 풀어보면, 각 데이터를 다른 데이터와 구분 가능하도록 해야 하는데 사족이 없었으면 좋겠다는 말입니다.
위의 예시에서 슈퍼 키가 될 수 있는 속성 조합은 주문 번호, {주문 번호, 주문 날짜}, {주문 번호, 회원 번호}, {주문 번호, 주문 날짜, 회원 번호}이었는데요. 이 중 후보 키는 주문 번호입니다. {주문 번호, 주문 날짜} 조합의 경우 주문 번호 만으로도 데이터를 유일하게 식별할 수 있는데, 주문 날짜가 사족으로 붙었기 때문에 후보 키가 될 수 없습니다.
우리는 이 후보 키 중 하나를 기본 키로 선택할 수 있습니다. 데이터베이스는 각 데이터를 고유하게 식별하는 용도로 기본 키를 사용합니다.
아래는 People이라는 테이블을 만들 때 ID라는 컬럼을 기본 키로 설정한 코드 예시입니다.
예시 출처: https://www.w3schools.com/sql/sql_primarykey.ASP
기본 키가 아닌 후보 키를 대체 키라고 부릅니다. 지금까지 후보 키가 1개만 있는 예시들을 봤기 때문에, ‘기본 키가 아닌 후보 키에는 어떤 게 있지?’하고 머리에 잘 안 그려질 수도 있을 것 같아요. 다른 예시를 살펴보겠습니다.
<학생>이라는 학번, 이름, 학과, 주민등록번호 속성을 가진 테이블이 있다고 가정해보겠습니다.
아래에서 슈퍼 키와 후보 키를 찾아보세요. 지금까지의 사례에서는 후보 키가 1개였지만, <학생> 테이블에서 후보 키는 2개입니다. 학번과 주민등록번호 각각 학생을 고유하게 식별할 수 있기 때문입니다. 후보 키는 1개 이상 존재할 수 있습니다.
후보 키 중 학번을 기본 키로 설정했다면 주민등록번호는 대체 키라고 부릅니다.
다른 테이블에 있는 기본 키를 참조해서 사용할 때, 외래 키라고 부릅니다.
아래와 같이 주문 정보가 들어있는 <주문> 테이블과, 그 주문의 상품 정보를 담고 있는 <주문 상세> 테이블이 있다고 가정해봅시다. <주문>의 기본 키는 주문 번호입니다. <주문 상세>에서는 이 주문 번호를 참조해서 사용하므로 <주문 상세> 테이블에서 주문 번호는 외래 키입니다.
답변. 아닙니다. 후보 키가 각 데이터를 유일하게 식별할 수 있는 “최소한의” 속성 집합이라고 하니, ‘후보 키는 속성 1개만 되는 거구나’ 오해를 하는 경우도 있습니다. 하지만 종종 아래와 같이 두 개 이상의 속성 조합이 후보 키가 되는 경우도 있습니다. 아래 테이블의 경우 후보 키는 {주문 번호, 상품 코드}의 조합입니다.
<주문 상세>는 특정 주문에서 어떤 상품을 구매했는지 정보를 담고 있기 때문에 이 데이터를 유일하게 식별하려면 주문 번호와 상품 코드가 함께 필요합니다. 위 예시에도 하나의 주문 번호에 여러 상품이 들어있기 때문에 주문 번호만으로는 데이터를 특정할 수 없는 것을 확인할 수 있습니다.
<주문 상세>와 같이 후보 키가 두 개 이상 속성의 조합일 때에, 이를 기본 키로도 설정할 수 있습니다. 복합 기본 키(Composite Primary Key)라고 부릅니다. ‘기본 키는 반드시 하나여야 한다’는 설명을 읽고 컬럼 한 개만 기본 키로 설정할 수 있다고 종종 오해하는 경우가 있는데, 이 때에 ‘반드시 하나여야 한다’는 것은 후보 키 중 하나만을 선택해야 한다는 것이지 컬럼이 하나여야 한다는 뜻은 아닙니다.
아래는 user_roles 라는 테이블을 만들 때 user_id, role_id를 복합 기본 키로 설정한 코드 예시입니다.
예시 출처: https://www.mysqltutorial.org/mysql-primary-key/
답변. 외래 키가 기본 키라면 모델링이 잘못 된 것입니다.
예를 들어, 아래와 같은 테이블을 생각해봅시다. <주문> 테이블에는 주문 번호, 주문 날짜, 회원 번호 정보가 들어있습니다. <주문 상세>에서는 <주문>의 기본 키인 주문 번호를 참조하는 외래 키로써 주문 번호가 있고 주문 수량이 있습니다. 한 가지 물건만 파는 회사라서 <주문 상세>에 상품 코드를 관리하지 않는다고 가정하겠습니다. 이런 경우 <주문 상세> 테이블에서 주문 번호는 기본 키이자, 외래 키입니다. 하지만 가만히 생각을 해보세요. 이렇다면 <주문>과 <주문 상세> 테이블을 분리 할 필요가 있었을까요? 주문 수량을 <주문> 테이블에서 함께 관리하면 될 일입니다. 이렇게 외래 키가 기본 키가 되었다면, 참조 관계를 없애고 테이블을 합쳐야 합니다.
하지만 외래 키가 기본 키 집합의 일부가 될 수는 있습니다. 아래의 <주문 상세> 테이블에서 주문 번호는 <주문>의 기본 키를 참조하는 외래 키 입니다. 또한 <주문 상세> 테이블의 복합 기본 키인 {주문 번호, 상품 코드}를 구성하는 속성이기도 합니다.
데이터 분석을 하다보면 테이블의 구조를 보기 위해 ERD를 참고할 일이 많은데요. 그 때마다 PK, FK라는 단어를 보면서 ‘저게 뭘까. 정확하게 알고 싶다’ 생각했던 분들에게 가려운 부분을 긁어주는 글이길 바랍니다.
기본 키와 외래 키 이외에도 기본 키의 후보가 되어주는 후보 키, 후보 키보다 더 넓은 개념의 슈퍼 키까지 기억하시면 더 좋을 것 같네요!
쉽고 재미있게, 실무에서 바로 사용할 수 있는 SQL 스킬
8주 만에 마스터하고 데이터 분석 프로젝트까지 만들어보세요.
데이터 분석가들이 SQL 데이터 분석 캠프를 만든 이유 3가지
1. 데이터를 내 손으로 직접 뽑아보려면 파이썬이 아니라 SQL이 필요해요
2. 자격증보다는 실제로 쿼리를 짤 수 있는 능력이 중요해요
3. 데이터 분석은 여러분 생각보다 훨씬 쉽고 재밌어요
▶ 데이터 분석가들이 직접 발행하는 뉴스레터 무료로 받아보기
▶ 데이터 분석 실무자들이 모여있는 오픈 카톡방 참여하기
(링크 클릭 후 참여 코드 확인 필수!)
▶ SQL 데이터 분석 캠프 커리큘럼 보러가기
▶ GA4 데이터 분석 캠프 커리큘럼 보러가기
▶ 데이터리안 블로그에서 더 다양한 데이터 분석 콘텐츠 구경하기
▶ 데이터 분석 전문 세미나 이번달 주제 보러가기