기본 키
Primary Key
개념
표에서 행 하나를 다른 어떤 행과도 겹치지 않게 가리키는 열로, 그 표의 모든 행이 값을 반드시 가집니다.
등장 배경
행과 열로 데이터를 담는 테이블에서 특정 행 하나를 고쳐야 할 때는 그 행을 가리킬 방법이 필요합니다. 처음에는 사람이 읽을 수 있는 값을 쓰는 것이 자연스러워 보입니다. 이름이나 메일 주소로 찾으면 사람이 눈으로 확인할 수 있으니까요. 문제는 그 값들이 유일하지도 않고 고정되어 있지도 않다는 데서 나옵니다.
페이지덱 초기 사용자 표가 그렇게 만들어져 있었습니다. 이름과 메일 주소가 있었고 메일을 기준으로 사용자를 찾았습니다. 한 사용자가 회사 메일이 바뀌어 주소를 고쳤을 때, 그 사람이 만든 문서 40건이 주인을 찾지 못하는 상태가 됐습니다. 문서 표에는 옛 메일 주소가 적혀 있었기 때문입니다. 태오가 반나절을 들여 옛 주소와 새 주소를 손으로 짝지어 복구했습니다.
기본 키는 그런 일이 생기지 않게 절대 바뀌지 않는 값 하나를 따로 두는 장치입니다. 사람이 읽을 필요가 없고 뜻도 없어야 합니다. 뜻이 없어야 바뀔 이유도 없기 때문입니다.
작동 방식
표를 만들 때 열 하나를 지정하고 그 열에 두 가지 규칙을 걸어 둡니다. 값이 비어 있을 수 없고, 같은 값이 두 번 나올 수 없습니다. 데이터베이스가 이 규칙을 직접 지키기 때문에 프로그램이 실수로 중복을 넣으려 하면 그 자리에서 거부됩니다.
값을 만드는 방법은 둘로 갈립니다.
- 자동으로 1씩 늘어나는 정수를 씁니다. 짧고 순서가 있어서 읽기 편하고 저장 공간도 적게 먹습니다. 대신 다음 값을 짐작할 수 있고, 서버 여러 대가 각자 값을 만들어야 하는 구조에서는 같은 번호가 두 번 나올 위험이 있습니다.
- 무작위로 만든 긴 식별자를 씁니다. 길이가 길어 저장과 색인에 부담이 있지만, 서버가 서로 묻지 않고 각자 만들어도 겹치지 않고 다음 값을 짐작할 수도 없습니다.
어느 쪽을 쓰든 지켜야 하는 규칙이 셋 더 있습니다.
- 뜻이 있는 값을 쓰지 않습니다. 메일 주소, 사업자 등록번호, 사원 번호는 지금 유일해 보여도 바뀔 수 있습니다. 바뀌는 순간 그 값을 가리키던 모든 곳이 깨집니다.
- 열 하나로 충분하지 않으면 여러 열을 묶어 지정할 수 있습니다. 어떤 사용자가 어떤 문서를 즐겨찾기에 넣었는지 담는 표라면 사용자 쪽 값과 문서 쪽 값을 함께 묶어 키로 씁니다. 같은 사람이 같은 문서를 두 번 넣는 일이 이 규칙으로 막힙니다.
- 한 표에 하나만 둡니다. 유일해야 하는 열이 더 있으면 그것은 따로 유일 조건을 거는 것이고 기본 키는 아닙니다. 가리키는 값이 둘이면 어느 것으로 이어야 하는지가 코드마다 달라집니다.
이 열에는 대개 검색을 빠르게 하는 인덱스가 자동으로 붙습니다. 그래서 키로 한 행을 찾는 조회는 표에 행이 100만 개 있어도 빠릅니다.
쓰이는 곳
다른 곳에서 이 행을 가리켜야 할 때마다 쓰입니다.
가장 많이 쓰이는 자리는 표와 표를 잇는 지점입니다. 다른 표의 행을 가리키는 열이 외래 키인데, 그 열에 들어가는 값이 상대 표의 기본 키입니다. 중복을 줄이려고 표를 여러 개로 나누는 정규화를 하면 나뉜 표를 다시 잇는 일이 전부 이 값으로 이뤄집니다.
화면과 주소에도 나옵니다. 목록에서 한 줄을 눌러 상세 화면으로 갈 때 넘기는 값이 이 키이고, API 주소에 문서 번호가 들어가는 자리도 같습니다. 여기서 자동 증가 정수를 그대로 쓰면 주소의 숫자를 하나 바꿔 남의 문서를 열어 보려는 시도가 가능해집니다. 그래서 바깥에 노출되는 자리에는 무작위 식별자를 쓰거나, 내부 키와 외부에 보여 줄 값을 나눠 두는 방식을 씁니다.
기록에도 쓰입니다. 로그나 분석 데이터에 사용자 이름이나 메일을 적으면 그 값이 바뀔 때 과거 기록과 이어지지 않고, 개인 정보를 여러 곳에 흘리는 문제도 생깁니다. 바뀌지 않는 키만 남겨 두면 나중에 필요할 때 이름을 붙여 볼 수 있습니다. 분석 도구에서 같은 사람의 행동을 이어 보는 기준도 이 값입니다.
실무 용례
"메일을 기본 키로 쓰면 안 됩니다. 사용자가 바꿀 수 있는 값이에요."
유일한 값과 바뀌지 않는 값은 다르다는 지적입니다.
"이 표에 기본 키가 없어요. 똑같은 행이 이미 세 건 들어가 있습니다."
규칙을 걸어 두지 않으면 중복이 조용히 쌓인다는 뜻입니다.
"주소에 번호가 그대로 나오면 하나 올려서 남의 문서를 열어 볼 수 있습니다."
내부 식별자를 바깥에 그대로 쓰면 안 된다는 말입니다.
태오가 사용자 표를 고치면서 뜻 없는 식별자 열을 새로 만들고 그것을 기본 키로 지정했습니다. 메일 주소는 일반 열로 내리고 유일 조건만 따로 걸었습니다. 문서 표는 사용자 이름이나 메일이 아니라 그 식별자를 가리키게 바꿨습니다.
그 뒤로 메일 주소가 바뀌는 일은 아무것도 깨뜨리지 않았습니다. 같은 작업을 하면서 바깥에 나가는 공유 주소는 별도의 무작위 값으로 만들었습니다. 두 값을 나눈 덕에 문서 번호를 하나씩 올려 보는 방식으로 남의 문서에 닿는 경로도 함께 막혔습니다.
흔한 오해
사용자에게 보여 줄 번호와 같은 것이라고 읽는 경우가 가장 많습니다. 둘 다 하나를 가리키는 번호라서 그렇게 보입니다. 하지만 주문 번호처럼 사람이 읽고 말로 옮기는 번호에는 날짜나 지점 표시를 넣고 싶어지고, 그 형식은 언젠가 바뀝니다. 기본 키에 그 요구가 섞이면 형식을 바꾸는 날 그 값을 가리키던 모든 표가 흔들립니다. 사람이 읽는 번호는 별도 열로 두는 것이 안전합니다. 두 번호를 처음부터 나눠 두면 형식이 바뀌어도 화면 쪽 일로만 남습니다.
지금 유일하면 기본 키로 쓸 수 있다고 읽는 것도 흔합니다. 규칙이 유일성을 요구하니 유일한 값을 찾으면 된 것처럼 보입니다. 그런데 필요한 성질은 둘입니다. 유일하고, 앞으로도 바뀌지 않아야 합니다. 휴대전화 번호는 지금 유일하지만 바뀌고, 그때 그 번호를 가리키던 행들은 아무 경고 없이 다른 사람을 가리키게 될 수도 있습니다.
자주 헷갈리는 용어
| 용어 | 무엇을 가리키는가 | 기본 키와의 차이 |
|---|---|---|
| 외래 키 | 다른 표의 행 | 자기 표의 행을 가리키는 것이 아니라 남의 표를 가리킵니다. 값이 중복될 수 있고 비어 있을 수도 있습니다. 한 사용자가 문서 40건을 만들면 문서 표의 그 열에는 같은 값이 40번 들어갑니다 |
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16