SQL 캠프 마스터 광고 이미지
  • SQL
  • 데이터 모델링
  • 로그인 전용

알아두면 쓸데있는 데이터 모델링 (7) 관계 톺아보기 (feat. 데이터 무결성)

SQL 캠프 마스터 광고 이미지
SQL 캠프 마스터 광고 이미지
지금 간편하게 로그인하고 전문성 있는 정보를 확인해보세요.

데이터 분석가들이 직접 쓰는 다른 로그인 전용 글들도 무제한으로 이용할 수 있습니다.

🔖
알아두면 쓸데있는 데이터 모델링 모아보기
  1. 정규화
  1. 여러 종류의 Key 이해하기 (feat. PK, FK는 무엇인가?)
  1. ER 모델의 구성 요소 - 엔티티, 관계, 속성 [✨ 로그인 전용]
  1. ERD 읽어보기 [✨ 로그인 전용]
  1. 엔티티 톺아보기 [✨ 로그인 전용]
  1. 속성 톺아보기 [✨ 로그인 전용]
  1. 관계 톺아보기 [✨ 로그인 전용]
  1. ERD 그려보기 [✨ 로그인 전용]
 
엔티티, 속성에 대해 지금까지 여러가지 관점으로 주의해야 할 점에 대해 이야기해보았습니다. 마지막으로 ER 모델의 중요 3 요소 중 ‘관계’에 대해 이야기해보려고 합니다.
관계에 대해 이야기하기 위해서 ‘무결성(Integrity)’이라는 개념을 알고 있으면 좋습니다. 특히 ‘관계’와 관련된 무결성은 ‘참조 무결성’인데요. 얘기가 나온 김에 무결성이라는 것이 뭔지 알아보겠습니다.
 

데이터 무결성(Data Integrity)

 
데이터 무결성(Data Integrity)은 데이터를 저장하고 관리할 때 데이터의 정확성과 일관성을 유지하기 위해 사전에 정의한 규칙이다. 데이터 무결성은 실체 무결성(Entity Integrity), 영역 무결성(Domain Integrity), 참조 무결성(Referential Integrity)이 있다. 데이터 무결성을 통해 데이터의 정확성, 일관성, 유효성, 신뢰성을 확보할 수 있고, 무효 갱신으로부터 데이터를 보호할 수 있다. 데이터 모델링 과정에서 정의된 일련의 규칙에 따라 데이터가 생성, 수정, 삭제될 수 있도록 프로그램이나 데이터베이스 기능을 강제할 수 있다. 그 결과 권한이 부여된 사용자에 의해 야기될 수 있는 의미적 에러를 방지하고, 데이터베이스 내의 데이터가 현실세계의 올바른 데이터를 갖도록 보장할 수 있다. 핵심 데이터 모델링 - 유동오
 
쉽게 말해 데이터가 정확성과 일관성을 가지기 위해 몇 가지 규칙들을 지켜야 한다는 이야기입니다. 실체 무결성, 영역 무결성, 참조 무결성 3가지가 있고, 이 규칙들이 실체가 없이 말로만 있으면 지켜지지 않을 수 있으니 데이터베이스 기능을 이용해 이를 강제할 수 있습니다. 무결성을 지키기 위해 데이터베이스에서 제공하는 기능들을 ‘제약조건(Constraint)’라고 부릅니다.
이어서 실체 무결성, 영역 무결성, 참조 무결성 각각의 의미와 관련 데이터베이스 기능을 알아보겠습니다. 데이터베이스는 PostgreSQL을 기준으로 합니다.
 

실체(Entity) 무결성

실체 무결성은 각 인스턴스를 유일하게 식별할 수 있어야 한다는 것입니다. 다르게 말하면, 모든 속성 값이 동일한 인스턴스가 한 엔티티 안에 2개 이상 존재할 수 없다는 뜻도 됩니다. 이 유일성을 보장하기 위해 가장 쉽게 사용할 수 있는 방법은 기본키(Primary Key) 또는 고유 제약(Unique Constraint) 조건을 설정하는 것입니다.
 

기본키 설정

