관계 데이터 모델: 릴레이션, 무결성 제약조건, 관계대수
관계 데이터 모델은 데이터를 행과 열로 이루어진 릴레이션으로 표현하는 논리적 데이터 모델이다. 하나의 개체에 관한 데이터는 하나의 릴레이션에 저장하고, 릴레이션 사이의 관계는 서로를 식별할 수 있는 값을 이용해 나타낸다.
이 글에서는 관계 데이터 모델의 기본 구조와 키, 무결성 제약조건, 관계대수의 주요 연산을 정리한다.
1. 릴레이션의 구성
릴레이션(relation)은 행과 열로 구성된 테이블이다. 릴레이션의 열은 속성(attribute), 행은 튜플(tuple)이라고 한다. 파일 관리 시스템의 용어와 비교하면 릴레이션은 파일, 속성은 필드, 튜플은 레코드에 대응한다.
예를 들어 고객 릴레이션에 고객아이디, 고객이름, 나이라는 열이 있다면 이 열들이 속성이다. 각 고객의 데이터가 들어 있는 한 행은 튜플이다.
스키마와 인스턴스
릴레이션은 스키마와 인스턴스로 구분한다.
릴레이션 스키마는 릴레이션의 논리적 구조다. 릴레이션의 이름과 포함된 속성의 이름으로 정의하며, 고객(고객아이디, 고객이름, 나이)처럼 표기할 수 있다. 속성이 가질 수 있는 값의 집합을 도메인(domain), 속성의 개수를 차수(degree)라고 한다.
릴레이션 인스턴스는 스키마에 따라 실제로 저장된 데이터의 집합이다. 인스턴스에 들어 있는 튜플의 수를 카디널리티(cardinality)라고 한다.
고객 데이터가 추가되거나 삭제되면 인스턴스와 카디널리티가 달라진다. 반면 고객 릴레이션에 어떤 속성이 있는지를 정의한 스키마는 자주 바뀌지 않는다.
릴레이션의 특징
릴레이션에는 다음과 같은 특징이 있다.
- 속성의 원자성: 각 속성은 하나의 원자값, 즉 단일값을 가진다. 이름 속성에 여러 이름을 한꺼번에 저장하는 방식은 적합하지 않다.
- 속성의 무순서성: 릴레이션에서 속성의 순서에는 의미가 없다.
- 속성의 동일성: 하나의 속성에는 정의된 도메인에 속하는 동일한 유형의 값이 들어간다.
- 튜플의 유일성: 하나의 릴레이션에 완전히 동일한 튜플이 중복해서 존재할 수 없다.
- 튜플의 무순서성: 릴레이션에서 튜플의 순서에는 의미가 없다.
2. 키의 종류
키(key)는 릴레이션의 튜플을 구별하는 속성 또는 속성의 집합이다. 키를 구분할 때는 유일성과 최소성을 확인한다.
유일성은 모든 튜플이 서로 다른 키 값을 가져야 한다는 뜻이다. 최소성은 튜플을 구별하는 데 필요한 속성만 키에 포함해야 한다는 뜻이다.
슈퍼키와 후보키
슈퍼키(super key)는 유일성을 만족하는 속성 또는 속성의 집합이다. 고객아이디만으로 고객을 구별할 수 있다면 고객아이디는 슈퍼키다. (고객아이디, 고객이름)도 각 고객을 구별할 수 있으므로 슈퍼키다.
후보키(candidate key)는 유일성과 최소성을 모두 만족하는 키다. 고객아이디만으로 고객을 구별할 수 있다면 (고객아이디, 고객이름)에는 불필요한 고객이름이 포함돼 있으므로 후보키가 아니다. 이 경우 고객아이디가 후보키가 될 수 있다.
후보키를 판단할 때는 현재 보이는 데이터에서 값이 우연히 다르다는 점만 볼 것이 아니라, 그 속성으로 튜플을 유일하게 구별할 수 있는지도 살펴봐야 한다.
기본키와 대체키
기본키(primary key)는 후보키 중에서 기본적으로 사용하기 위해 선택한 키다. 기본키는 NULL 값을 가질 수 없으며, 각 튜플을 유일하게 식별해야 한다.
후보키가 여러 개라면 기본키로 선택되지 않은 후보키를 대체키(alternate key)라고 한다. 즉, 대체키도 유일성과 최소성을 만족하지만 기본키로 사용되지는 않은 키다.
대리키: 주문번호로 이해하기
대리키(surrogate key)는 기존 속성만으로 적절한 기본키를 정하기 어렵거나, 기본키가 여러 속성으로 구성돼 복잡한 경우에 식별을 위해 인위적으로 만든 속성이다. 기본키로 사용할 값이 보안을 필요로 하는 경우에도 대리키를 사용할 수 있다.
수업자료의 예시는 주문번호다. 주문번호는 주문을 구별할 수 있도록 새로 부여한 번호다.
| 1 | carrot | 제품 A |
| 2 | carrot | 제품 B |
| 3 | apple | 제품 A |
이 표에서 주문고객만으로는 주문을 구별할 수 없다. carrot 고객의 주문이 두 건이기 때문이다. 주문제품만으로도 구별할 수 없다. 제품 A를 주문한 내역이 두 건이다. 고객과 제품을 묶어 사용하더라도 같은 고객이 같은 제품을 다시 주문하는 상황까지 생각하면 주문을 항상 구별할 수 있는 값으로 삼기 어렵다.
이때 주문마다 1, 2, 3처럼 별도의 주문번호를 부여하면 각 주문을 구별할 수 있다. 이 번호는 고객이나 제품의 특징을 나타내기 위해 존재하는 값이 아니라, 주문 한 건을 식별하기 위해 만든 값이다. 이것이 대리키의 핵심이다.
정리하면 기본키는 어떤 역할을 하는 키인가를 나타내고, 대리키는 그 값을 어떻게 마련했는가와 관련된 표현이다. 주문번호를 인위적으로 만들어 주문 릴레이션의 기본키로 선택했다면, 그 주문번호는 대리키이면서 기본키다.
외래키
외래키(foreign key)는 다른 릴레이션의 기본키를 참조하는 속성 또는 속성의 집합이다. 외래키를 이용해 릴레이션 사이의 관계를 표현한다.
고객과 주문 릴레이션을 예로 들면, 주문 릴레이션에 고객을 식별하는 값을 저장해 해당 주문이 어느 고객의 주문인지 나타낼 수 있다. 이때 주문 릴레이션처럼 외래키를 가진 쪽을 자식 릴레이션, 참조되는 기본키를 가진 고객 릴레이션을 부모 릴레이션이라고 한다.
외래키 속성과 참조하는 기본키 속성은 이름이 달라도 되지만 도메인은 같아야 한다. 외래키는 기본키와 달리 NULL이나 중복값을 가질 수 있다.
3. 무결성 제약조건
무결성은 데이터에 결함이 없고 정확하며 유효한 상태를 뜻한다. 데이터의 삽입·삭제·수정 이후에도 이 상태를 유지하기 위해 적용하는 규칙이 무결성 제약조건이다.
도메인 무결성
도메인 무결성 제약조건은 각 속성이 정의된 도메인에 속하는 값을 가져야 한다는 규칙이다. 데이터를 입력하거나 수정할 때 해당 속성에 허용되는 값인지 확인한다.
개체 무결성
개체 무결성 제약조건은 기본키가 NULL 값을 가지거나 중복돼서는 안 된다는 규칙이다. 기본키가 NULL이면 튜플을 식별할 수 없고, 같은 기본키 값이 여러 번 나타나면 서로 다른 튜플을 구별할 수 없다.
기본키가 여러 속성으로 구성된 복합키라면, 그 속성 중 일부도 NULL 값을 가질 수 없다. 수업자료의 학생 릴레이션 예시에서는 이미 존재하는 학번으로 학생을 추가하거나 학번을 NULL로 추가하는 경우가 거부된다.
참조 무결성
참조 무결성 제약조건은 외래키가 참조하는 관계를 올바르게 유지하기 위한 규칙이다. 자식 릴레이션의 외래키에 값이 있다면, 그 값은 부모 릴레이션에서 참조할 수 있어야 한다.
수업자료의 학생과 학과 릴레이션을 예로 들면, 학생의 학과코드에 3001을 넣으려는데 학과 릴레이션에 3001이라는 학과코드가 없다면 삽입이 거부된다. 존재하지 않는 학과를 참조하게 되기 때문이다. 학과 릴레이션에 해당 학과를 먼저 추가한 뒤에는 참조할 수 있다.
외래키에 NULL을 허용하도록 정의했다면 학과코드를 NULL로 두는 것은 가능하다. NULL은 부모 릴레이션에 존재하지 않는 값을 지정한 경우와 구분된다.
부모 릴레이션의 데이터를 삭제할 때도 참조 무결성을 확인해야 한다. 예를 들어 학생들이 참조하고 있는 학과를 삭제하면, 학생 릴레이션의 학과코드가 가리킬 대상이 사라질 수 있다. 수업자료에서는 이를 처리하는 옵션으로 다음을 제시한다.
- RESTRICT / NO ACTION: 부모 데이터의 삭제를 거부한다.
- CASCADE: 부모 데이터를 삭제할 때 자식 데이터도 함께 삭제한다.
- SET NULL / SET DEFAULT: 자식의 외래키를 NULL 또는 기본값으로 변경한다.
4. 관계대수
관계대수는 릴레이션에서 원하는 결과를 얻기 위해 수행할 연산의 과정을 표현하는 방법이다. 하나 이상의 릴레이션에 연산을 적용하며, 그 결과도 릴레이션이다. 따라서 어떤 연산의 결과에 다른 연산을 이어서 적용할 수 있다. 이를 폐쇄 특성이라고 한다.
집합 연산
릴레이션은 튜플의 집합이므로 집합 연산을 적용할 수 있다. 다만 합집합, 교집합, 차집합을 수행하려면 두 릴레이션이 합병 가능해야 한다. 두 릴레이션의 차수가 같고, 서로 대응되는 속성의 도메인이 같아야 한다.
- 합집합 R ∪ S: R 또는 S에 속하는 모든 튜플을 반환한다.
- 교집합 R ∩ S: R과 S에 공통으로 속하는 튜플을 반환한다.
- 차집합 R − S: R에는 있지만 S에는 없는 튜플을 반환한다.
합집합과 교집합은 R과 S의 순서를 바꿔도 결과가 같다. 차집합은 순서에 따라 의미가 달라지므로 R − S와 S − R을 구분해야 한다.
카티션 프로덕트(cartesian product)는 R의 각 튜플을 S의 모든 튜플과 연결해 가능한 조합을 만든다. R과 S의 튜플이 각각 3개라면 결과에는 3 × 3 = 9개의 튜플이 생긴다. 결과의 차수는 두 릴레이션의 차수를 더한 값이다.
셀렉션과 프로젝션
셀렉션(selection)은 릴레이션에서 조건을 만족하는 튜플, 즉 행을 추출한다. σ조건식(릴레이션)으로 나타낸다. 조건식에는 비교 연산자와 논리 연산자를 사용할 수 있다. 수업자료의 ‘등급이 gold이고 적립금이 2000 이상인 고객’을 찾는 것이 셀렉션의 예다.
프로젝션(projection)은 릴레이션에서 필요한 속성, 즉 열을 추출한다. π속성리스트(릴레이션)으로 나타낸다. 결과에 동일한 튜플이 생기면 중복 없이 한 번만 표시한다.
‘가격이 8,000원 이하인 도서의 이름과 출판사’를 구할 때는 먼저 가격 조건에 맞는 튜플을 셀렉션하고, 그 결과에서 도서이름과 출판사 속성을 프로젝션할 수 있다.
조인
조인(join)은 두 릴레이션에서 관련 있는 튜플을 연결하는 연산이다. 수업자료에서는 여러 종류의 조인을 다룬다.
세타조인은 =, ≠, <, > 등의 비교 연산자를 조건으로 사용한다. 세타조인 중 =를 사용하는 것이 동등조인이다. 동등조인 결과에는 양쪽 릴레이션의 조인 속성이 모두 나타난다.
자연조인은 값이 같은 튜플을 연결하고, 결과에서 중복되는 조인 속성을 제거한다. 공통 속성이 여러 개라면 해당 속성들의 값이 같은 튜플을 연결한다.
외부조인은 조인 조건에 맞지 않는 튜플도 결과에 포함하고, 대응되는 값이 없는 속성에는 NULL을 채운다. 왼쪽 릴레이션의 모든 튜플을 포함하는 왼쪽 외부조인, 오른쪽 릴레이션의 모든 튜플을 포함하는 오른쪽 외부조인, 양쪽 릴레이션의 모든 튜플을 포함하는 완전 외부조인이 있다.
세미조인은 두 릴레이션을 연결한 뒤 한쪽 릴레이션의 결과만 반환한다. 수업자료의 ‘주문한 적이 있는 고객의 데이터만 보기’가 예다. 주문 내역을 이용해 주문 여부를 확인하지만, 결과에는 고객 쪽 데이터만 남긴다.
디비전
디비전(division)은 주어진 조건을 모두 만족하는 대상을 찾을 때 사용하는 연산이다. R ÷ S로 나타내며, R은 S의 모든 속성을 포함해야 한다.
수업자료에서는 학생이 수강한 과목을 담은 StudentCourse와 전공 필수 과목을 담은 RequiredCourses를 사용한다. 이때 StudentCourse ÷ RequiredCourses는 전공 필수 과목을 모두 수강한 학생을 구한다.
두 릴레이션을 조인하면 학생이 수강한 과목 중 필수 과목과 일치하는 내역을 볼 수 있지만, 필수 과목을 일부만 수강한 학생도 나타날 수 있다. 디비전은 필수 과목 전체를 수강했는지를 확인한다는 차이가 있다.
5. 관계대수와 SQL
관계대수의 연산은 SQL 구문과도 연결해서 볼 수 있다. 셀렉션은 조건에 맞는 행을 찾는 WHERE, 프로젝션은 필요한 열을 선택하는 SELECT에 대응한다. 합집합은 UNION, 카티션 프로덕트는 CROSS JOIN, 조인은 JOIN ... ON으로 표현할 수 있다. ‘모든 조건을 만족하는 대상’을 찾는 디비전은 NOT EXISTS를 이용해 표현할 수 있다.
특정 고객이 주문한 제품을 찾는 경우에는 고객 릴레이션에서 이름이 일치하는 튜플을 선택하고, 주문 릴레이션과 조인한 뒤, 주문제품 속성만 추출하는 순서로 관계대수식을 구성할 수 있다.
소감
대리키가 이해가 잘 안가서, 추가 설명을 더 찾아봤다. SQL말고 관계대수 표현은 낯설어서 수업할때는 이해가 갔는데 막상 다시보니 어렵게 느껴졌다.
문제풀이

