Skip to content

Commit

Permalink
2024-05-27
Browse files Browse the repository at this point in the history
  • Loading branch information
Seung-IL-Bang committed May 27, 2024
1 parent 6735b83 commit d20ef20
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions _posts/Database/2024-05-27-성적관리연습1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: 성적 관리 모델링 연습 (1)
description: 데이터베이스 중급(Modeling) - 성적 관리 모델링 연습 (1)
categories:
- Database
- 데이터베이스 중급(Modeling)

tags:
- Database

---

> 중학교 학생들의 성적을 관리하는 시스템의 DB를 설계 해보자!
<!-- more -->

## 성적 관리 요구 사항

- 중학교(남녀공학) 학생 성적관리 프로젝트
- 과목은 학년별로 담당 선생님이 따로 있다.
- 시험은 중간고사, 기말고사 두 가지가 있다.
- 학생들은 학년, 반에 배정되며 반별로 학생들에게 고유 번호를 부여하고 있다.
- 각 반에는 담임 선생님이 배정되어 있다. 선생님 중에는 담임을 맡지 않는 선생님도 있다.
- 한 반의 학생은 대략 40명 정도이고 남녀 공학이다.
- 석차는 남녀 공통 1등부터 순서대로 정한다.

## 마스터 테이블

- 학생(반당 40명정도, 반별 고유 번호 존재), 학년, 반
- 과목(학년별 담당 선생님 별도로 존재), 선생님(담임/비담임)
- 성적(반 석차/ 학년 석차) ⇒ 시험에 의한 객체 생성
- 시험(중간고사, 기말고사)

## 관계 테이블

- 시험(보다), 배정(하다), 개강(하다)

> 만약 실무에서 시나리오에 모르는 단어가 있는 경우, 고객에게 그 개념을 물어봐서 확실히 개념을 잡고 설계한다.
## 논리적 설계

### 온전한 명사 선별하기

가장 먼저 해야할 것은 마스터 테이블로 존재할 수 있는 객체들을 선별하는 것이다.

**종속성**, **수식어** 등을 파악하여 마스터 테이블의 객체를 정리해나간다. 예를 들어, 학생과 고유 번호가 있을 때 고유 번호는 학생에 종속되므로 학생 객체의 속성으로 들어가는 것이 맞다. 또한, 담임과 선생님을 생각해보면, 담임은 선생님의 수식어이기 때문에 선생님 객체의 속성으로 들어가는 것이 맞다. 이렇게 **종속성** 또는 **수식어** 등을 파악하여 **<u>명사로 온전히 존재할 수 있는 객체를 가려낼 수 있다.</u>** 만약 속성으로 들어갔던 컬럼이 알고보니 복잡도가 높다고 판단되면 마스터 테이블로 분리해내면 된다.

> 더 이상 분열할 수 없을 만큼 작은 단위로 객체를 마스터 테이블로 만들면 된다. 그렇다고 마스터가 아닌 것을 마스터로 만들면 굉장히 어색해진다.
### 1:M 관계 찾기

그 다음 해야할 것은 마스터 테이블 간의 `1:M(부자지간)` 관계가 있는지 살펴보는 것이다.

> 1:M 관계는 직관적으로 보이기 마련이다.
*데이터베이스 스키마 설계는 많은 경험치가 필요한 일이다. 처음부터 잘 못하더라도 괜찮다.*

### 기준 테이블

**자식**의 포지션이 되지 않는 테이블을 **절대 마스터 테이블**이라고 하고 다른 말로 **기준 테이블** 이라고 한다.

**기준 테이블**에서 오류가 발생하면 그 이하 연결된 자식 테이블에 모두 문제가 발생한다. <u>기준 테이블같은 경우에는 한 번 생성되면 거의 변경이 없는 성격을 가진다.</u> 그렇기 때문에 DBA 입장에서 가장 신경 써야 하는 것은 기준 테이블에 오류가 있느냐를 파악해야 한다. 예제에서 기준 테이블은 `학년`으로 볼 수 있다.

