# 34강. 데이터베이스 설계
여기에서는 데이터베이스 설계의 개념 및 설계도를 읽는 방법 등에 관해 알기 쉽게 설명한다. 나아가서는 트랜젝션에 대해서도 다룬다. 트랜젝션은 데이터베이스 설계의 방법이라고는 할 수 없지만 시스템 개발 현장에서 자주 쓰이는 기능 중 하나이다.

---

## 1. 데이터베이스 설계
- 데이터베이스를 설계한다는 것은 데이터베이스의 스키마 내에 테이블, 인덱스, 뷰 등의 데이터베이스 객체를 정의하는 것을 말한다.
- 스키마 내에 정의한다는 뜻에서 `스키마 설계`라 부르기도 한다.
- 데이터베이스 설계의 주된 내용은 테이블의 이름이나 열, 자료형을 결정하는 것이다.
- `이 테이블은 이 열을 이용해 저쪽 테이블과 연결한다`와 같이 테이블 간의 관계를 생각하면서 여러 테이블을 정의하고 작성하게 된다.
- 단, 설계인 이상 테이블 정의에만 그치지 않는다.

### 논리명과 물리명
- 테이블을 설계할 때는 테이블 정의서나 설계도 등의 문서를 작성하는 경우가 많다.
- 문서 양식은 여러 가지가 있으나 일반적으로 다음과 같은 양식을 사용한다.

`테이블명 : 상품`
|열명|자료형|NULL|기본값|비고|
|-|-|-|-|-|
|상품코드|CHAR(4)|No|||
|상품명|VARCHAR(30)|Yes|||
|가격|INTEGER|Yes|||

- `DESC` 명령에 따라 표시되는 결과를 그대로 옮겨적은 것이라 봐도 무방하다.
- 이외에 어느 열이 기본키인지를 지정하는 경우도 있다.
- 테이블을 설계할 때는 테이블 이름이나 열 이름을 지정하는데, 하나의 테이블에 대해 두 개 의 이름을 지정할 때도 있다.
- 하나는 데이터베이스에서 사용할 이름으로, 실제로는 `CREATE TABLE`에 지정하는 이름을 말하며 `물리명`이라고 부른다.
- 또 하나는 `논리명`이라는 것으로 테이블의 `설계상 이름`에 해당한다.
- 물리명은 데이터베이스 시스템 규칙에 따라 길이에 제한이 있거나 공백문자를 사용할 수 없는 등의 제약이 따른다.
- 따라서 일상에서 사용하는 단어로는 이름을 지정하는 데 한계가 있다.
- 또한 전통적으로 알파벳을 사용해 이름을 지정한다.
- 예를 들면 테이블의 물리명은 'item_master', 논리명은 '상품 마스터'로 지정하는 경우가 그것이다.
- 길이도 제한되다 보니 생략하거나 약자로 이름을 붙이는 경우도 많다.
- 그러다 보면 물리명만으로는 의미가 전달되지 않는 경우도 많아 논리명이 필요해진다.
- 여기서 차이점은, 물리명의 경우 `CREATE TABLE` 명령으로 테이블을 작성할 때 사용하는 이름이라면, 논리명은 해당 테이블을 실제로 부를 때 사용하는 이름이라는 점이다.
- 물리명은 잘못 정하면 변경하기 힘들지만 논리명은 언제나 바꿀 수 있다.

##### 물리명은 CREATE TABLE에 지정하는 테이블이나 열 이름이다!
##### 논리명은 설계상의 이름이다!

- 이러한 이유로 물리명과 논리명이 함꼐 기재된 설계도나 정의서도 있다.
- 경우에 따라서는 별도의 논리명 기입 항목을 지정하지 않고 비고란에 기재하는 경우도 있다.

### 자료형
- 테이블의 열에는 자료형을 지정해야 한다.
- 데이터베이스에 따라 다르지만 무엇이든 저장할 수 있는 자료형은 없다.
- 수치 데이터만 저장하는 열에는 설계 시 수치형으로 지정한다.
- 따라서 금액이나 개수처럼 수치 데이터만 다룰 수 있는 열은 주저없이 수치 자료형으로 지정하면 된다.
- 한편 제조번호처럼 알파벳도 다루어야 한다면 문자열형으로 지정하는 편이 낫다.
- 수치형을 문자열형으로 변환하는 것은 문제가 되지 않지만 문자열형을 수치형으로 변환하는 경우에는 에러가 발생하기도 해 번거로울 수 있다.
- 데이터에 따라서는 '1, 2, 3 중에 하나'라든가 'yes, no중에 하나'만 데이터 값으로 취급하는 경우가 생기기도 한다.
- 이런 경우에는 데이터베이스 기능으로 제약(CHECK 제약)을 걸 수 있으므로 데이터 정합성이 중요한 부분에는 적극적으로 사용할 필요가 있다.
- 일반적으로는, 데이터베이스 시스템에서 데이터 정합성을 체크할 수 있다면 데이터베이스에 맡겨버리는 편이 가장 확실하고 편리하다.
- 이런 기능을 활용하는 대신 애플리케이션에서 따로 구현해 사용할 수도 있지만, 이런 경우 정합성이 맞지 않을 수 있으며 개발비용도 상승해 추천하지 않는다.
- 한편, 앞에서 예로 든 '1, 2, 3' 등의 경우 각 숫자에 '상, 중, 하'와 같은 의미를 부여해 데이터를 사용할 때는 정의서의 비고란에 적어두는 경우가 많다.
- 데이터의 의미를 따로 정의할 수 없기 때문에 비고란도 중요한 역할을 한다.
    - `MySQL`에서는 테이블을 작성할 때 `comment`라는 키워드를 이용하여 주석을 열 단위로 기입해 둘 수 있다.