(3) 주문이 있는 판매원의 이름
정답
π_salesperson(Order)
풀이: 주문 한 건에는 그 주문을 담당한 판매원의 이름이 salesperson에 들어 있다. 따라서 Order에서 이 열만 추출하면 된다. 같은 판매원이 여러 건을 수주했더라도 관계대수의 프로젝션 결과에는 이름이 중복해서 나오지 않는다.
(4) 주문이 없는 판매원의 이름
정답
π_name(Salesperson) - π_salesperson(Order)
풀이: 전체 판매원 이름에서 주문에 한 번이라도 등장한 판매원 이름을 빼면 된다. 왼쪽과 오른쪽이 모두 ‘판매원 이름 한 열’이므로 차집합으로 표현할 수 있다.
(5) 고객 ‘홍길동’의 주문을 수주한 판매원의 나이
정답
π_age(Salesperson ⋈_{Salesperson.name = Order.salesperson} σ_{custname = '홍길동'}(Order))
풀이: 먼저 Order에서 custname이 ‘홍길동’인 주문을 고른다. 그 주문의 salesperson과 Salesperson.name을 연결하면 담당 판매원 정보를 찾을 수 있다. 마지막으로 age만 추출한다.
(6) 나이가 25세인 판매원에게 주문한 고객의 city 값
정답
π_city((σ_{age = 25}(Salesperson) ⋈_{Salesperson.name = Order.salesperson} Order) ⋈_{Order.custname = Customer.name} Customer)
풀이: 나이가 25세인 판매원을 먼저 선택한다. Order와 연결해 그 판매원이 받은 주문을 찾고, 다시 Customer와 연결해 주문한 고객을 찾는다. 최종적으로 고객의 city를 추출한다.
(7) 판매원 이름과 그 판매원에게 주문한 고객 이름 — 주문이 없는 판매원도 포함
정답
π_{Salesperson.name, Order.custname}(Salesperson ⟕_{Salesperson.name = Order.salesperson} Order)
풀이: 왼쪽 외부조인을 사용해야 한다. Salesperson을 왼쪽에 두면 주문이 없는 판매원도 결과에 남는다. 그런 판매원은 대응되는 주문이 없으므로 고객 이름 자리인 Order.custname이 NULL로 표시된다. 일반 조인을 쓰면 주문이 없는 판매원이 결과에서 빠진다.
연습문제 10개