> 기준 테이블의 경우 한 번 생성되면 그 이후에는 변경될 일이 거의 없다. 따라서 생성된 이후에는 `INSERT` , `DELETE` , `UPDATE` 를 막아버리는 것이 좋다. 즉, `SELECT` 만 열어줘서 **read-only** 로 설정하는 것이 좋다.
### 고정 관념 버리기

데이터 타입을 정할 때 주의해야 할 점은 고정 관념에 빠져서 잘못된 데이터 타입을 설정해주는 것이다.

예를 들어, 반이름의 경우 보통 1반, 2반, … 이런 식일텐데, 개나리반, 무궁화반 처럼 이럴수도 있다. 이럴때 varchar의 글자수를 전자에 맞췄을 경우 글자수 부족 문제가 발생할 수도 있다. 따라서, <u>고정 관념에 빠져서 데이터 타입을 설정하는 것에 주의해야 한다.</u> 이런 것은 **확장성**을 고려하지 않은 설계 방식이다.


### 코드 레벨에서 할 일

확장성을 고려한 설계 이후에는 개발 단계에서 **요구 사항에 맞도록 검증 로직을 추가**하면 된다. 예를 들어, 반의 개수는 최대 12반 까지 있어야 한다면, `tinyint`로 충분하다. 그리고 코드 레벨에서 1반 부터 12반까지만 입력되도록 검증 로직을 추가하면 된다. <u>즉, 입력되는 값에 대한 컨트롤은 설계 단계에서 할 필요가 없다.</u>

<br>

## ERD 그리기

<figure align="center">
<img src="/post_images/Database/학년과반.png">
<figcaption>학년과 반 1:M 관계</figcaption>
</figure>

- 반ID가 학년별로 1반, 2반 … 체계를 갖기 위해 **상속형 PK**를 사용했다.

앞서 말했듯이 `학년` 기준 테이블은 거의 변경될 일이 없으므로 미리 값을 넣어놔서 `DML`을 사용하지 않도록 한다.

```SQL
INSERT INTO 학년 VALUES (1, '1학년'), (2, '2학년'), (3, '3학년');
SELECT * FROM 학년;
```

### 학년 테이블

| | 학년ID | 학년명 |
| --- | --- | --- |
| 1 | 1 | 1학년 |
| 2 | 2 | 2학년 |
| 3 | 3 | 3학년 |

반면에 `` 테이블은 값이 바뀔 수 있는 있기 때문에 `DML`을 허용해야 한다. 이처럼 비즈니스 상황에 따라 또는 고객의 요구사항에 따라 `DML`을 허용해야 할 지 파악하고 데이터를 미리 넣을지 말지 결정하면 된다.

### 학년, 반, 학생 객체

<figure align="center">
<img src="/post_images/Database/학년-반-학생.png">
<figcaption></figcaption>
</figure>

학년, 반, 학생 객체들에 대해 PK와 최소한의 속성으로만 ERD를 구성했다.

> PK에 어떤 의미를 부여하는 행동은 지양해야 한다. 확장성과 유연성을 망가뜨리는 행위이다. PK는 유니크하고 낫널이면 충분하다.
- 예약어와 같은 혼란을 빚을만한 단어로는 테이블명으로 사용하지 않는다. (ex. 학급, 반 → `class` 사용 금지)
- 각 테이블명들은 **일관성**있게 작성하는 것이 좋다. (ex. 학년 → school_grade, 반 → school_class)
- 참고로 작명할 때 테이블은 접두어로 `TB`, 뷰는 `VW`, 스토어드 프로시저는 `SP` 가 붙는 경우도 있다. 이름만 보고 테이블인지 뷰인지 스토어드 프로시저인지 바로 파악하기 편리하다.

---
Binary file added post_images/Database/학년-반-학생.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added post_images/Database/학년과반.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d20ef20

Please sign in to comment.