상세 컨텐츠

본문 제목

관계 종류 (일대일 관계, 배타관계)

기록 - 프로그래밍/Data

by wjjun 2024. 6. 11. 12:06

본문

일대일 관계

일대일 관계는 상위 엔티티의 하나의 인스턴스에 하위 엔티티도 하나의 인스턴스가 연관되는 관계입니다.

엔티티 간 업뮤 규칙이 일대일 관계일 수도 성능 차원에서 일대일 관계를 채택할 수도 있습니다.

 

흔하지 않지만 업무적으로 두 엔티티 사이 일대일 관계가 존재할 수 있습니다. 예를들어 개인고객 엔티티와 여권 엔티티 사이에는 업무적으로 일대일 관계가 존재합니다.

 

개인고객 엔티티와 여권 엔티티는 일대일 관계입니다. 업무적으로 일대일 관게를 나타내고 있으며 현재 상태의 여권 데이터를 관리합니다. 만약 여권을 재발급 받아 여권번호, 여권종류, 발급일자, 만료일자가 바뀌면 데이터를 업데이트 하겠다는 것을 의미합니다.

 

일대일 관계 모델

개인고객 - 고객번호(PK) / 고객명

여권 - 고객번호(FK) / 여권번호 / 여권종류 / 발급일자 / 만료일자

 

과거 여권에 대한 정보를 알 필욕다 없을 때 위 모델로 관리해도 무관하지만 여권의 과거 데이터를 관리하면 아래 처럼 일대다 관계가 됩니다.

 

일대다 관계 모델

개인고객 - 고객번호 (PK) / 고객명

여권 - 여권번호 (PK) / 고객번호 (FK) / 여권종류 / 발급일자 / 만료일자

 

위 모델은 여권을 하나의 실체로 본 것으로 여권이라는 실물을 구별할 수 있는 여권번호 속성이 여권 엔티티의 주 식별자가 되었으며 고객번호 속성은 해당 여권을 소유한 고객이 누구냐를 관리하는 관계속성입니다.

 

데이터 성격이 다르면 업무를 명확히 표현하기 위해 일대일 관계를 유지하는 것이 좋습니다. 그래야 모델을 이해하기 쉽고 업무 변경이나 이력 관리 요건 등을 유연하게 적용할 수 있는 모델이 됩니다.

 

엔티티 속성 중 유사 속성을 일대일 관계로 분해하는 것에 대해서는 주의가 필요합니다. 모델이 서로 데이터 성격이 다르고 관리할 속성이 다양하게 존재하면 일대일 관계로 도출하는 것이 옳지만 고객의 속성 중에서 유사 2, 3개 속성을 묶어 별도 엔티티로 분해하는 것은 업무적으로 발생한 일대일 관계와 다르게 실익이 없어 과도한 엔티티 분해를 지양해야 합니다.

 

데이터가 같은 성격인지 다른 성격인지 구분하기 쉽지 않아 일대일 관계로 도출해야 하는지를 결정하는 것은 엔티티 통합하는 것과 같이 어려운 판단 중 하나입니다.

 

만약 해당 데이터가 단독으로 취득되는 데이터이거나 해당 데이터만 별도 조회 요건이 있을 때는 일대일 관계의 별도 엔티티로 관리할 수도 있지만 엔티티를 불필요하게 분해하는 것은 지양해야 합니다.

 

많은 인스턴스에서 널값을 포함한 속성이 있다면 그 속성만 분해하는 것도 고려할 수 있습니다. 일대일 관계의 새로운 엔티티로 분리하는 것이 저장 공간을 효율적으로 사용할 수 있습니다. 

 

엔티티의 속성이 많으면 성능을 고려해 일부 속성을 별도 엔티티로 분리하는 이유는 핵심적인 속성을 하나의 블록에 가능한 많이 저장해서 사용하기 위해서 입니다. 한 엔티티에 많은 속성이 존재하면 조회할 때 많은 디스크I/O가 발생합니다. 여러 인스턴스 조회할 때는 더 많이 발생됩니다.

 

그래서 주로 같이 조회되는 속성과 자주 조회되지 않는 속성으로 나눠 엔티티를 분할하면 주로 조회되는 속성에 대한 디스크 I/O가 감소하여 성능이 개선됩니다.

 