풀이 및 해설
릴레이션에서 차수(degree)는 릴레이션을 구성하는 속성(attribute)의 개수를 의미한다.

풀이 및 해설
튜플의 개수는 카디널리티 이다.

풀이 및 해설
표 전체가 하나의 릴레이션이므로
릴레이션 = 1개이다.
열을 보면
고객ID / 고객이름 / 나이
총 3개이므로 속성 = 3개이다.
실제 데이터 행은 C01부터 C05까지 총 5개이므로
튜플 = 5개이다.
따라서
릴레이션 1개 + 속성 3개 + 튜플 5개
이므로 정답은 ④번이다.

풀이 및 해설
여기서 카디널리티는 튜플의 개수를 의미한다.
따라서 후보키가 몇 개인지, 속성이 몇 개인지는 카디널리티를 구할 때 관계없다.
튜플이 10개라고 했으므로 카디널리티 = 10이다. 따라서 정답은 ③번이다.

풀이 및 해설
(A) O
릴레이션에서는 동일한 튜플이 중복해서 존재하지 않는다.
(B) O
릴레이션에서 튜플의 순서는 의미가 없다.
어떤 튜플이 첫 번째 행에 있다고 해서 두 번째 행보다 더 중요하다는 의미가 아니다.
(C) O
하나의 릴레이션 안에서 각각의 속성은 이름을 통해 구별된다.
(D) X
속성의 순서는 중요한 의미를 갖지 않는다.
예를 들어 학생(학번, 이름, 학과)와 학생(이름, 학과, 학번)
처럼 순서를 바꿨다고 해서 데이터 자체의 의미가 달라지는 것은 아니다.
(E) O
관계 데이터 모델에서 속성값은 원자 값(atomic value)을 가져야 한다.
따라서 정답은 (A), (B), (C), (E)이다.