예시로 기본키 설정하는 방법을 간단하게 살펴보겠습니다. 아래는 테이블을 생성할 때 기본키를 설정하는 방법입니다.
 
아래와 같이 이미 생성된 테이블에 기본키를 추가할 수도 있습니다.
 

Unique 제약 조건 설정

아래는 email 컬럼에 고유 제약 조건을 설정한 예시입니다.
 
위 테이블에 이미 들어있는 email 값과 같은 데이터를 넣으려고 하면 아래와 같은 에러가 출력됩니다. 기본키로 설정된 컬럼도 마찬가지로 동작합니다. 이렇게 DBMS의 기본키 설정, 고유 제약 조건 설정 기능을 이용해 실체 무결성을 시스템적으로 강제할 수 있습니다.
 
번외로, DBMS는 중복 에러를 어떻게 빠르게 찾아줄 수 있는 것일까요? 언뜻 생각을 해봤을 때에는 새로운 데이터를 넣으려고 INSERT 시도를 할 때마다 전체 테이블을 스캔하여 지금 새롭게 추가하려는 데이터가 테이블에 있던 데이터인지 확인하는 절차가 필요할 것 같습니다. 그러면 매번 데이터를 넣을 때마다 굉장히 많은 연산이 필요하겠지요. 이 과정에서 DBMS가 최적화를 위해 어떤 작업을 미리 해놓는지 궁금하다면 고유 인덱스 (Unique Index)를 살펴봐주세요. 여러분들이 읽기 좋도록 PostgreSQL 공식 문서를 데이터리안이 번역했습니다 😊
 
 

영역(Domain) 무결성

두 번째는 영역 무결성입니다. 데이터의 속성 값이 정해진 범위를 벗어나지 않고 데이터 타입이나, 데이터의 길이 등을 일관되게 유지해야 한다는 규칙입니다. 크게 3가지 기능으로 이를 강제할 수 있습니다.
 
  • CHECK: 속성 값이 특정 범위 내에 있는지, 특정 형식을 갖추고 있는지 등을 체크
  • DEFAULT: 값을 넣어주지 않았을 때 기본으로 사용하는 값을 지정
  • NOT NULL: 값으로 NULL이 들어갈 수 없음
 
CHECK, DEFAULT, NOT NULL 제약조건 예시
 
 

참조(Referential) 무결성

마지막으로 참조 무결성은 모델링에서 정의한 엔티티간의 관계를 유지해야 한다는 것입니다.
 
notion image
 
예를 들어, customers 테이블과 orders 테이블이 customer_id로 1:N 관계를 가지고 있다고 모델링에서 정의했다면 실제 데이터베이스에 들어있는 데이터도 이 규칙에 따라야 합니다. customers 테이블에는 데이터가 없는 고객인데, orders 테이블에는 존재하는 상황이 있으면 안됩니다. 이 규칙을 시스템으로 강제하기 위해 DBMS에는 외래키(Foreign Key)를 설정하는 기능이 있습니다.
아래 예시는 고객(customer) 한 명에 여러 연락 수단(contact)을 저장할 필요가 있을 때 customers, contacts 테이블을 각각 만드는 상황입니다. contacts 테이블을 정의할 때 customer_id를 외래키로 설정하고, 이 외래키가 customers 테이블의 customer_id 컬럼을 참조한다고 적었습니다.
 
 
크게 두 가지 효과가 있습니다.
  • 부모 테이블인 customers에 없는 customer_id를 자식 테이블인 contacts에 넣을 수 없습니다.
  • 부모 테이블인 customers에서 특정 customer_id를 삭제하거나, 업데이트 할 때 자식 테이블에도 이 사항을 반영하도록 설정할 수 있습니다.
 
참조 무결성을 이해하기 위해 FOREIGN KEY 설정 방법을 간단하게 알아봤습니다. 더 자세한 내용을 알고싶다면 참고 자료를 봐주세요!
 
 

관계선 그리기

