복합키에 대한 개념을 기록하기 전에 간단하게 슈퍼키, 후보키, PK와 FK의 의미를 알아보자
위 개념을 구분하기 위해서는 유일성과 최소성이 무슨 의미인지를 아는 것이 중요하다.
쉽게 말해 중복되지 않는가를 말한다. 이름이나 혈액형은 중복되기가 쉽기 때문에 유일성을 보장하지 못한다. 그러나, 주민번호나 전화번호 따위는 중복될 수 없기 때문에 유일성을 보장한다.
키를 구성하는 속성들 중 가장 최소로 필요한 속성들로만 구성함을 말한다. 예를 들면 학번과 학과의 묶음은 유일성을 보장하지만 학번만으로도 충분히 학생을 식별할 수 있기 때문에 최소성을 보장하지 못한다.
또한 상품 주문을 식별할 때 주문 일자+고객명+상품명으로도 식별할 수 있겠지만, 간단히 주문 번호만으로도 식별을 할 수 있기 때문에 최소성을 고려하지 않은 설계라고 칭할 수 있다.
유일성을 만족하는 집합
유일성과 최소성을 만족하는 집합
이는 기본 키가 될 수 있는 키의 집합이며, 기본키로 설정되면 나머지는 대체키가 된다.
아래 테이블을 통해 무엇이 유일성과 최소성을 만족하는지 알아보자.
사진 출처: http://dbteam1116.pbworks.com/w/page/38413057/%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD%20%EB%B6%84%EC%84%9D
위의 표에서 후보키는 무엇이 될까?
고객번호, 전화번호, 주민번호가 될 것이다.
후보키에서 선택받은 키이다.
주민번호나 전화번호 같은 고객의 개인정보는 PK로 사용하는 것을 지양한다.
다른 테이블의 기본키를 가져와 관계를 연결시키면 이를 외래 키라고 부른다.
이는 테이블이 다른 테이블의 데이터를 참조하여 테이블간의 관계를 설정한다.
복합키
두 개 이상의 컬럼을 묶어서 하나의 기본키로 지정한다. 이는 하나의 테이블에 하나의 기본키만 존재할 수 있다는 규칙을 위배하지 않는다.
기본키는 하나의 테이블에 하나만 존재할 수 있다. 그런데 데이터베이스 모델링을 하면 하나의 컬럼으로는 기본키를 선택하기 어려운 상황이 발생한다.예를 들면, 위와 같은 반 테이블을 만들고 싶다. 학년, 반, 반이름 컬럼이 있을 때 어떤 것을 기본 키로 설정해야 하는지이다. 학년과 반 이름은 모두 유일성을 위배하기 때문에, 반을 PK로 설정하게 되면, 최대 3반까지만 있는 학교라고 가정했을 때 위에처럼 2학년 부터는 4반, 5반, 6반으로 증가하는 문제가 생긴다. 이럴 때는 학년 컬럼과 반 컬럼을 하나로 묶어서 지정하는 복합키를 사용 한다.
즉, 1-1, 1-2, 1-3, 2-1, 2-2, 3-1처럼 학년과 반을 묶어서 사용하면 유일성을 가지게 된다.
아래처럼 관계도를 만들 예정이다.
1. 먼저 Create New Table로 복합키를 설정할 테이블을 만든다.2. 컬럼에는 아래처럼 부서 이름, 부서id, 회사id를 넣어주었다.3. 그리고 Columns아래 Constraints로 들어가서 Create New Constraint를 선택한다.4. 복합키로 설정할 컬럼을 선택한다. 여기서 이미 PK가 존재한다면, PK를 먼저 삭제하고 진행해야 한다.
5. PK가 2개로 등록이 된 것을 확인 할 수 있다.
여기서는 Companyid와 Deptid의 결합이 PK로 설정되었기 때문에, 아래 그림처럼 총무부를 두번째 INSERT했을 때 Depid가 3이 되지 않고 1이 되는 것을 볼 수 있다.그 이유는 처음 INSERT 한 총무부는 Company id가 1인 회사이기에 PK가 1-1이고, 세 번째 INSERT 한 총무부는 Company id는 2인 회사이기에 Depid를 3을 배정할 필요가 없이 1을 배정하더라도 PK는 2-1로 중복이 된 것이 아니게 된다.
만약 PK를 Deptid 하나로만 설정한다면 아래처럼 Deptid는 1,2,3...으로 증가되게끔 설정된다.그리고 아래처럼 쿼리입력을 하면 '1'은 이미 존재한다는 오류가 나게 된다.
복합키를 사용할 때는 PK로 설정하는 순간, Null을 허용하지 않기 때문에
반드시 데이터값이 들어가야 한다.
그러나 우리가 실제로 데이터 모델링을 할 때는 부모나 자식의 위치를 모르고 일단 INSERT 하게 되는 경우도 존재한다. 예를 들면, 몇 학년인지는 정해졌지만, 아직 반이 정해지지 않았을 경우 복합키를 사용하면 반이 정해질 때까지 INSERT를 할 수 없게 된다. 사용자의 의도를 고려해서 복합키를 사용할 필요가 있다.
키 개념에 대해서 다시 한번 정리하는 계기가 되었다. 특히, 복합키의 개념은 처음 접해보았고, 직접 구현하면서 이를 설정하고 작동하는 방식에 대해 이해하게 되었다. 이러한 경험을 통해 복합키는 나중에 AK(Alternate Key)로도 사용될 수 있음을 알게 되었고, 개념을 정리하는 중요성을 깨달았다.
실제로 기존의 기본 키(PK)를 삭제하고 다시 생성하는 작업에서 몇 가지 어려움을 겪었다. 이유는 먼저 기존의 PK를 삭제하고 PK를 생성시에 하나의 PK는 반드시 설정해야 한다는 오류가 발생했고, 먼저 PK를 생성하고 PK를 삭제했을 때는 한 테이블에는 PK를 하나만 생성할 수 있다는 오류가 발생했다.
이를 해결하기 위해서는 기존 데이터를 먼저 지워야 한다는 점을 알게 되었다. PK를 변경하면 기존 데이터는 변경 전의 PK를 따르고 있기 때문에 이러한 처리가 필요한 것이었다.
이러한 오류 해결을 통해 DBeaver와 같은 데이터베이스 관리 도구에 점차 익숙해지고 있음을 느낀다. 계속해서 경험을 쌓아가면서 데이터베이스 작업에 대한 이해와 능력을 향상시켜 나갈 계획이다.