로우 체이닝이나 로우 마이그레이션도 감소해 성능에 좋은 영향을 미칩니다. 속성이 많고 사용도 빈번해 성능을 고려해야 하는 핵심 엔티티가 분할의 대상이 됩니다.

 

로우 체이닝 : 하나의 행(row)이 여러 데이터 블록(data block)에 걸쳐 저장되는 상황입니다. 주로 행의 크기가 커지거나 업데이트 과정에서 행의 크기가 증가하여 하나의 데이터 블록에 더 이상 저장할 수 없을 때 발생합니다.

 

로우 마이그레이션 : 로우 마이그레이션(Row Migration)은 데이터베이스 관리 시스템에서 발생하는 현상으로, 하나의 행(row)이 데이터 블록(data block) 간에 이동하는 것을 의미합니다. 이는 주로 행의 크기가 증가하여 원래 저장된 블록에 더 이상 저장할 수 없을 때 발생하며, 행의 일부 또는 전체가 다른 블록으로 이동하게 됩니다

 

 

배타 관계

두 개 이상의 상위 엔티티와 관계를 가지며 그 관계가 상호배타적일 때 관계입니다. 하위 엔티티 하나의 인스턴스는 관계를 갖는 두 개 이상의 상위 엔티티 중에서 하나의 엔티티 하고만 관계를 갖습니다.

거래내역 엔티티는 두 개의 상위 엔티티와 관계를 갖습니다. 그리고 두 개의 관계는 상호 배타적입니다.

 

거래내역은 주식이나 채권 종목과 관계가 있으며 거래내역 엔티티의 각 인스턴스는 상위 엔티티인 주식종목이나 채권종목 둘 중 하나의 엔티티와 관계가 있습니다. 이런 관계를 배타 관계라고 하고 서비스에서 자주 볼 수 있습니다.

 

배타관계 엔티티

주식종목 - 주식종목코드 (PK)

채권종목 - 채권종목코드 (PK)

거래내역 - 거래번호 (PK) / 종목구분코드 [=주식, 채권] / 종목코드(FK) 

 

배타 관계를 관리하는 속성은 두 식별자의 의미를 포괄하여 '종목코드'가 된다. 종목코드 속성 값은 당연히 주식 또는 채권 종목이어야 하기 때문에 널(Null) 값을 허용하면 안됩니다.

 

배타 관계가 발생한 엔티티에서는 보통 해당 인스턴스가 어떤 상위 엔티티와 관계를 갖는지 구분자 속성으로 관리합니다.

업무적으로 거래내역 엔티티에서 먼저 조인이 발생하지 않고 상위 엔티티에서 먼저 조인이 발생하면 이미 주식종목인지 채권종목인지 아는 상태에서 거래내역 엔티티와 조인하므로 '종목구분코드'라는 속성이 필요 없을 수 있지만, 그렇지 않고 거래내역 엔티티를 기준으로 조인이 발생하면 종목구분코드 속성이 필요해집니다. 공간을 조금 더 차지한다는 이유로 종목구분코드 속성을 없애면 조회할 때 불편하며 성능에 비효율이 발생하게 됩니다.

 

배타 관계를 발생시킨 두 엔티티를 통합하는 경우 아래 모델처럼 서브타입이 발생합니다.

 

배타관계 엔티티 통합해 서브타입이 도출된 모델 - 종목 : 거래내역 ( 1 : N )

종목 - 종목코드 (PK) / 종목구분코드 [=주식, 채권]

거래내역 - 거래번호 (PK) / 종목코드(FK)

 

배타 관계와 서브타입은 밀접한 관계가 있으며 서브타입은 데이터 통합과 관계가 있습니다.

배타 관계는 통합의 대상이 됩니다. 엔티티 통합 기준 중 하나가 배타 관계가 발생할 때 이기도 합니다.

 

배타 관계는 복잡한 관계로 배타 관계를 발생시킨 상위 엔티티를 통합하는 것을 적극적으로 고려해야 하지만 상위 엔티티의 성격이 다를 때는 통합을 할 수 없습니다. 엔티티 정의를 흐리게 하는 것은 부작용이 커질 수 있습니다.

관련글 더보기

댓글 영역