- 관계 대수와 관계 해석의 공통점과 차이점
- 관계 대수의 종류
- 우리가 관계 대수와 관계 해석을 알아야 하는 이유
- 조인의 종류
관계 데이터 연산의 개념
연산(operation)은 원하는 데이터를 얻기 위해 릴레이션에서 필요한 처리 요구를 수행하는 것이다.
관계 데이터 모델의 연산은 크게 두 가지로 나뉜다.

- 관계 대수 (relational algebra) - What + How
관계 대수는 수학적인 기법을 이용하여 데이터를 처리한다.
일련의 연산을 통해 데이터를 추출하고 조작하는데, 관계형 데이터베이스의 테이블과 열을 수학적으로 다룬다.
관계 대수로 원하는 결과를 얻기 위해선 데이터의 처리 과정을 순서대로 기술하기 때문에 절차 언어(procedural language)라고 한다.
- 관계 해석 (relational calculus) - What
관계 해석은 논리적 접근 방식으로 데이터를 처리한다.
논리적인 조건을 지정하여 데이터를 필터링하고 추출한다. 일반적으로 SQL과 같은 질의 언어에서 사용된다.
관계 해석은 원하는 결과를 얻기 위해 원하는 데이터가 무엇인지만 기술하기 때문에 비절차 언어(nonprocedural language)라고 한다.
우리가 관계 대수와 관계 해석을 이해해야 하는 이유
관계 대수와 관계 해석은 개념적 언어이기 때문에 사용자가 실제로 많이 사용하진 않는다. 그러나 관계 대수와 관계 해석은 관계형 데이터베이스에서 데이터를 추출하고 관리하는 기본 개념이기 때문에 알면 장점이 많다. 만약 새로운 데이터 언어가 등장한다면 그 언어와 기술의 기반이 되는 개념이어서 습득에 수월할 것이다.
또한 관계 대수는 데이터베이스 쿼리 최적화에 중요한 역할을 한다. 따라서 관계 대수를 이해하면 데이터베이스 쿼리를 최적하하여 효율적으로 데이터베이스를 사용할 수 있다.
관계 대수
원하는 결과를 얻기 위해 릴레이션을 처리하는 과정을 순서대로 기술하는 언어
일반적으로 연산의 대상이 되는 피연산자가 필요한데, 관계 대수에서의 피연산자는 릴레이션이다. 즉 관계 대수를 통해 릴레이션 간의 연산을 수행할 수 있다. 그래서 관계 대수로 연산한 결과는 무조건 릴레이션이 된다. 이러한 특성을 폐쇄 특성(closure property)라고 한다.
콩 심은 데 콩나고, 릴레이션 심은 데 릴레이션 난다
관계 대수는 대표적으로 8개의 연산자가 있다. 이를 두 개로 분류한다.
- 일반 집합 연산자 (set operation)
- 순수 관계 연산자 (relational operation)

일반 집합 연산자
릴레이션은 튜플들의 집합이다. 따라서 수학의 집합 연산자를 이용하면 원하는 결과를 도출할 수 있다.
합집합, 교집합, 차집합 모두 지켜야 하는 중요한 제약조건이 있다.
(1) 연산에 필요한 릴레이션은 2개
(2) 합집합, 교집합, 차집합 연산은 릴레이션이 합병 가능해야 함 - 두 릴레이션의 차수와 도메인이 동일!
합집합, 교집합 차집합 연산을 수행하면 두 릴레이션을 위 아래로 합병하기 때문에 속성의 개수(차수)와 속성의 데이터 타입(도메인)이 똑같아야 한다. 차수 또는 도메인이 다르다면 합병이 불가능해서 일반 관계 연산은 할 수 없다.
합병이 가능하다 = 차수 동일 + 도메인 동일
대신 특별히 카티션 프로덕트는 합병 조건, 즉 차수 및 도메인과 상관없이 가능하다.

합집합 ( ∪ )
합병이 가능한 두 릴레이션 R과 S의 합집합(union)은 R ∪ S 로 표현한다.
릴레이션 R에 속하거나 릴레이션 S에 속하는 모든 튜플로 결과 릴레이션을 구성한다. 중복되는 튜플은 한 번만 나타난다. 릴레이션은 동일한 튜플을 가질 수 없다는 특성을 기억하고 있는가?

합집합 연산을 한 후 얻게 되는 결과 릴레이션의 차수는 릴레이션 R과 S의 차수와 같고, 카디널리티는 R과 S의 튜플 개수를 더한 것과 같거나 적어진다.
교집합 ( ∩ )
합병이 가능한 두 릴레이션 R과 S의 교집합(intersection)은 R ∩ S 로 표현한다.
릴레이션 R과 S에 공통으로 속하는 튜플로 결과를 구성한다. 릴레이션은 동일한 튜플을 가질 수 없다는 특성을 기억하고 있는가?

