이 글은 DATABASE SYSTEMS:The Complete Book(2nd Edition, Hector Garcia-Molina, Jeffrey D. Ullman, Jennifer Widom)의 Chapter2: Relational Database Modeling를 요약/재구성한 글입니다.
2.1 데이터 모델 개요(An Overview Of Data Models)
데이터 모델이란 무엇인가? 이것을 정의하기에 앞서, 데이터 모델을 정의하는 세가지 관점을 소개한다.
첫째, 데이터의 구조(structure of data): 프로그래밍 언어의 배열, 객체 같은 것과 유사하다. 그러나, 데이터베이스에서 얘기하는 데이터의 구조는 그것보다는 상위 계층에서 일어나는 일이다. 그래서, 물리적 모델(physical model)보다는 개념적 모델(conceptual model)이라는 말이 더 잘 들어맞는다.
둘째, 데이터의 연산(operations on the data): 프로그래밍 언어랑은 다르게, 데이터베이스의 데이터에 할 수 있는 연산은 제한적이다. 쿼리(queries)와 변경(modification), 두 종류다.
셋째, 데이터의 제한조건(constraints on the data): 데이터는 “아무거나”로 표현되지는 않는다. 그 종류가 “숫자” 라거나 “1부터 10사이의 정수” 라거나 “영화제목” 같은 타입(type)이나 범위(range)가 존재한다.
데이터 모델은 두 종류로 나뉜다.
- 관계형 모델(relational model)
- 비정형 모델(semistructured-data model)
관계형 모델(Relational Model)
- 구조의 관점: 프로그래밍 언어로 생각한다면, 그냥 struct 객체의 배열 정도로 상상하면 된다. 가능은 하겠다만, 실제로 그런식으로 구현되지는 않는다. 그 이유는 데이터의 규모 때문이다. 보통 데이터베이스는 대량의 데이터를 상상하고, RAM 보다는 디스크에 저장하기 좋은 형태로 데이터를 다룬다.
- 연산의 관점: 우리는 이 표에서 “장르가 comedy”인 row 만을 골라낼 수 있다.
- 제한조건의 관점: 예를 들어, “title과 year가 동시에 같은 영화는 없다” 같은 조건이 있다.
비정형 모델(Semistructured-data Model)
- 구조의 관점: 대개 테이블, 배열 같은 느낌보단 트리(tree)나 그래프(graph)를 상상하면 된다. 위 Figure는 Semistructured-data Model의 대표적 예시인 XML이다.
- 연산의 관점: 여기서의 연산은 원소(element)의 하위원소(subelement)들을 타고타고 내려가며 진행된다. 장르가 “comedy”인 영화를 찾으려면 태그 하위의 태그 안의 값을 확인해야 한다.
- 제한조건의 관점: “ 태그 안에 항상 태그가 존재하는가?” 같은 조건이 있다.
비정형 모델이 관계형 모델에 비해 더 유연하다는 장점은 있다. 그러나, 최근의 DBMS는 더 많은 데이터를 더 효과적으로 접근하고 수정할 수 있게 하기 위해 관계형 모델을 선택한다. 남은 글에서는 관계형 모델을 집중적으로 소개한다.
2.2 관계형 모델 기초(Basics of the Relational Model)
다시 아까의 figure를 가져왔다. 우리는 이런 2차원의 테이블을 릴레이션(relation)이라고 부른다. 이 “Movies relation”을 보며, relational model에서 사용되는 주요 용어들을 소개한다.
속성(Attributes)
표에서 title, year, length, genre 같은 세로열(column)들을 말한다. 필드(field), 피쳐(feature)도 비슷한 표현이다. 어느 릴레이션의 attributes의 개수를 차수(degree) 혹은 차원(dimension) 혹은 애리티(arity)라고 한다.
스키마(Schemas)
릴레이션의 이름과 속성들의 집합을 우리는 스키마(schema)라고 부른다. 예를 들어, 위의 Movies의 스키마는 아래처럼 표현한다.
Movies(title, length, year, genre)
속성들의 “집합”이라고 표현한 것은, 그들의 순서는 중요치 않기 때문이다. 또, 데이터베이스는 대개 여러개의 스키마로 구성된다. 그것을 우리는 데이터베이스 스키마(database schema)라고 부른다.
튜플(Tuples)
릴레이션에서 하나의 가로행(row), 레코드(record)나 오브젝트(object)라는 표현도 가능하다. 그리고 어느 릴레이션의 tuples의 개수를 크기(cardinality)라고 부른다. 아래처럼 표현한다.
(Star Wars, 1939, 231, drama)
도메인(Domains)
데이터타입(data type)도 동일한 표현이다. 각 속성들은 atomic하다, 혹은 elementary type을 갖는다. 더 이상 쪼갤 수 없다는 뜻으로, 집합, 배열 같은 데이터 구조들은 포함되지 않는다. 도메인을 살려서 스키마를 표현하면 아래와 같다.
Movies(title: string, year: integer, length: integer, genre: string)
릴레이션은 튜플들의 배열이 아닌 집합이다. 앞서 말했듯이, 속성들의 순서 또한 중요치 않다. 즉 아래처럼 데이터의 가로와 세로를 마구 섞어도, 우리는 동일한 릴레이션의 다른 표현방법일 뿐으로 본다.
인스턴스(instance)
릴레이션은 멈춰있는 것이 아니다. 새로운 튜플이 수정되거나, 기존 튜플이 변경되거나, 삭제된다. 비용이 크긴 할테지만, 스키마가 변경될수도 있다. 예를 들어, 새로운 속성이 추가될 수 있다. 그래서, 지금 당장 이순간의 릴레이션의 튜플들의 집합을 인스턴스(current instance)라고 부른다.
키(key)
앞서, 제목과 연도가 같은 영화는 없다고 하기로 했다. 이 경우 제목 속성과 연도 속성의 집합을 키(key)라고 부른다. 키는 이렇게 밑줄을 그어 표현한다.Genre가 키가 될수는 없을 것이다. 당장의 인스턴스에는 영화들의 genre가 다 다르지만, 앞으로 새로운 tuple들이 추가되면, 아니게 될 것이기 때문이다.
Movies(title, length, year, genre)
현실 세계 에서는 인공키(aritifical key)를 사용하기도 한다. 주민등록번호처럼 영화마다 고유한 임의의 문자열이나 숫자를 영화등록번호로 설정하는 것이다. 아래의 MovieID는 튜플에게 인위적으로 부여된 고유한 문자열 값이다.
Movies(MovieID, title, length, year, genre)
2.3 Defining a Relation Schema in SQL
SQL(”시퀄”, “sequel”이라고 발음)은 관계형 데이터베이스에서 사용하는 주된 언어중 하나이다. 두 가지의 기능이 있다.
- 스키마를 정의하는 DDL(Data-Definition Language)로써의 기능
- 데이터를 쿼리(query, 질의)하거나 수정하는 DML(Data-Manipulation Language)로써의 기능
SQL은 릴레이션을 세 종류로 구분한다.
- 테이블(Tables): 일반적으로 데이터베이스에 저장된(stored) 수정이나 쿼리가 가능한 데이터들이 있는 릴레이션을 말한다.
- 뷰(Views): 데이터베이스에 저장된 데이터들 중 필요에 따라 연산을 해서 나온 결과물로 나온 릴레이션이다.
- 임시 테이블(Temporary tables): query processor가 임시로 생성한, 저장되지 않는 테이블이다. (사용자가 목적을 두고 만든건 뷰, 의도하지 않았으나 데이터베이스 내의 소프트웨어가 명령 수행을 위해 만들어진 부산물은 임시테이블 인듯하다 - 글쓴이의 이해)
SQL 에는 원시 타입(primitivie data types)이 존재한다.
- CHAR(n): 길이가 n으로 고정된 문자열, 길이를 맞추기 위한 패딩(padding)이 들어감
- VARCHAR(n): 길이 최대 n의 가변 길이 문자열, 패딩 없이 문자열 끝에 마커(endmarker, \0)나 길이가 따라 붙는다.
- BIT(n): 고정 길이 비트
- BIT VARYING(n): 가변 길이 비트
- BOOLEAN: TRUE, FALSE, 그리고.. UNKNOWN 3가지 값이 가능함
- INT(=INTEGER): 4bytes 정수, SHORTINT 같은 것도 있으며, C의 타입 체계와 동일
- FLOAT(=REAL): 부동소수점(floating-point) 숫자, C와 동일하며, DOUBLE PRECISION도 있음
- DECIMAL(n,d): 유효숫자 n개, 소숫점 아래 d개의 숫자가 있는 숫자. NUMERIC과 거의 유사하나, DBMS마다 구현의 차이가 있을 수 있음
- DATE, TIME: 각각 ‘yyyy-mm-dd’와 ‘hh:mm:ss.s’ 의 문자열 다뤄진다.
우리의 Movies Relation에 몇개의 속성을 추가하여, 테이블로 생성하자면 아래의 문법으로 SQL 선언을 하면 된다.
CREATE TABLE Movies (
title CHAR(100),
year INT,
length INT,
genre CHAR(10),
studioName CHAR(30),
producerCNum INT,
);
몇가지 스키마를 수정하는 SQL 문(statements)을 더 소개한다.
테이블의 삭제: DROP TABLE Movies;
테이블에 속성 추가: ALTER TABLE Movies ADD title CHAR(100);
테이블에 속성 삭제: ALTER TABLE Movies DROP title;
어떤 스키마에 새로운 속성을 추가한 경우를 생각해보자. 기존의 tuple들은 그 속성에 할당할 값이 필요하다. 보통 이럴때는 NULL
이라는 값이 자리잡게 된다. 그게 싫다면, 기본(default) 값을 추가하면 된다. 앞서 소개한 ALTER TABLE
과 ADD
문 뒤에 DEFAULT 'any default title'
을 추가하면 된다.
다음은, 테이블을 생성할때 키를 설정하는 방법이다. 두가지 키워드가 있다. PRIMARY KEY는 NULL을 허용하지 않으며, 테이블에 하나만 존재할 수 있다(여러개의 속성이 하나의 primary key를 이룰 수는 있다). UNIQUE는 NULL을 허용한다.
방법은 두가지가 있다. 속성을 정의할때, 그 데이터 타입 옆에 키워드를 붙이거나, 아예 별개의 키 정의 키워드를 선언문 말미에 붙이는 것이다.
CREATE TABLE MovieStar (
name CHAR(30) PRIMARY KEY,
address VARCHAR(255),
gender CHAR(1),
birthdate DATE
);
# 또는
CREATE TABLE Movies (
title CHAR(100),
producerCNum INT,
PRIMARY KEY (title, year)
);
2.4 대수적 쿼리언어(An Algebraic Query Language)
여기서는 관계형 모델을 위한 특별한 대수학인 관계대수학(relational algebra)을 배운다. 이것은, 주어진 릴레이션으로부터 새로운 릴레이션을 생성하는 방법을 제시한다. 초창기 쿼리언어들은 이 대수학을 직접 차용하기도 했고, 현대의 SQL 또한 이 대수학에 문법적인 양념이 가해진(syntactically sugared) 것일 뿐이다.
C나 Java같은 훌륭한 프로그래밍 언어들이 있는데도, 왜 이런것을 배워야할까? 관계대수학에 비해 C나 Java는 너무 똑똑해서 그렇다. C나 Java는 관계대수학이 못하는 일들을 많이 할 수 있다. 예를 들어, 숫자의 홀짝을 판단하는 것 등이 있다. 그렇지만 관계대수학은 관계형 모델 아래서 동작하기에는 충분하며, 이런 부족한 능력이 오히려 두 가지 장점을 갖는다. 사용자에게는 프로그래밍의 편리함(ease of programming)을, DBMS에게는 컴파일러가 최적의 코드(highly optimized code)를 만들수 있게끔하는 능력을 제공한다.
대수학이 무엇인가? 대수학은 연산자(operators)와 어토믹 피연산자(atomic operands)로 구성된다. 예를 들어, 산수대수학(arithmetic algebra)은 변수 x 나 상수 15 같은 피연산자와, 덧셈, 뺼셈 같은 연산자를 합쳐 x+15 같은 표현식(expressions)을 만들어낸다.
관계대수학에서 피연산자는 변수 혹은 상수로써의 릴레이션들이다. 그렇다면 연산에는 무엇이 있는가? 크게 4종류로 나뉜다.
- 집합 연산(set operations): 합집합(union), 교집합(intersection), 차집합(difference)
- 릴레이션의 일부를 제거함: 속성들을 지우는 사영(projection)과 튜플들을 지우는 선택(selection)
- 서로 다른 릴레이션의 튜플을 합침: 가능한 모든 쌍을 짝짓는 데카르트곱(Cartesian Product), 선택적으로 짝짓는 조인(join)
- 이름을 바꿈: 릴레이션이나 속성의 이름을 바꿈. 튜플에 변화는 없으나, 스키마에 변화는 생김
이제 이 4종류의 연산들에 대해 알아보자.
집합 연산(set operations)
합집합, 교집합, 차집합이 있다. 주의할 점은 연산하려는 두 집합의 스키마는 같아야한다. 속성들의 이름과 타입, 그리고 순서도 같아야 이 연산을 할 수 있다.
제거하는 연산
사영(Projection)은 릴레이션 R로부터, 몇개의 속성들만을 취해서 새로운 릴레이션을 만든다.
선택(Selection)은 relation R로부터, 어떤 조건 C를 만족하는 몇 개의 튜플들만을 취해서 새로운 릴레이션을 만든다.
곱하는 연산
데카르트곱(Cartesian Product, or cross-product, or product)은 두 relation R과 S 사이에 가능한 모든 쌍을 합친다. 만약, R과 S에 공통의 속성 A가 있다면, R.A, S.A로 합쳐진 후의 두 속성을 구분한다.
자연조인(Natural Join)은 두 Relation R과 S 간 공통의 속성들이 있어야 한다. 그 속성들이 같은 튜플들끼리 짝짓는다.
세타조인(Theta Join)은 주어진 조건 C를 만족하는 두 튜플을 짝짓는다. 공통의 속성이 있다면, 데카르트 곱처럼 R.A, S.A 같은 이름의 속성들이 생길 수 있다.
이름바꾸는 연산
릴레이션의 이름과 속성들의 이름을 바꿀 수 있다. 밑에는 새로운 스키마명과 속성들을, 항에는 릴레이션 명을 넣어 표현한다.
이 4가지의 연산들은 합쳐져서 사용가능하다. 가령, “What are the titles and years of movies made by Fox that are at least 100 minutes long?” 라는 쿼리는 이렇게 쪼갤 수 있다.
- Select those Movies tuples that have length > 100
- Select those Movies tuples that have studioName = ’Fox’
- Compute the intersection of (1) and (2).
- Project the relation from (3) onto attributes t i t l e and year.
그리고 이것은 아래의 표현 나무(expression tree)와 선형 표현식(linear notation)으로 나타낼 수 있다.
이 복잡한 선형 표현식을 단순화 하기 위해, 적절한 항끼리 묶어 임시 릴레이션으로 표기하면, 더욱 간결하다.
이렇게 4가지 분류의 연산들을 소개했다. 그런데, 사실 이 중 3가지 연산은 나머지의 연산들로 표현이 가능하다.
- 교집합
- 세타 조인
- 자연 조인
나머지 교집합(union), 차집합(difference), 선택(selection), 사영(projection), 곱(product), 개명(renaming), 이렇게 6개의 기본연산들은 서로서로 표현할 수 없는 독립적인 연산들이다.
2.5 릴레이션의 제한조건(Constraints on Relations)
앞서, “키”에 관한 제한조건들은 살펴보았다. 이 절에서는 참조 무결성(referential-integrity) 제한조건를 추가로 소개한다. 이 조건은 한 릴레이션의 어느 한 속성이 다른 릴레이션의 속성에서도 발견될 때 적용된다.
Movies relation과 MovieExec(영화 제작자, executive) relation에는 각각 producerC#, cert#(고유번호, certificate number) 이라는 속성이 있다. 우리는 이 데이터베이스의 Movies의 제작자 정보들은 MovieExec relation에도 존재할 것이라고 가정할 수 있다. 그렇지 않으면, 뭔가 문제가 있는 상황이라고 생각할 수 있다. 이걸 표현식으로 나타내면 아래와 같다.
키에 관해서도 이런 관계대수 표현식으로 나타낼 수 있다. Name을 키로 삼고, address라는 속성을 갖는 MovieStar relation을 상상하자. Name은 고유한 키여야하기 때문에, 어떤 임의의 두 튜플의 name이 같다면, address는 물론 모든 속성의 다른 값들도 같아야 할 것이다. 즉, 두 튜플은 같은 튜플이여야만한다. 혹은, 임의의 두 튜플의 name은 같고, address는 다른 경우는 존재해서는 안된다. MovieStar relation의 두 복사본인 MS1, MS2 relation을 만들고, 우리는 아래 처럼 표현할 수 있다.
MS1의 정의도 관계대수 표현식으로 나타내자면 아래와 같다.
이런식으로 다양한 제한조건들을 관계대수 표현식으로 작성할 수 있다. 마지막 예시를 보자, MovieStar의 gender 속성은 반드시 ‘M’ 혹은 ‘F’ 값을 갖는다는 것은 아래처럼 표현된다.
'개인 공부' 카테고리의 다른 글
[데이터베이스 개론] 3. 고급 데이터베이스 모델(High-Level Database Model) (0) | 2025.04.22 |
---|---|
[데이터베이스 개론] 2. 관계형 데이터베이스 설계(Design Theory for Relational Databases) (0) | 2025.04.22 |
[이산구조] 명제(Proposition) (0) | 2025.03.02 |
[전산기조직] 논리 디자인의 기초 - Combinational Logic 편 (0) | 2025.03.02 |
[정보보호개론] 보안의 속성(CIA triad, AAA triad) (0) | 2025.02.28 |