풀이 및 해설
먼저 슈퍼키는 튜플을 유일하게 구별할 수 있는 속성 또는 속성의 집합이다.
즉, 유일성을 만족한다.
그런데 슈퍼키 중에서 불필요한 속성을 제거하고도 튜플을 구별할 수 있는 키를 후보키라고 한다.
따라서 후보키는 유일성 + 최소성을 만족해야 한다.
후보키가 여러 개라면 그중 하나를 선택하여 기본키(primary key)로 사용한다.
그리고 기본키로 선택되지 않은 나머지 후보키를 대체키(alternate key)라고 한다.
따라서
슈퍼키 → 유일성
후보키 → 유일성 + 최소성
기본키 → 후보키 중 선택
대체키 → 후보키 중 기본키로 선택되지 않은 키 이다.

풀이 및 해설
개체 무결성은 기본키와 관련된 규칙이다.
기본키는 각각의 튜플을 식별해야 하기 때문에 기본키가 NULL이면 안 된다.
따라서 기본키는 NULL 값을 가질 수 없다 → 개체 무결성이다.
반면 참조 무결성은 외래키와 관련된다.
예를 들어
학생(학번, 이름, 학과코드)
학과(학과코드, 학과명)
이라는 두 릴레이션이 있고 학생의 학과코드가 학과 릴레이션을 참조한다고 생각해보자.
학생의 학과코드가 C001이라면 학과 릴레이션에도 C001이 실제로 존재해야 한다.
존재하지 않는 학과코드를 학생이 참조하면 안 된다.
따라서 기본키 NULL 금지 → 개체 무결성 외래키의 올바른 참조 → 참조 무결성으로 구분하면 된다.

