이번 주제는 관계대수와 관계해석입니다.
일단 먼저 관계대수라는 단어의 뜻부터 알아보자면,
관계대수란?
일단 '관계대수' 라는 말 자체는
컴퓨터과학에서만 쓰이는 용어입니다.
관계대수는
관계형 데이터베이스의 관계 모델에서
'집합론' 과 '1차 논리' 에 기반해서
관계표로 표현된 데이터를 취급하는
대수적인 연산 체계를 말합니다.
말이 너무 어려운데,
쉽게 얘기해서 우리가 어떤 형식의 표를 작성하면,
그 표에 입력된 항목과
각 항목에는 임의의 값들이 존재하는 형식으로 작성할 것인데,
이러한 항목이나 값, 또는 표 자체를 데이터로 취급하고,
이 데이터들이 어떤식으로 서로 연관됐는지를
표현하기 위해 만들어진 연산자 라고 생각하시면 됩니다.
예시 1) <축구선수>
번호 | 이름 | 나이 | 연봉(억) | 팀명 |
7 | 손흥민 | 31 | 165 | 토트넘 핫스퍼 |
19 | 이강인 | 23 | 57 | 파리 생제르맹 |
3 | 김민재 | 27 | 170 | 바이에른 뮌헨 |
11 | 황희찬 | 28 | 26 | 울버햄튼 |
이런식으로 작성된 표가 있다고 치면,
번호, 이름, 나이, 연봉 이라는 각 집합이 있고
그것들은 각자 원소들을 갖고있습니다.
이런 집합들이 서로 어떤 관계를 갖고 있는지를
식으로써 나타내기 위해,
대수 = 숫자를 대신해서 나타내는 것이기 때문에,
관계대수 라고 표현합니다.
이상하지만, 이 관계대수에서는
위 예시의 <축구선수> 표 자체를 "관계 (Relation)" 라고 부릅니다.
관계표 라고 부르면 이해하기 좀 편할텐데,
한글자라도 더 줄이고 싶었나 봅니다.
이러한 관계대수에는,
순수 관계 연산자와 일반 집합 연산자가 있습니다.
순수 관계 연산자 : Select, Project, Join, Division
순수 관계 연산자는 관계형 데이터베이스에서
데이터 간의 관계를 설명하기 위해 따로 개발한 연산자 입니다.
Select
셀렉트는 릴레이션에 있는 튜플 중에서,
내가 선택한 조건을 만족하는 부분집합으로
새로운 릴레이션을 만드는 연산 입니다.
표기는 σ (sigma : 시그마) 라는 그리스 문자를 사용합니다.
*튜플은 관계에서 값들이 들어있는 행 (가로줄) 을 말합니다.
따라서,
σ 연봉>=100억 (축구선수)
라는 Select 연산을 수행한다면,
번호 | 이름 | 나이 | 연봉(억) | 팀명 |
7 | 손흥민 | 31 | 165 | 토트넘 핫스퍼 |
3 | 김민재 | 27 | 170 | 바이에른 뮌헨 |
이러한 새로운 릴레이션이 만들어지게 됩니다.
셀렉트의 연산에는, 비교 연산자와 논리 연산자를 이용할 수 있습니다.
비교 연산자 종류 : =, != (not equal), <, <=, >, >=
논리 연산자 종류 : AND(∧), OR(∨), NOT (ㄱ)
*개인적인 생각으론 AND 의 A 와,
OR 의 소문자 r 로써 기억하면 쉬운 것 같습니다.
Project
프로젝트는 셀렉트가 가로줄을 추려냈다면,
이건 세로줄을 추려내는 거라고 생각하시면 됩니다.
세로줄 집합을 각각 속성 (Attribute) 이라고 부르고,
연산 기호는 역시 그리스 문자 𝝅 (pie : 파이) 를 사용합니다.
릴레이션에는 각 행을 구분짓는 키가 존재하는데,
혹여나 각 튜플의 다른 모든 속성의 값이 같은 값이더라도,
키 값은 같을 수 없기 때문에
릴레이션 내에서 튜플은 중복이 존재하지 않습니다.
그래서 셀렉트 연산을 수행할 때에는,
연산 조건에 해당하는 튜플을 추려내면 끝이었습니다.
그러나, 프로젝트 연산을 수행하면
하나의 집합 (열 : 세로줄) 에는 중복된 값이 존재할 수 있습니다.
예컨데, 손흥민과 김민재의 연봉과 등번호가 같을 수 있는데,
프로젝트 연산의 조건을
<축구선수> 관계에서 연봉과 등번호만 추려낸다고 하면
같은 연봉과 등번호 값이 중복되는 튜플이 만들어지게 됩니다.
따라서, 프로젝트에서는 새로 만들어진 릴레이션에서
중복되는 값은 제거한 결과 릴레이션이 만들어지게 됩니다.
다시 한 번 예를 들어,
예시 2) <동네주민>
키(key) | 이름 | 나이 | MBTI | 주민번호 |
1 | 김자바 | 30 | INFP | 900101-1234567 |
2 | 이봄 | 20 | ESTJ | 010101-4321234 |
3 | 박대수 | 30 | INFP | 701212-1312321 |
4 | 제갈수희 | 20 | ESTJ | 880330-4567890 |
이라는 표가 있고,
𝝅 나이, MBTI (동네주민)
이라는 Project 연산을 수행하는데
중복을 제거하지 않는다면,
나이 | MBTI |
30 | INFP |
20 | ESTJ |
30 | INFP |
20 | ESTJ |
이런 식으로 중복값이 발생하고,
릴레이션에 존재하는 튜플에는
중복값이 존재할 수 없기 때문에,
중복을 제거한 올바른 연산을 수행한다면,
나이 | MBTI |
30 | INFP |
20 | ESTJ |
이러한 릴레이션이 만들어지게 됩니다.
Join
조인은 공통된 속성을 가진 릴레이션끼리 합쳐서
새 릴레이션을 만드는 연산 입니다.
연산자의 기호는 ▷◁ 를 사용합니다.
예시 3) <운동선수>
이름 | 특기 | 나이 |
강호동 | 씨름 | 53 |
이만기 | 씨름 | 60 |
김동현 | 격투기 | 42 |
추성훈 | 격투기 | 48 |
예시 4) <방송인>
이름 | 채널 | 방송 |
강호동 | JTBC | 아는 형님 |
김동현 | TVN | 놀라운 토요일 |
추성훈 | KBS | 슈퍼맨이 돌아왔다 |
유재석 | MBC | 놀면 뭐하니? |
이런 두 릴레이션이 있다고 치고
Join 연산을 수행하면
(운동선수)▷◁이름(방송인)
이라고 명시할 것이고,
이름 | 종목 | 나이 | 채널 | 방송 |
강호동 | 씨름 | 53 | JTBC | 아는형님 |
김동현 | 격투기 | 42 | TVN | 놀라운 토요일 |
추성훈 | 격투기 | 48 | KBS | 슈퍼맨이 돌아왔다 |
이런식의 새 릴레이션이 만들어집니다...만,
이건 사실 네츄럴 조인 (Natural Join) 이라는
조인의 종류 중에 하나로써
정처기에서 주로 다뤄지는 개념이고,
조인에는 여러 종류가 있습니다.
일단 위와 같이 중복되는 속성을 토대로 조인하는 것은
자연 조인(Natural Join) 이라고 합니다.
운동선수에 포함되지 않은 '유재석' 튜플과,
방송인에 포함되지 않은 '이만기' 튜플은 제외하고,
중복되는 튜플들끼리 조인한 것입니다.
MySQL 에서는 기본적으로 조건을 걸지 않고
테이블 끼리 조인하면
교차곱 형태의 릴레이션을 만들어서 보여줍니다.
참고로 정처기에서는 또 쓸데없이 어려운 말을 쓰는데,
차수를 물어보면 속성의 개수이고,
카디널리티 라고 하면 튜플의 개수입니다.
따라서 위 조인된 릴레이션의 카디널리티는 3, 차수는 5이고,
조건을 걸지 않은 기본 Join 연산의 결과는,
차수는 릴레이션 속성간의 합.
카디널리티는 릴레이션 튜플간의 곱. 입니다.
이 외의 조인 연산 방식들은 별도의 글을 작성해서
나~~중에 다시 한 번 다뤄보겠습니다.
(시간이 없어서요 흑흑..)
Division
디비젼은 사실 나누기 보다는 빼기가 더 어울리긴 하지만,
아래에서 다루게 될 빼기와는 약간 다릅니다.
디비젼은 속성이 X ⊃ Y 인 두 개의 릴레이션 R(X), S(Y) 가 있을 때,
R(X) 에서 S(Y) 를 제외한 새 릴레이션을 만드는 연산입니다.
R(X) 와 S(Y) 는 별 의미 없는 이름입니다. R 은 relation, S 는 sub 에서 땄습니다.
( ⊂, ⊃ 기호는 '포함한다' 는 뜻의 Contain 에서 비롯됐고,
X ⊃ Y 는 'X contains Y' 라고 읽습니다. 궁금하실까봐,
반대의 경우엔 X ⊂ Y 는 'X is contained in Y' 라고 읽습니다. )
연산 기호로는 ÷ 를 사용합니다.
예시 5) <종합 예능인>
이름 | 종목 | 나이 | 채널 | 방송 |
강호동 | 씨름 | 53 | JTBC | 아는 형님 |
이만기 | 씨름 | 60 | null | null |
김동현 | 격투기 | 42 | TVN | 놀라운 토요일 |
추성훈 | 격투기 | 48 | KBS | 슈퍼맨이 돌아왔다 |
유재석 | 진행 | 51 | MBC | 놀면 뭐하니? |
예시를 만들기 힘들어서...
위에 조인했던 릴레이션을 빌려서 다시 쓰겠습니다.
예시 6) <스포츠 종목>
종목 |
씨름 |
격투기 |
이런 릴레이션이 있다면,
(종합 예능인) [ 종목 ÷ 종목 ] (스포츠 종목)
이라는 릴레이션은 아래처럼 만들어집니다.
이름 | 나이 | 채널 | 방송 |
강호동 | 53 | JTBC | 아는 형님 |
이만기 | 60 | null | null |
김동현 | 42 | TVN | 놀라운 토요일 |
추성훈 | 51 | KBS | 슈퍼맨이 돌아왔다 |
이름 = '유재석' 의 종목인 진행이 <스포츠 종목> 릴레이션에
포함되지 않았기 때문에, 포함된 튜플만으로 이루어진 릴레이션이 만들어집니다.
일반 집합 연산자 : Union, Intersection, Difference (Minus), Cartesian Product
일반 집합 연산자는 우리가 학교 다닐적에 배운 집합과 같은 개념입니다.
일반 집합 연산자를 사용하기 위해선 제약 사항이 존재하는데,
두 릴레이션 간에 속성의 수와, 도메인의 수가 같아야 합니다.
쉽게 말해, 테이블 가로 세로 크기가 똑같고, 각각의 값은 달라도,
각 값이 무엇을 나타내는가 하는 속성과 속성의 이름은 전부 매칭이 돼야 합니다.
이를 '합병조건이 만족한다' 라고 어렵게 말하기도 합니다.
아래 설명을 이어가기 전에 모두 같은 예시로 설명이 가능하기 때문에,
릴레이션을 먼저 만들고 설명하겠습니다.
<학생>
이름 | 학번 |
김영희 | 1 |
김철수 | 2 |
<군인>
이름 | 군번 |
김철수 | 10 |
홍길동 | 03 |
Union : 합집합 (기호 : U)
두 릴레이션에 존재하는 튜플의 합에서 중복을 제외하는 연산입니다.
𝝅 학생.이름 U 𝝅 군인.이름
이라고 표현할수도 있고,
{ t | t ∈ 학생.이름 ∨ t ∈ 군인.이름 }
이라고 쓸데없이 어렵게 표현할수도 있습니다.
t 는 튜플을 의미하고, ∈ 는 Element 를 기호로 표현한 것으로,
'학생.이름에 포함되거나, OR 군인.이름에 포함되는 원소' 라는 의미입니다.
연산의 결과는 아래와 같습니다.
이름 |
김영희 |
김철수 |
홍길동 |
Intersection : 교집합 (기호 : ∩)
두 릴레이션에 동시에 존재하는 튜플만 구하는 연산입니다.
마찬가지로,
𝝅 학생.이름 ∩ 𝝅 군인.이름
또는
{ t | t ∈ 학생.이름 ∧ t ∈ 군인.이름 }
이라고 표현할 수 있습니다.
연산의 결과는 아래와 같습니다.
이름 |
김철수 |
Difference 혹은 Minus : 차집합 (기호 : -)
두 릴레이션에 존재하는 튜플의 차집합을 구하는 연산 입니다.
연산에서 어떤 릴레이션이 왼쪽에 있느냐,
아님 오른쪽에 있느냐에 따라 결과가 달라지는 것만 빼곤,
딱히 설명할 게 없기 때문에 연산 결과만 보여드리겠습니다.
𝝅 학생.이름 - 𝝅 군인.이름
{ t | t ∈ 학생.이름 ∧ t ∉ 군인.이름 }
이름 |
김영희 |
군인.이름 - 학생.이름
이름 |
홍길동 |
Cartesian Product : 교차곱 (기호 : X)
카르테시안 프로덕트는,
천장에 파리가 붙어서 날아다니는 걸 보고
xy좌표계를 발명한 수학자 '르네 데카르트' 의 이름에서 따온 것인데,
데카르트의 라틴어 이름이 '레나투스 카르테시우스' 라고 합니다.
그리고 프로덕트 는 단어의 뜻에 '생산의 결과물, 곱' 이라는 뜻이 있습니다.
따라서,
카르테시안 프로덕트, 카르테시안 곱,
데카르트 프로덕트, 데카르트 곱,
교차 프로덕트, 교차 곱
모두 같은 말이고,
교차 곱은 그냥 x 좌표와 y 좌표의 값을 곱한다는 뜻입니다.
연산 결과는 아래와 같습니다.
𝝅 학생.이름 X 𝝅 군인.이름
학생.이름 | 군인.이름 |
김영희 | 김철수 |
김철수 | 홍길동 |
김영희 | 홍길동 |
김철수 | 김철수 |
관계해석이란?
관계형 데이터베이스 모델에서
관계대수가 연산자와 피연산자를 사용해서
프로그램에게 어떤 방식으로 연산을 수행할지
개발자가 직접 절차를 정해주는 절차적 언어라면,
관계해석은, 개발자는 원하는 결과만을 명시하고,
프로그램에게 수행을 맡기는 비절차적 언어입니다.
정처기 책에서는 관계해석을 아주 조금만 다루는데,
실제 실무에서도 관계해석은 잘 쓰이지 않는다고 합니다.
이유는 추측컨데,
관계대수는 사용자가 직접 절차를 정해주기 때문에 명확하고 오류의 위험이 적은데,
관계해석을 사용하게 되면 내부 절차를 모르기 때문에,
문제가 생겨도 원인파악이 힘들어서 그러지 않을까 생각합니다.
주요 기호로는 ∀ (전칭 정량자) 와 ∃ (존재 정량자) 가 있는데,
아 진짜 어려운 말 쓰는거 극혐입니다...
그냥 모든 테이블에 존재하는게 전칭 (for All) 이고,
(MySQL 에서는 SELECT *)
하나라도 존재하는 튜플이 있으면 존재 (there Exist) 입니다.
예시와 연산 결과는 따로 들 필요가 없는 게,
위에서 보여드린 { } 중괄호 안의 모든 수식들이 관계해석식입니다!
저처럼 해석하는 법을 모르는 분들을 위해,
관계해석식을 읽는 법을 알려드리자면,
{ t | t ∈ 학생.이름 ∧ t ∉ 군인.이름 }
이 수식은 '조건제시법' 으로 표현한 것입니다.
조건제시법을 이해하려면
명제와 조건 이라는 개념을 알아야 하는데,
중학교 1학년 수학에서 배우는 것입니다.
기억 안나시죠? 하하 저두요
명제라는 것은 참과 거짓으로 구분이 되는 문장이고,
조건은 항상 참인 문장을 말합니다.
따라서 관계해석식은
"명제가 항상 참이 되는 문장" => "조건" 을 을 제시하는 해석식 입니다.
이 말에 따라서 위의 수식을 다시 살펴보면,
| 기호 뒤에 오는 것은 '명제' 이고,
그것들을 참으로 만드는 레코드를 추출하는 것이
관계해석 연산 이고,
이런 식을 제시해서 수행을 프로그램에게 맡기는 것이
비절차적인 언어를 사용하는 관계해석 입니다.!
'정보처리기사 관련 개념 정리' 카테고리의 다른 글
페이지 교체 알고리즘에 대하여... (0) | 2024.04.18 |
---|---|
트리에 관하여...(개요, 용어, 종류, 이진 트리의 종류, 이진 탐색 트리, 트리 운행법, 수식 표기법) (2) | 2024.04.12 |
정렬에 관하여... (삽입, 선택, 버블, 셸, 퀵, 합병, 힙, 기수) (0) | 2024.03.29 |
미들웨어 솔루션 명세 (0) | 2024.03.22 |
디자인 패턴 (0) | 2024.03.15 |