간혹 모델링을 할 때에 엔티티, 속성까지는 잘 생각을 해놓고 관계를 정의하는데에 소홀한 분들이 있는데요(접니다). 관계, 즉 참조 무결성 제약은 오류 데이터의 진입을 막는데 굉장히 효과적인 방법이기 때문에 신경을 쓰는 것이 좋습니다.
ERD를 그리는 방법에 대해서 뒤에서 다시 다루겠지만, 관계선을 그릴 때에는 부모 엔티티의 기본키가 자식 엔티티의 외래키로 내려오는 관계가 존재할 때에만 관계선을 그려줘야 합니다. 이외의 경우(LIKE, BETWEEN 등 값이 정확하게 일치하는 관계가 아닌 경우 등)는 FOREIGN KEY 설정을 통해 참조 무결성을 구현할 수 없고, ERD에서 관계선으로 표현하는 것도 적절하지 않습니다. 다만 이런 규칙들도 표현을 해놓아야 ERD가 설계도로서 역할을 제대로 할 수 있겠지요. 이런 경우는 관계선보다는 설명으로 적어놓는 것이 좋습니다.
 
 

M:N 관계는 이렇게 해결하세요

solvesql 플레이그라운드에 있는 ‘Museum of Modern Art Collection’ 데이터베이스를 이용해 M:N 관계를 해결하는 방법을 알아보겠습니다.
이 데이터는 뉴욕의 MoMA 미술관에 전시된 작품과, 작품의 작가를 담고 있습니다. 한 명의 작가가 여러 작품을 MoMA에 전시할 수 있고, 한 작품에 여러 작가가 협업을 할 수 있기 때문에 작품과 작가는 다대다 관계입니다.
notion image
이 경우 artists, artworks 엔티티 사이에 어떻게 관계선을 그려야 할까요?
관계선을 그리기 전에 먼저 다대다 관계를 해소해주어야 합니다. 제 1 정규화 원칙을 다시 생각해보면, 하나의 셀에 여러 개의 값을 넣어야 하거나 개념적으로 중복되는 컬럼이 있는 경우 별도의 테이블로 분리해야 합니다. 예를 들어, artists 테이블을 아래와 같이 만들 수는 없습니다. (프랑스 사진 작가 Eugène Atget은 MoMA에 5050점의 작품을 전시하고 있는데 이 정보를 저장하려면 컬럼을 5050개 추가해야 합니다.)
 
테이블 <artists>
artist_id
name
nationality
gender
birth_year
death_year
artwork_1
artwork_2
artwork_3
1
Robert Arneson
American
Male
1930
1992
2
Doroteo Arnaiz
Spanish
Male
1936
3
Bill Arnold
American
Male
1941
4
Charles Arnoldi
American
Male
1946
5
Per Arnoldi
Danish
Male
1941
 
이런 경우 artworks_artists 같은 중간 테이블을 만들어 artistsartworks가 서로와 직접 연결되지 않고 중간 테이블을 거쳐 연결되어야 합니다. 이 작업을 통해 다대다 관계가 해소되고 2개의 1:N 관계가 만들어졌습니다.
notion image
데이터 모델링을 하다보면 이런 상황이 매우 흔하게 발생합니다. 예를 들어, 데이터리안의 캠프와 수강생의 관계도 다대다 관계입니다. 한 캠프에 여러 명의 수강생이 있고 또 한 명의 수강생이 여러 캠프를 들을 수 있기 때문이죠. 이런 경우에도 수강생-캠프의 관계만 저장하는 artworks_artists 같은 테이블이 필요합니다. 저희 DB에는 course_registration이라는 이름의 테이블이 이 역할을 해주고 있습니다.
 
마지막으로 초보자의 입장에서 어려움을 느끼기 쉬운 다대다 관계까지 이야기를 해보았습니다. 다음 글에서는 지금까지 배운 내용을 종합하여 ERD를 그려보겠습니다.
 
 

참고 자료

PostgreSQL Tutorial - Database Constraints
 
윤선미데이터 분석가

어느새 7년차 데이터 분석가이고, 4년째 데이터 분석 교육을 하고 있습니다. 데이터리안 멤버들과 함께 일하면서 데이터의 힘을 더 믿게 되었습니다.

함께 읽어보면 좋은 글

주식회사 데이터리안