교집합 연산을 한 후 얻게 되는 결과 릴레이션 차수는 피연산자인 릴레이션 R과 S의 차수와 같다. 카디널리티는 릴레이션 R과 S의 카디널리티보다 작거나 같다.
차집합 ( - )
합병이 가능한 두 릴레이션 R과 S의 차집합(difference)은 R - S 로 표현한다.
R - S는 릴레이션 R에는 존재하지만 릴레이션 S에는 존재하지 않는 튜플들로 결과 릴레이션을 구성한다. S - R는 릴레이션 S에는 존재하지만 릴레이션 R에는 존재하지 않는 튜플들로 결과 릴레이션을 구성한다.

차집합 연산을 한 후 얻게 되는 결과 릴레이션의 차수는 릴레이션 R과 S의 차수와 같다. 카디널리티는 릴레이션 R이나 릴레이션 S의 카디널리티와 같거나 적다.
차집합 연산은 피연산자의 순서에 따라 결과 릴레이션이 달라진다.
카티션 프로덕트 ( X ) - 교차곱
두 릴레이션 R과 S의 카티션 프로덕트(cartesian product)은 R X S 로 표현한다.
릴레이션 R에 속한 각 튜플과 릴레이션 S에 속한 각 튜플을 모두 연결하여 만들어진 새로운 튜플로 결과 릴레이션을 구성한다.

카티션 프로덕트의 결과 릴레이션은 합집합, 교집합, 차집합과 다르게 '가로'로 확장되어 만들어진다. 그래서 두 릴레이션의 도메인이 동일하지 않아도 된다. 즉 두 릴레이션이 합병이 불가능한 경우에도 카티션 프로덕트 연산은 가능하다.
카티션 프로덕트 연산을 한 후 얻게 되는 결과 릴레이션의 차수는 피연산자인 릴레이션 R과 S의 차수를 더한 것과 같다. 결과 릴레이션의 카디널리티는 두 릴레이션의 카디널리티를 곱한 값이 된다.
순수 관계 연산자
관계 데이터 모델에서 새로 제시된 개념으로써, 릴레이션의 구조와 특성을 이용한다. 순수 관계 연산자를 통해 릴레이션에 저장되어 있는 데이터를 다양하게 처리하는 데 자주 사용된다.

SELECT ( σ )
σ 조건식 (릴레이션)
릴레이션에서 조건을 만족하는 튜플(행)을 구하는 연산
릴레이션의 모든 튜플 중 조건식을 참으로 만드는 일부분의 튜플들만 선택하기 때문에 결과 릴레이션은 주어진 릴레이션을 수평으로 절단한 모양이 된다.
셀렉트 연산은 하나의 릴레이션을 대상으로 수행한다. 조건식엔 비교 연산자( >, <, >=, <=, =, !=)를 이용함으로 비교를 하기 위해서 상수의 데이터 타입이 속성의 도메인과 일치해야 한다. 다른 속성들 간의 비교로 구성할 때는 속성들의 도메인이 같아야 비교가 가능하다.
비교 연산자뿐만 아니라 논리 연산자(AND(∧), OR(∨), NOT(ㄱ))를 사용해서 조건식을 더 복잡하게 구성할 수도 있다.


셀렉트 연산은 교환적 특징이 있기 때문에 여러 조건들의 순서를 바꿔도 동일한 결과를 도출한다.
PROJECT ( π )
π 속성리스트 (릴레이션)
릴레이션에서 주어진 속성(열)들의 값으로만 구성된 튜플을 구하는 연산
결과 릴레이션이 주어진 릴레이션의 일부 열로만 구성되어 해당 릴레이션에서 수직적 부분집합을 생성하는 것과 같다.

위 예시에서 "등급" 속성을 프로젝트 연산한 결과를 보면 카디널리티가 3이다. 그 이유는 모든 튜플은 중복되선 안된다는 기본적인 특성 때문에 등급 속성만 추출하였을 경우 gold 등급이 중복되어서 하나는 삭제되어 추출된다.
프로젝트는 릴레이션의 모든 속성 중 일부분만 선택하는데, 속성은 릴레이션에서 열에 해당되므로 프로젝트는 대상 릴레이션의 수직적 부분집합으로 결과 릴레이션을 구성하는 수직적 연산자이다.