풀이 및 해설
셀렉트 연산은 릴레이션에서 주어진 조건을 만족하는 튜플을 선택하는 연산이다.

풀이 및 해설
PROJECT 연산은 릴레이션에서 원하는 속성만 선택하는 연산이다.
예를 들어 학생(학번, 이름, 학과, 학년)
이라는 릴레이션에서 이름과 학과만 필요하다면 PROJECT 연산을 사용한다.

풀이 및 해설
카티션 프로덕트는 두 릴레이션의 모든 튜플을 서로 조합하는 연산이다.
먼저 차수부터 계산한다.
R의 차수 = 5
S의 차수 = 3
카티션 프로덕트를 하면 두 릴레이션의 속성이 합쳐지므로
5 + 3 = 8
따라서 결과 릴레이션의 차수는 8이다.
이번에는 카디널리티를 계산한다.
R의 카디널리티 = 8
S의 카디널리티 = 6
R의 튜플 하나마다 S의 6개 튜플이 모두 결합한다.
따라서 8 × 6 = 48 이 된다.
즉, 차수 = 5 + 3 = 8 카디널리티 = 8 × 6 = 48
따라서 정답은 ② 8, 48이다.
'데이터베이스시스템특론' 카테고리의 다른 글
| 1.데이터베이스시스템 (1) | 2026.09.15 |
|---|