### 고정길이와 가변길이
- 문자열의 자료형에는 고정길이와 가변길이가 있다.
- 어느쪽으로 지정할 것인지는 저장할 데이터를 고려해 결정한다.
- 예를 들어 제조번호처럼 자리수가 이미 정해져 있는 경우에는 고정길이 문자열로 지정하는 편이 좋다.
- 데이터의 최대길이 역시 제조번호의 자릿수에 맞춰 정하면 된다.
- 한편, 비고란과 같이 자주 입력되지도 않지만 입력되는 문자열의 길이의 변동폭이 클 경우에는 가변길이 문자열이 적합하다.
- 데이터베이스의 열에 저장할 수 있는 크기는 의외로 작다.
- `VARCHAR` 형으로 지정할 수 있는 최대 크기는 기껏해야 수천 바이트이다.
- 조금 큰 파일을 그대로 `VARCHAR` 형의 열에 저장하면 쉽게 용량을 넘겨버린다.
- 이러한 경우에는 `LOB` 형을 사용한다.
- 여기서 `LOB`는 `Large Object`의 약자이다.
- `LOB`형은 큰 데이터를 다루는 자료형이지만 인덱스를 지정할 수 없다는 제약이 있다.

##### 큰 데이터는 LOB 형으로 저장할 수 있다!

### 기본키
- 테이블을 작성할 때 기본키 제약을 거는 경우에는 주의를 기울여야 한다.
- 테이블의 행에 유일성을 지정한다는 것은 대단히 중요한 일이다.
- 하지만 기본키로 지정할 열이 생각나지 않는 경우도 많을 것이다.
- 이러한 경우 자동증가 열을 사용해서 기본키로 지정하면 간단하게 해결할 수 있다.
- 자동증가 열은 `INSERT` 할 경우 번호를 자동으로 증가시켜 저장해주는 편리한 열이다.
- 데이터베이스 제품에 따라 다르지만, `MySQL`의 경우는 열을 정의할 때 `AUTO_INCREMENT`를 지정하는 것으로 자동증가 열이 된다.
- `AUTO_INCREMENT`로 지정한 열은 `PRIMARY KEY` 또는 `UNIQUE`로 유일성을 지정해야 한다. 아무 열이나 자동증가 열로 지정하지 않도록 주의해야 한다.
- 테이블 설계에 관련해 정규화라는 것도 있다(추후에 설명).
- 지금까지 소개한 여러 요소들을 바탕으로 테이블 정의서가 작성되므로 테이블 정의서를 소홀하게 여기지 않도록 하자.

---

## 2. ER다이어그램
- 테이블을 설계할 때 테이블 간의 관계를 명확히 하기 위해 설계도를 작성하는 경우가 있다.
- `ER다이어그램`은 이런 경우에 널리 쓰이는 도식이다.
- `ER`의 `E`는 개체를 뜻하는 `Entity`의 약자이며 `R`은 `Relationship`의 약자이다.
- 즉, `ER다이어그램`은 개체 간의 관계를 표현한 것이다.
- 여기에서도 관계라는 단어가 나오는데, ER다이어그램의 관계는 관계형 데이터베이스의 릴레이션과 달리 릴레이션십을 가리킨다.
- 여기서는 헷갈리지 않도록 릴레이션십을 연계라 불러 구별한다.
- 이 같은 ER다이어그램은 관계형 데이터베이스 외의 대상에 대해서도 사용된다.
- 엔티티, 즉 개체는 테이블 또는 뷰를 말한다.
- ER다이어그램에서 개체는 사각형으로 표기한다. 사각형의 상단에는 개체 이름을 적고 사각형 안에는 개체의 속성을 표기한다.
- 여기서 속성은 테이블의 열을 의미한다.
- 기본키가 되는 열부터 차례로 기술하며, 열 이름은 주로 논리명으로 표기한다.
- 개체와 개체가 서로 연계되는 경우에는 선으로 이어서 표현한다.
- 앞에서 결합을 설명할 때 작성했던 상품 테이블과 메이커 테이블은 메이커코드를 매체로 연결된다.
- 이것을 ER다이어그램으로 표현하면 다음과 같다.

![34강 ER다이어그램의 개체와 연관](https://user-images.githubusercontent.com/68052095/102681144-69f58d00-4202-11eb-9321-6955bc14a7f2.png)

- 연계를 표기할 때는 서로 몇 개의 데이터 행과 연관되는지, 즉 몇 대 몇의 관계를 가지는지를 숫자나 기호로 나타낼 수 있다(카디널리티 또는 다중도라고 한다).
- 이는 매우 중요한 것으로, 여러 가지 패턴의 표기방법 중에서도 가장 기본적인 세 가지는 다음과 같다.
    - 일대일(1 : 1)
    - 일대다(1 : 多)
    - 다대다(多 : 多)
- ER다이어그램의 연계는 데이터베이스에서는 외부참조제약(외부키 제약)으로 지정되는 경우가 있으므로 기억해두자.
- 외부키 제약을 설정하면 데이터의 정합성이 엄격히 관리되어 번거로워진다는 이유로 이를 채용하지 않는 시스템도 있다.
- `설계상 이렇게 연관되어 있다`라고 나타내는 것이 ER다이어그램의 역할이다.

---
