관계(Relation)
관계형 데이터베이스(RDB)를 처음 접하는 사람들이 가장 먼저 만나게 되는 장벽이 바로 관계다. 자세한 예시를 들어도 이해하기 쉽지 않다. 직접 써보면서 깨닫기 전까지는.
관계는 데이터베이스에서 컬럼의 비어있는 데이터 공간을 최소화하기 위한 수단이다. 무슨 말이지 감이 잘 안 올 수도 있다. 그래서 먼저 관계가 없으면 어떤 사태가 일어나는지를 음식점의 음식으로 예를 들어보자.
매장명 | 전화번호 | 위치 | 최소금액 | 배달비 | 음식1 | 음식2 | 음식3 ... |
쉑쉑버거 | xxx-xxxx | 종로구 | 12,000 | 2,000 | 그냥버거 | 치즈버거 | 더블패티 |
자담치킨 | xxx-xxxx | 강남구 | 13,000 | 1,000 | 후라이드 | 양념치킨 | null |
짜장면맛집 | xxx-xxxx | 강서구 | 7,000 | 4,000 | 짜장면 | null | null |
관계 없이 음식점을 정의하려고 하면, 음식의 종류가 가장 많은 음식점의 수 만큼 컬럼을 생성해야하고, 음식의 종류가 부족한 음식점은 해당 컬럼들을 빈 공간으로 두어야 한다. 데이터의 존재 여부와 관계 없이 격자 형식으로 용량을 할당하는 데이터베이스에게 있어서 정말 비효율적인 일이다. 그렇다면 이런 경우를 줄이기 위해 어떻게 해야할까. 바로 연관되어있는 컬럼으로 서로를 참조하여 테이블을 분리 하는거다.
관계를 만들면 공간적으로는 효율적이지만 속도는 사실 느려진다. 연관성 있는 테이블을 서로 참조하는 구조이다보니 추가적인 시간이 소모되는 것이다. 때문에 경우에 따라 NULL 공간의 발생을 감수하면서 테이블을 일부 합쳐 운영을 하는 경우가 있다고 한다. 속도와 효율 사이에서 타협을 잘 봐야 할 것이다.
그러면 관계가 뭔지, 관계가 왜 필요한지에 대해서는 정의했으니, 이제 관계의 종류는 무엇이 있는지 알아보자.
※ 예시는 이해를 돕기 위한 예시일 뿐으로, 실제로는 기본키(PK)값을 가지고 서로를 참조하는 구조를 가진다. 그냥 전체적인 개요를 이해하는 정도로만 받아들이면 좋겠다.
일대일 관계(One to One)
일대일 관계는 각자의 테이블에서 중복되지 않는(UNIQUE) 참조키를 가지는 관계를 말한다.
음식점으로 친다면, 매장의 메뉴 정보와 매장의 위치를 별도로 관리한다고 했을 때를 생각하면 편할 것이다.
하나의 매장 이름은 하나의 주소만 가져야 한다. 배달어플을 사용하는 사람에게 있어서 이 정보는 혼동을 일으켜서는 안 되니까. 그렇기 때문에 하나의 주소에 여러 개의 매장이 등록되면 안 되고, 하나의 매장이 여러 개의 주소를 가지면 안 된다.
이론상으로는 이렇지만, 사실 배민에서는 하나의 주소로 매장 여러개 등록해놓는다..... 탐지 범위를 늘리기 위한 편법이라고 하던데, 그러지 않았으면 좋겠다..
일대다 관계(Many to One | One to Many)
두 테이블 중 자식 테이블이 부모에 해당하는 테이블을 참조하는 구조로, 데이터베이스 설계시 가장 많이 나타나는 관계이다. 부모 테이블의 경우 매정하게도 자신의 자식이 누구인지 굳이 명세해놓을 필요가 없고, 자식은 부모가 누구인지 참조하여 데이터 구조를 만들어낸다.
일반적으로 음식 옵션은 사장님이 직접 기입하는 식으로 작성이 된다. 그렇기 때문에 하나의 음식은 여러 개의 옵션을 가질 수 있지만, 하나의 옵션은 여러 개의 음식을 참조할 수 없다.
다대다 관계(Many to Many)
근데 만약에, 배달의 민족이 음식 옵션의 풀을 미리 지정해놓고, 사장님이 선택해서 사용할 수 있도록 만들었다면 어떨까?
이 경우 일대다 관계로 설계한다면, 옵션을 먼저 등록하기 위한 쟁탈전이 일어날 것이다. 이 옵션에 등록할 수 있는 음식은 단 하나뿐이니까.
이럴 때 여러 개의 음식과 여러 개의 옵션이 상호 참조할 수 있도록 설정해 주는 것이 다대다 관계이다.
근데 다대다관계를 맺어놓는것은 좋은 구조가 아니다. 왜냐면, 데이터베이스는 해당 레코드를 유일하게 식별할 수 있어야 하는데, 다대다 관계가 되는 순간 유일한 데이터를 식별할 수 있는 방법을 잃게 된다.
기본키로 id를 두면 되지 않는가? 라는 의문이 들 수 있는데, 다대다 관계가 되는 순간 결국 레코드를 식별하려면 다대다 관계를 갖는 컬럼들을 참조할 수밖에 없게 되고, 결국 id는 기본키임에도 기본키 역할을 할 수 없게 된다.
그래서, 일반적으로 다대다 관계를 맺을 때는 일대다 관계로 상호 연결된 중간 테이블을 만들어 본래 데이터의 유일성을 보존시킨다.
이렇게 해놓으면 음식-음식옵션 테이블에서 메뉴이름과 옵션을 완전히 일치하지 않는 선에서 자유롭게 작성할 수 있게 되고, 음식 테이블과 음식 옵션 테이블은 자신의 데이터의 기본키의 역할을 지켜낼 수 있게 된다.
여기서 조금 더 심화단계로 나아가자면, 관계는 서로 참조하는 테이블이 많아질수록 속도가 느려지는 문제가 있는데, 이 현상을 최대한 줄이기 위해 테이블을 어디까지 분리를 해놓아야 하는가에 대한 고민 또한 해야 할 것이다. 심지어 테이블을 어느 정도까지 분리를 해야 하는가에 대해 정의해놓은 일종의 규칙이 있는데, 이걸 전문용어로 정규화(Normalization)라고 부른다. 이런 것들을 고려해가며 데이터베이스를 설계하게 된다면 좋을 구조가 나올 수 있지 않을까라는 생각이 든다.
'내가 배운 것들 > 기타' 카테고리의 다른 글
Youtube Data API v3의 검색 기능 매개변수들 (0) | 2021.12.17 |
---|---|
변수는 반복문 안에서 선언하는게 좋을까? 밖에서 하는게 좋을까? (0) | 2021.12.10 |
REST API가 뭘까? (0) | 2021.11.29 |
WAS가 뭘까? (0) | 2021.11.29 |
ORM이 뭘까? (0) | 2021.11.28 |
댓글