JOIN ( ▷◁ )
1) 동등 조인 (equi - join)
릴레이션 1 ▷◁ 릴레이션 2
공통 속성을 이용해 두 릴레이션의 튜플들을 연결하여 생성된 튜플을 구하는 연산
하나의 릴레이션으론 원하는 데이터를 얻을 수 없는 경우가 있다. 관계가 있는 여러 릴레이션을 함께 사용해야 하는 경우에 조인 연산을 이용한다.
조인 연산의 결과는 두 릴레이션에 대해 카티션 프로덕트 연산을 수행한 후, 조인 속성의 값이 값은 조건을 만족하는 튜플을 반환하는 셀렉트 연산을 수행한 것과 같다. 조인 속성 두 릴레이션이 공통으로 가지고 있는 속성으로, 두 릴레이션이 관계가 있음을 나타낸다.
카티션 프로덕트 연산 + 셀렉트 연산(조건 : 공통된 조인 속성의 값)
= 조인 연산

위 예시를 보면 주문 릴레이션의 "고객아이디" 속성은 외래키로 고객 릴레이션의 기본키를 참조하고 있다. 그래서 "고객아이디" 속성은 두 릴레이션에 공통으로 존재하는 조인 속성이다. 두 릴레이션을 조인할 때는 조인 속성의 값이 같은 투플만 연결하여 결과 릴레이션을 구성해야 한다.

조인 속성 값이 같은 튜플끼리만 연결하여 새로운 릴레이션을 구성하기 때문에 고객아이디의 "orange" 튜플은 조인 연산에서 제외된다.
2) 세타 조인 (theta - join)
릴레이션 1 ▷◁ AΘB 릴레이션 2
주어진 조인 조건을 만족하는 두 릴레이션의 모든 튜플을 연결한 새로운 튜플로 새로운 릴레이션을 구성
AΘB는 조인 조건으로서 A는 릴레이션 1의 속성, B는 릴리에션 2의 속성이다. Θ는 비교 연산자( >, <, >=, <=, =, !=)다. 비교를 위해서 A와 B는 동일한 도메인이어야 한다.
위에서 본 동등 조인을 세타 조인으로 표현할 수 있다. 두 속성이 동일한 조건을 의미하기 때문에 릴레이션 1 ▷◁A=B 릴레이션 2와 동일하다.
세타 조인 연산을 한 후 얻게 되는 결과 릴레이션의 차수는 릴레이션 1의 차수와 릴레이션 2의 차수를 더한 것과 같다.
3) 자연 조인 (natural - join)
릴레이션 1 ▷◁ N 릴레이션 2
동등 조인의 결과 릴레이션에서 중복된 속성을 제거하여 조인 속성이 한 번만 나타나게 함
동등 조인의 연산 결과 릴레이션에는 두 릴레이션의 모든 속성이 포함되기 때문에 조인 속성이 중복되어 나타난다. 만약 동등 조인의 결과 릴레이션에서 조인 속성이 중복되지 않고 한 번만 표현되도록 하고 싶으면 자연 조인 연산을 수행하면 된다.

원래의 동등 조인이었다면 "고객 아이디" 속성이 중복되어 등장했을 것이지만, 중복 속성이 제거되어 한 번만 표현된다.
4) 세미 조인 (semi - join)
릴레이션 2의 조인 속성으로만 구성한(프로젝트한) 릴레이션을 릴레이션 1에 자연 조인 하는 것
두 릴레이션 R과 S의 세미 조인 연산은 아래와 같이 표현한다.

세미 조인은 릴레이션 S를 릴레이션 R에 조인하기 전에 먼저 S의 조인 속성을 프로젝트 연산을 수행한다. 그렇게 S의 조인 속성만 남긴 후 릴레이션 R에 조인한다.

자연 조인을 하면 두 릴레이션의 모든 속성을 결합하기 때문에 불필요한 속성까지 연산하게 된다. 하지만 세미 조인은 프로젝트 연산으로 조인 속성만 남긴 뒤 자연 조인을 수행함으로 조인 연산의 비용을 줄일 수 있는 장점이 있다.
위 예시에도 주문 릴레이션의 "주문번호", "주문제품" 속성을 날린 뒤 고객 릴레이션과 조인한다. 따라서 주문을 한 적 있는 고객의 데이터만 검색이 가능하다.
세미 조인은 교환적 특성이 없어 연산 순서에 따라 다른 결과를 도출한다는 점에 주의해야 한다.
5) 외부 조인 (outer - join)
원래 조인 연산은 상대 릴레이션에 존재하지 않으면 조인 연산에서 제외되는데, 외부 조인은 모든 튜플을 결과 릴레이션에 포함하는 것
조인 연산에서 제외된 튜플을 포함해 모든 튜플을 결과 릴레이션으로 가져오고 자 하는 릴레이션이 무엇이냐에 따라 왼쪽, 오른쪽, 완전 외부 조인으로 구분할 수 있다.



