서론: 기본 엔티티 (Base Entity)

GPT에게 물어보니 Base Entity를 위와 같이 설명합니다. Base Entity는 상속을 위한 엔티티라고 합니다. 데이터베이스로 설계를 곧 잘 해보신 백엔드 개발자분들께서도, DB 레벨에서 상속을 구현한 경우는 많지 않을 거라고 생각합니다. 코드 상에서 Base Entity라는 클래스를 정의해봤다고 해도 대부분은 공통된 칼럼을 갖게끔 구현하기 위함이고, 실제로 상속과 같이 구현되지는 않았을 거라고 생각합니다. 따라서 이번 글에서는 데이터베이스 상에서 Base Entity를 어떻게 정의하는지, 그리고 그 예시가 무엇인지 설명하고자 합니다. Base Entity를 사용하면 훨씬더 직관적이고 확장성 있는 ERD 표현이 가능하죠.

Base Entity를 활용한 정규화

erDiagram
    EMPLOYEE {
        int id PK
        string name
        string email
        string position
        int salary
    }
    
    CUSTOMER {
        int id PK
        string name
        string email
        string membership_level
        date signup_date
    }

Employee와 Customer 테이블을 정의해야 한다고 해봅시다. 이 두 테이블은 ‘회원’에 해당하며 로그인이 가능해야 합니다. 또한, 두 테이블을 공통된 칼럼으로 id, name, email를 가져야 합니다. 이런 구조는 커머스에서도 흔합니다. 커머스에서는 Buyer, Seller, Admin이 그러합니다. 이런 인증 로직을 구현해본 백엔드 개발자라면, 서로 다른 테이블에서 인증을 구현하는 게 꽤나 까다로운 작업임을 알고 있을 겁니다. 만약 PK가 Auto increment로 정의되어 있는 INT 칼럼이라고 한다면, 사실 각각 다른 로그인 API로써 토큰을 발급해주는 게 쉬울 겁니다. 그 결과 구매자 회원가입, 로그인, 판매자 회원가입, 로그인, 어드민 회원가입, 로그인 등 테이블마다 API가 생겨납니다.

이것은 비단 인증 로직에만 해당하는 것이 아니고, 테이블이 나뉘어져 있는 경우에 모두 해당합니다. 당연히 그도 그럴 것이, 서로 나뉘어져 있는 PK를 가지고 있는 이상 데이터를 지칭할 방법도 나뉠 수 밖에 없죠. 하지만 이 둘의 공통 칼럼을 묶어서 Base Entity 라는 개념을 만들면 해결할 수 있습니다.

erDiagram
    PERSON {
        int id PK
        string name
        string email
    }
    
    EMPLOYEE {
        int id PK, FK
        string position
        int salary
    }
    
    CUSTOMER {
        int id PK, FK
        string membership_level
        date signup_date
    }

    PERSON ||--o| EMPLOYEE : "inherits"
    PERSON ||--o| CUSTOMER : "inherits"

Base Entity는 공통된 칼럼을 가진 둘 이상의 테이블에서 공통 칼럼을 모아서 하나로 묶은 테이블을 의미합니다. 위 그림에서는 Person 이라는 Base Entity가 있다면 Employee와 Customer 둘을 통합하는 것이 매우 편해집니다. 핵심은 Base Entity의 PK를 FK이자 PK로 가지게 하는 것입니다. 이렇게 되면 로그인에 대한 것을 Person에서 구현하면 되기 때문에 훨씬 더 낫습니다. Person에 대한 회원가입 / 로그인만 만들면 두 리소스에 대해 모두 대응이 가능해지죠. 그리고 데이터베이스 이론에서 말하는 정규화 면에서도 훨씬 더 깔끔합니다. ( 여기서는 제2정규형이니 뭐니 하는 말은 쓰지 않겠습니다. )