이제 본격적인 내용에 들어가도록 하겠습니다.
데이터베이스의 역사
1970년 이전의 데이터 관리는 프로그래머에 따라 독자적인 파일 구조를 가진 채로 관리되었습니다. 하지만 Codd. E. F.가 1970년 “A relational model of data for large shared data banks”라는 논문을 출간하면서 일대 변혁이 일어나게 됩니다. 이 논문은 기존의 독자적인 정형화 되지 않은 파일 구조에서 벗어나 큰 용량의 데이터를 “관계 대수(Relation Algebra)”로 데이터를 정형화시켜 표현하면 좀 더 효과적인 데이터 관리를 할 수 있음을 시사하였습니다.
그리고 1976년에 Perter Chen이 “The Entity-Relationship Model-Toward a Unified View of Data”를 출간하면서 관계형에 또 다른 변혁을 가져오게 됩니다. 기존의 Codd의 관계 대수 표기법에서 나아가서 E-R 모델을 도입하여 실세계에 대한 이해를 좀 더 심층적으로 할 수 있게 만들었습니다.
시간이 흘러 1991년에 James Rumbaugh 등 5명에 의해 “Object-oriented modeling and design”이 나오게 됩니다. 이는 기존의 E-R 모델을 수정 및 보완하여 좀 더 세련된 OMT(Object-modeling technique) 모델의 탄생에 이바지하게 되었습니다. 그리고 이런 OMT 모델은 1999년 UML(Unified Modeling Language)의 탄생에 결정적인 역할을 하게 됩니다. 우리는 이 UML에 관해서 알아보도록 하겠습니다.
클래스 다이어그램(Class Diagram)
클래스 다이어그램은 데이터 모델링의 진수(眞髓)로서 이 세상의 모든 정보를 객체로 만들자는 일념 아래 탄생하게 되었습니다. 이러한 클래스 다이어그램은 아래의 내용을 포함합니다.
- 시스템 내부에서의 객체의 형태
- 클래스 다이어그램 간에 존재하는 다양한 종류의 정적 관계
- 선언된 정적 개체들(elements)에 대해서 정적 관점의 시각적 표현
그리고 이러한 모델링의 핵심이 되는 기술은 거의 모든 것이 객체 기반의 방법으로 돌아가게 만드는 것입니다. 그리고 이를 표현하는 가장 좋은 방법은 UML입니다. 이는 매우 단순하지만, 실세계 대부분을 적절하게 표현할 수 있습니다.
UML 클래스 다이어그램의 핵심 개체들
UML 클래스 다이어그램을 그리는 데 있어서 가장 중요 개체는 아래와 같습니다.
- 클래스(Class)
- 속성(Attributes)
- 명령(operations)
- 관계(relationships)
- 연관(association)
- 일반화(generalization)
- 의존(dependency)
- 실체화(realization)
- 제약 조건과 메모(Constraint Rules and Notes)
여기서 각각을 간략하게 짚고 넘어가면 먼저 클래스는 ‘교수’가 될 수 있습니다. 이런 ‘교수’의 속성으로는 ‘나이, 전공….’이 있을 수 있습니다. 그리고 명령은 일반적으로 C++에서 메소드(method)라 불리는 것과 대응이 되는 데 이는 우리 데이터베이스에서는 크게 중요한 내용이 아닙니다. 관계는 뒤에서 다룰 내용이 매우 많으므로 지금은 생략하겠습니다. 제약 조건과 메모는 일반적으로 ‘교수’는 ‘박사 학위’를 무조건 소지 해야 합니다. 이러한 ‘박사 학위를 가져야 한다’라는 제약 조건이 될 수 있습니다.
클래스(Classes)
먼저 클래스입니다. 클래스는 유사한 속성, 명령, 관계 및 행동 양식을 가지는 객체들 집합의 틀을 의미합니다. DB 안에 실재(entity)하는 형태(type)로 저장되게 됩니다.
위에서부터 클래스 이름, 속성, 명령에 관련된 상자들입니다.
연관(Association)
연관은 아래와 같이 이야기 할 수 있습니다.
- 클래스들 사이에서 의미론적인(semantic) 관계 (인스턴스1들 사이에서의 연결)
- 구조적 관계 (어떤 클래스에서 파생된 객체들과 다른 클래스에서 파생된 개체들 사이의 연결)
Example
실제 예시를 보면서 어떻게 UML이 구축되는지 알아보도록 하겠습니다. 먼저 아래와 같은 연관이 있다고 하겠습니다.
[Student]
이는 역할(Role)을 의미합니다.
[instructor]
이는 역할 이름(Role Name)으로 Faculty의 역할은 instructor라는 것을 의미합니다.
[instructs]
이는 연관 이름(Association Name)으로 지금 이 연결이 어떤 것에 관련된 연결인지를 명시적으로 표현하도록 해주는 것입니다.
[instructs 관계에서의 ‘1..*’, ‘*’]
이는 다중성(Multiplicity or Cardinality)를 의미하며 “1..*”의 의미는 Student 한 명에 대해서 Faculty는 최소 1명, 최대 무한대를 의미합니다. 그리고 “*”은 제약 없음을 의미하며, Faculty 한 명에 대해서 Student는 어떠한 제약 없이 존재할 수 있음을 의미합니다.2
[화살표(→)]
화살표는 방향성을 가진 연관을 의미합니다. 이는 Student가 듣는 Course에 대해서는 명시적으로 작성이 되어야 하나, Course를 듣는 Student는 명시적으로 표현될 필요 없음을 의미합니다. 이러한 연관 관계를 보고 운항(運航)성 또는 단방향 연결(Navigable or uni-directional association)이라 합니다.
[본인에게 돌아오는 화살표]
이것을 “재귀적 연관(Reflexive association)”을 의미합니다. 여기서 이것의 의미는 하나의 Course를 듣기 위해서는 0개 이상 3개 이하의 Course를 선행적으로 들어야 함을 의미합니다.
이제 각각의 내용을 좀 더 상세하게 알아보도록 하겠습니다.
이름과 역할(Name and Role)
연관은 고유의 이름을 제마다 가지고 있고, 이 이름은 다음을 충족해야 합니다.
- 의미가 명확해야 합니다.
- 이름은 연관 선의 중앙에 라벨(label)로 존재해야 합니다.
- 일반적으로 동사 혹은 동사구로 구성돼야 합니다.
그리고 역할은 클래스를 연결하는 연관의 끝에 존재해야 합니다. 그리고 이러한 역할은 다음을 충족합니다.
- 보통 명사나 명사구로 구성됩니다.
- 재귀적 연관에 관해서는 필수적으로 있어야 합니다. 요약하자면 다이어그램을 그릴 때 동사를 사용하면 연관을 의미하고, 명사를 사용하면 클래스를 의미하게 됩니다.
다중성(Multiplicity or Cardinality)
다중성의 정의는 하나의 연관 안에서 임의의 인스턴스에 대해서 연관된 인스턴스들의 수를 의미합니다. 이것들은 연결이 필수인지 아닌지를 나타내면서 연결되는 인스터스들의 최소, 최댓값을 알려줍니다. 이러한 다중성의 표현은 아래와 같습니다. 표기하지 않을 때는 최소, 최대 1을 의미합니다.
항목 | 표기법 |
---|---|
정확히 하나 | 1 |
0 이상의 수 | * 또는 (0..*) |
1 이상의 수 | 1..* |
0 또는 1 | 0..1 |
a 이상 b 이하 | a..b |
다중, 불연속 범위 | 2, 4..6, 8 |
연관 클래스(Association Class)
이런 연관 관계 중에 “삼각관계(Triple Relation)”가 있습니다. 이는 클래스 간에 정의되는 내용 중 부차적인 내용을 정의할 때 사용되는 것으로 여러 개의 연관 클래스를 만드는 것도 가능합니다. 단, 유의사항으로 각각의 클래스는 독립적인 클래스여야 합니다. 이에 따라 아래와 같은 모델을 구현할 수 있습니다.
집합(Aggregation)
집합은 여러 개를 하나로 합치는 것을 의미하며, 여러 관계 정의 중 하나라고 볼 수 있습니다. 이런 모델은 “is part-part of” 관계를 만족하며 여기서 상위 클래스를 전체(Whole)라 하고 하위 클래스를 부분(Part)이라 합니다. 또한, 전체는 일반적으로 한 개입니다. 이에 따라 아래와 같은 모델이 구현 가능합니다.
일반적으로 전체의 다중성는 표현하지 않도록 합니다. 단, 부분의 다중성는 반드시 표기할 수 있도록 합니다. 이러한 집합의 표시는 속이 빈 다이아몬드로 표기하도록 합니다.
구성(composition)
구성은 집합의 강한 형태입니다. 전체는 부분의 유일한 소유자여야 합니다. 즉, 한 개여야 합니다. 또한, 전체의 다중성은 0 또는 1이어야만 합니다. 그리고 부분의 생명 주기는 전체의 생명 주기에 의존하게 됩니다. 요약하면 생명 주기가 다른 집합은 그냥 집합이고, 같은 경우에는 구성이라고 할 수 있습니다. 예를 들어, 아래와 같은 모델을 만들 수 있습니다.
이 모델을 단적으로 이야기하면 Polygon이 없어지면 Point가 사라지게 됩니다. 만약 집합이었다면 Polygon이 사라져도 Point는 존재하게 됩니다. 하지만 구성은 Polygon이 사라지는 순간 Point도 사라지게 됩니다.
일반화(Generalization)
“특정 하위 클래스(specialized class 또는 subclass)”의 어떤 객체가 “일반적인 상위 클래스(generalized class 또는 super-class)”의 견고한 객체의 종류이면 이를 일반화 관계라고 합니다. 이러한 관계는 “is kind of”의 관계라고 합니다. 이때 추상화(abstract) 클래스 설정이 있는 데, 이 설정을 하게 되면 데이터가 생성되지 않습니다. 이것의 생성은 하위 클래스에서 생성이 되게 됩니다. 이를테면, 다음의 경우가 있을 수 있습니다.
여기서 도형(Shape)은 추상 클래스이자 상위 클래스가 됩니다. 그리고 원(Circle)은 하위 클래스가 됩니다. 여기서 우리는 둘 관계를 “원은 도형의 일종이다(Circle is a kind of Shape)”라고 할 수 있습니다. 그리고 여기는 생략이 되지만 일반적으로 상위 클래스가 가지고 있는 관계들도 하위 클래스는 받게 됩니다.
좀 더 보충하면 사람(Person)과 학생(Student) 사이의 관계를 생각해보도록 하겠습니다. 학생은 사람의 일종(is a kind of)입니다. 그렇다면 여기서 사람에 들어가는 정보는 무엇이 있을지 생각해봅시다. 이를테면 이름, 성별, 직업, 나이를 가질 수 있습니다. 이번에는 학생을 생각해봅시다. 학생은 사람의 속성을 다 가질 수 있습니다. 왜냐하면, 학생도 사람의 일종이기 때문입니다. 여기서 추가로 학교의 정보와 학년의 정보가 더 들어갈 수 있습니다. 결과적으로 하위 클래스로 갈수록 클래스가 가지는 정보는 점점 많아짐을 알 수 있습니다.
상속(Inheritance)
위에서 일반화 관계에서 상위 클래스가 가지고 있는 관계들을 하위 클래스도 받게 된다 하였습니다. 이를 보고 상속이라고 합니다. 이런 상속은 상위 클래스로부터 속성, 명령, 관계를 받는 것을 이야기하며, 하위 클래스는 속성과 명령, 관계를 추가하고, 상속받은 명령을 “다시 정의(Refine 또는 Override)” 할 수 있습니다.
이를테면, 아래와 같은 모델에서 Employee와 Division 사이 관계 내용은 Professor에도 그대로 상속됩니다.
모델의 설계 예시
[요구사항] 현재 우리는 RFID 키를 사용하는 대학 보안 관리에 관련한 데이터베이스를 설계 예정입니다. 이 데이터베이스는 아래의 규칙을 따르게 제작해주셔야 합니다.
- 대학 건물의 출입문들은 RFID 잠김 시스템을 가지고 있습니다.
- 대학의 사람들은 그들의 ID에 해당하는 그들만의 RFID 키를 가지고 있습니다.
- 대학의 사람들은 학생, 직원, 교수 세 가지로 분류됩니다.
- 직원은 자기 부서 건물의 모든 접근 권한을 가집니다.
- 학생은 미리 지정된 건물과 방을 접근 권한만 가집니다.
- 교수는 본인에게 배정된 방에만 접근 권한을 가집니다.
- 각각의 건물의 출입 기록을 가져야 합니다. (기록 기재 내용 : 이름, 분류, 부서, 접근 시간, 건물 번호, 문 번호)
이와 같은 요구사항을 보고 제작을 하면 아래와 유사해집니다. 유사해진다고 한 이유는 설계라는 것은 하나로 귀결되는 사항이나 정답을 가진 것이 아닙니다. 그리고 더더욱 이 모델은 많은 사항이 누락(漏落)되어있기 때문입니다.
제약사항
하지만 이러한 UML로 모든 의미론적 내용을 표현하는 것이 불가능합니다. 예를 들어, ‘남자의 나이가 여자의 나이보다 반드시 작아야 한다.’라는 조건을 UML 다이어그램만으로 표현하는 것은 매우 어려운 일입니다. 이러한 표현의 제한을 넘어서기 위해서 우리는 제약(constraints)을 표기하는 방법을 알아야 합니다. 이러한 제약의 대표적인 것으로 2가지가 있습니다.
- 키 제약(Key constraints)
- 참조 무결성(Referential integrity)
키 제약
키(Key)는 객체를 유일하게 구별할 수 있는 한 개 또는 그 이상의 집합으로 서로 다른 객체는 같은 키를 가질 수 없는 특징이 있습니다. 그리고 이러한 키에서 괄목할 만한 키로 기본키(Primary Key)가 존재합니다. 하나의 객체는 일반적으로 하나 이상의 키를 가집니다. 하지만 이 중에서 객체를 구별하거나 그 특징을 명확하게 보여주는 가장 중요한 키를 기본키라고 지칭합니다. 이를테면, 아래와 같은 클래스가 있다고 가정하겠습니다. 여기서 citizenID
, phone
으로도 직원을 분류할 수 있습니다. 하지만 좀 더 직원 자체에 충실한 키가 될 수 있는 것은 (name, address)
의 집합입니다. 따라서 아래와 같은 클래스에 대한 기본키는 (name, address)
라고 할 수 있습니다.
참조 무결성
이 말은 다른 객체에 의해 참조되는 값이 데이터베이스에 실제로 존재해야 함을 의미합니다. 데이터베이스 내에서 이러한 참조는 다른 객체의 기본키를 참조하는 것으로 이루어집니다. 이때 이러한 다른 기본키로의 참조를 할 수 있도록 만들어주는 키를 외래키라고 합니다. 하지만 이러한 외래키를 참조하는 경우에 객체가 존재하지 않게 되면 해당 외래키는 정상적인 기능을 하지 못하는 프로그래밍 언어에서 말하는 허상 포인터(dangling pointer)나 허상(dangling reference)와 비슷한 일이 벌어지게 됩니다. 따라서 이를 제한하는 것을 참조 무결성 조건이라고 합니다.
약 엔티티 집합
약 엔티티 집합(Weak Entity Set) 키의 일부 또는 전부가 다른 어떤 엔티티 집합(또는 객체)에 있는 속성에 의해서 만들어지는 집합을 의미합니다. 아래의 클래스 관계를 생각해보도록 하겠습니다.
만약 구단으로 유벤투스와 토트넘이 있다고 가정을 하겠습니다. 이 유벤투스에는 등 번호가 7번인 호나우도가 있고, 토트넘에는 등 번호가 7번인 손흥민이 있습니다. 이 경우에 호나우도랑 손흥민을 식별하기 위해서 (이름, 등 번호)
로 찾을 수도 있지만 아마 그거는 힘들 것입니다. 만약에 등 번호 7번의 손흥민이 다른 구단에 있다면 이건 문제가 있을 것입니다.
이렇게 하나의 객체가 가지고 있는 속성만으로 기본키를 구성하지 못하고 기본키를 구성하기 위해서는 상위 객체의 키를 조합해서 찾을 수 있습니다. 여기서 Player
를 약 엔티티 집합이라 하고 Football team
을 지원 클래스(supporting class)라고 합니다. 그런데 여기서 만약 Football team
도 약 엔티티 집합에 해당하면 해당 객체를 지원할 지원 클래스가 필요하게 됩니다. 그리고 참조 무결성은 반드시 지켜져야만 합니다.
이러한 약 엔티티 집합과 지원 클래스는 다대일로 구성이 되어야 합니다. 만약에 Football team
하나에 Player
하나이면 그 자체로 고유하므로 약 엔티티 집합의 조건이 될 수 없습니다.
E-R 모델
E-R 모델은 OMT의 확장인 UML이 나오기 전에 만들어진 모델로 관계형 모델의 단점을 보완하기 위해서 나왔습니다. 당연히 이는 UML에 영향을 준 만큼 UML과 매우 비슷한 모양을 취합니다. 아래의 모델 중 위는 UML 샘플을 아래는 해당 모델을 E-R 모델로 변경한 결과입니다.
이러한 E-R 모델의 표기 의미는 아래와 같습니다.
이러한 E-R에서 대표적인 다중성의 표시법으로는 화살표가 있습니다. 이런 화살표는 가리키는 방향을 기준으로 \(1:n\)의 속성을 가집니다. 이 이외에도 다중성은 아래의 종류가 있습니다.
만약에 결혼에 관해서 E-R 모델을 작성한다고 하면 아래와 같이 될 수 있습니다. 결혼이라는 관계를 중심으로 다중 연관을 구축할 수 있습니다. 그리고 이러한 결혼에 대한 속성도 부여가 가능합니다.
다음에서는 이러한 UML 모델과 E-R 모델의 기본이 되는 관계형 모델에 관해서 알아보도록 하겠습니다.