- 왼쪽 외부 조인 (left - outer - join) : 왼쪽에 있는 릴레이션에 존재하는 모든 튜플을 결과 릴레이션에 포함 시킨다.
- 오른쪽 외부 조인 (right - outer - join) : 오른쪽에 있는 릴레이션에 존재하는 모든 튜플을 결과 릴레이션에 포함 시킨다.
- 완전 외부 조인 (full - outer - join) : 연산에 참여하는 두 릴레이션에 있는 모든 튜플을 결과 릴레이션에 포함시킨다.
세타 조인 : 주어진 조인 조건을 만족하는 두 릴레이션의 모든 튜플을 연결하여 새로운 릴레이션 구성
동등 조인 : 세타 조인에서 '=' 연산자를 이용해 조인 조건을 표현
자연 조인 : 동등 조인의 결과 릴레이션에서 중복된 속성을 제거
세미 조인 : 프로젝트 연산으로 불필요한 릴레이션의 속성을 제거한 후, 자연 조인을 수행
외부 조인 : 조인 연산에서 제외되었던 모든 튜플을 결과 릴레이션에 포함
만약 두 릴레이션의 관계를 의미하는 조인 속성이 여러 개의 속성으로 구성되어 있다면 어떨까? 그러면 두 릴레이션의 속성 값의 쌍이 값이 같은 튜플만 조인 연산에 참여하게 된다.

DIVISION ( ÷ )
릴레이션 1 ÷ 릴레이션 2
나누어지는 릴레이션에서 나누는 릴레이션의 모든 튜플과 관련이 있는 튜플을 구하는 연산
릴레이션 R과 S의 디비전 연산은 R ÷ S으로 표현한다. 이것은 릴레이션 S의 모든 튜플과 관련 있는 릴레이션 R의 튜플로 결과 릴레이션을 구성한다는 의미다. 이 연산을 가능케하려면 릴레이션 S의 모든 속성과 도메인이 같은 속성을 릴레이션 R이 가지고 있어야 한다.
디비전 연산은 정수의 나눗셈과 비슷하다. 12 ÷ 2은 6이다. 12는 2와 6을 곱한 값이기 때문에 나누는 수인 2를 제외한 6이 결과 값이 된다. 이처럼 12를 R로, 2를 S로 보고 이해하면 이해가 쉽다.

위 예시는 고객 릴레이션과 우수등급 릴레이션의 디비전 연산 결과이다. 등급이 gold인 모든 고객의 고객아이디, 고객이름, 나이, 직업, 적립금을 검색하는 것과 같다.

또 다른 예시이다. 제품1 릴레이션에서 "진짜 우동", "그대로만두"를 모두 주문한 고객아이디와 제조업체를 검색한다. 제품2 릴레이션에선 제품이름이 "그대로만두"인 동시에 제조업체가 "한빛식품"인 주문고객을 검색하는 것과 의미가 같다.
'일반 집합 연산자'와 '순수 관계 연산자'의 차이
일반 집합 연산자, 순수 관계 연산자 둘 다 관계 대수에서 사용되는 연산자이다.
일반 집합 연산자는 두 개의 릴레이션(테이블)에서 집합 연산을 수행하고, 결과적으로 새로운 릴레이션을 생성한다.
순수 관계 연산자는 릴레이션에서 행들을 선택하거나 제거하는 등의 조작을 수행한다. 따라서 릴레이션을 변경하는 것이 아니라, 릴레이션에서 필요한 결과를 선택하거나 제거하는 일을 수행한다. 이러한 연산자들은 SQL에서 WHERE, GROUP BY, HAVING, ORDER BY 등의 절에서 사용된다.
- 일반 집합 연산자는 두 개의 릴레이션을 조작하여 새로운 릴레이션을 생성.
- 순수 관계 연산자는 릴레이션에서 행들을 선택하거나 제거하는 등의 조작을 수행.
관계 대수를 이용한 질의 표현
사용자 질의는 복잡하기 때문에 대부분 여러 연산자를 함께 사용하는 경우가 많다.

위 예시를 이용해서 복잡한 관계 대수 연산자를 연습해보자!

관계 해석
처리를 원하는 데이터가 무엇인지만 기술하는 비절차 언어로, 관계 대수처럼 관계 데이터 연산의 한 종류다.
데이터를 처리하는 기능과 처리를 요구하는 표현력에서 관계 대수와 관계 해석은 능력이 모두 동일하다.
'데이터 베이스' 카테고리의 다른 글
| Ch.8 데이터베이스 설계 [데이터베이스 개론] (0) | 2023.05.12 |
|---|---|
| Ch.7 데이터베이스 언어 SQL [데이터베이스 개론] (0) | 2023.04.26 |
| Ch.5 관계 데이터 모델 [데이터베이스 개론] (0) | 2023.04.25 |
| Ch.4 데이터 모델링 [데이터베이스 개론 도서] (1) | 2023.04.21 |
| Ch.3 데이터베이스 시스템 [데이터베이스 개론 도서] (0) | 2023.04.20 |