관계형 데이터베이스는 관계형 모델(Relational Model)을 기반으로 작성된 데이터베이스입니다. 그러나 관계형 모델에서 사용하는 용어와 SQL의 용어가 완벽하게 일치하지는 않습니다.
관계형 모델(Relational Model)의 기본적인 요소는 관계, 릴레이션(Relation)입니다.
관계형 모델에서 이 릴레이션은 약간 다른 의미를 가집니다. 관계형 모델의 릴레이션은 SQL에서 말하는 테이블(Table)에 해당합니다.
관계형 모델의 릴레이션에는 몇 가지 속성(Attribute)이 있습니다.
이 속성은 속성 이름과 형 이름으로 구성됩니다.
속성은 SQL에서 말하는 열(Column)에 해당합니다.
그리고 튜플(Tuple)이 곧 SQL에서 말하는 행(Row)을 의미합니다.
튜플(Tuple), 다시 말해 행(Row)은 속성(Attribute)의 집합, 다시 말해 열(Column)의 집합으로 레코드(Record)라고도 부릅니다.
관계대수(Relational Algebra)
라 합니다. 이러한 관계대수의 기본 규칙은 다음과 같습니다.
하나 이상의 관계를 바탕으로 연산한다.
연산한 결과, 반환되는 것 또한 관계이다.
연산을 중첩 구조로 실행해도 상관없다.
하나씩 SQL과 비교하여 설명해보겠습니다.
앞서 살펴본 일대일, 일대다, 다대다 관계처럼 하나 이상의 관계를 바탕으로 연산합니다.
UNION
명령, JOIN
명령을 통한 테이블 결합처럼 연산한 결과와 반환되는 것도 관계(Relation), 다시 말해 테이블입니다.
서브쿼리를 활용하여 연산을 중첩 구조로 실행할 수 있습니다.
관계대수에서는 자주 사용될 것 같은 릴레이션의 연산 방법을 미리 규정합니다. SQL 명령과 한 번 비교해보겠습니다.
합집합(Union)은 릴레이션끼리의 덧셈을 의미합니다. SQL에서는 UNION에 해당합니다.
SELECT * FROM a UNION
SELECT * FROM b
차집합(Difference)은 릴레이션끼리의 뺄셈을 의미합니다. SQL에서는 EXCEPT에 해당합니다.
SELECT * FROM a
EXCEPT
SELECT * FROM b
EXCEPT
키워드가 존재하지 않기 때문에 아래와 같이 NOT EXISTS
키워드를 WHERE 구의 서브쿼리 조건으로 활용하여 차집합을 계산할 수 있습니다.SELECT * FROM a WHERE NOT EXISTS ( SELECT * FROM b WHERE a.no = b.no )
교집합(Intersection)은 릴레이션끼리의 공통부분(교집합)을 의미합니다. SQL에서는 INTERSECT에 해당합니다.
SELECT * FROM a INTERSECT SELECT * FROM b
INTERSECT
키워드가 존재하지 않기 때문에 아래와 같이 EXISTS
키워드를 WHER
E 구의 서브쿼리
조건으로 활용하여 교집합을 계산할 수 있습니다.SELECT * FROM a WHERE EXISTS ( SELECT * FROM b WHERE a.no = b.no )
곱집합(Cartesian Product)은 릴레이션끼리의 대전표를 조합하는 연산을 의미합니다. SQL에서는
FROM
구에 복수의 테이블을 지정하거나CROSS JOIN
을 활용하여 계산할 수 있습니다.
-- FROM (복수 테이블)
SELECT * FROM a, b
-- CROSS JOIN
SELECT * FROM a CROSS JOIN b
선택(Selection)은 튜플의 추출을 의미합니다. 제한이라고 불리기도 합니다.
WHERE
구에 조건을 지정해 데이터를 검색(SELECT)
하는 것에 해당합니다. 예시는 아래와 같습니다.SELECT * FROM a WHERE no < 3
투영(Projection)은 속성의 추출을 의미합니다. 속성은 앞서 SQL에서는 열을 의미한다고 언급했습니다.
따라서 SQL에서는SELECT
구에 결과로 반환할 열을 지정하는 것에 해당합니다. 예시는 아래와 같습니다.
SELECT no, nickname FROM a
결합(Join)은 릴레이션끼리 교차결합해 계산된 곱집합에서 결합조건을 만족하는 튜플을 추출하는 연산입니다. SQL에서는 내부결합에 해당합니다.
-- 구식방법
SELECT * FROM a, b WHERE a.no = b.no
-- INNER JOIN
SELECT * FROM a INNER JOIN b ON a.no = b.no
-- LEFT JOIN
SELECT * FROM a LEFT JOIN b ON a.no = b.no
-- RIGHT JOIN
SELECT * FROM b RIGHT JOIN a ON b.no = a.no