---
# System prepended metadata

title: Relational Data Model

---

# Relational Data Model

## Definition

Relational Database Management System

![](https://i.imgur.com/8TJnaUK.png =500x)

### Domains

由許多 atomic value 組成的集合，atomic values 代表無法再被分割的值，像是電話：0987654321，再被分割會變得沒有意義。

### Tuple

> A tuple is a partial function from attribute names to atomic values.

## Normalization

在實務上，Boyce-Codd normal form(BCNF) 被視為大部分應用程式所需的最高階正規形式。

正規化是循序漸進的過程，亦即資料表必須滿足第一正規化的條件之後，才能進行第二正規化，如此類推。

![](https://i.imgur.com/3K3zkZn.png =400x)

![](https://i.imgur.com/HXaPSOy.png =400x)

### 第一正規化 First Normal Form (1NF)

第一正規化是為了要 ==**排除重複群**== 的出現。採用的方法是要求資料庫的每個attribute 都是由 atomic value 組成。

下表以賣大頭菜為例，數量就出現了重複群的狀況。

| Name   | Date       | Count |
|--------|------------|-------|
| Celine | 2020-05-07 | 40,40 |
| Joe    | 2020-05-07 | 40,40 |
| Wayne  | 2020-05-08 | 40    |

==**每個欄位只存一個值**==，所以修改之後會像這樣：

| Name   | Date       | Count |
|--------|------------|-------|
| Celine | 2020-05-07 | 40    |
| Celine | 2020-05-07 | 40    |
| Joe    | 2020-05-07 | 40    |
| Joe    | 2020-05-07 | 40    |
| Wayne  | 2020-05-08 | 40    |

但這樣可以看到在 row 上出現了重複的值，沒辦法分辨是賣第幾次大頭菜，所以應該為每一次賣菜，也就是每一個 ==**row 加上 Primary key**==，來確保他的唯一性。

| Id | Name   | Date       | Count |
|----|--------|------------|-------|
| 1  | Celine | 2020-05-07 | 40    |
| 2  | Celine | 2020-05-07 | 40    |
| 3  | Joe    | 2020-05-07 | 40    |
| 4  | Joe    | 2020-05-07 | 40    |
| 5  | Wayne  | 2020-05-08 | 40    |

### 第二正規化 Second Normal Form (2NF)

==**消除任何欄位與主鍵部分相依**==。

一樣以賣大頭菜為例：

| Id | Name | Island Name | Date | Price |
|----|------|-------------|------|-------|
| 1  | 臻臻 | 學長把我撲島 | 2020-05-07 | 115 |
| 2  | 臻臻 | 學長把我撲島 | 2020-05-08 | 110 |
| 3  | 品菇 | 島島島 | 2020-05-07 | 431 |
| 4  | 品菇 | 島島島 | 2020-05-08 | 85 |
| 5  | Wayne | 卡娜島 | 2020-05-07 | 102 |
| 6  | Wayne | 卡娜島 | 2020-05-07 | 233 |

如果今天有人改名或改島名了（~~雖然不能改~~），要改就會很麻煩。所以要 ==**將無關主鍵的欄位獨立出來**==：

| Id | Name | Island Name |
|----|------|-------------|
| 1  | 臻臻 | 學長把我撲島 |
| 2  | 品菇 | 島島島 |
| 3  | Wayne | 卡娜島 |

如此一來原本的菜價 table 就會水噹噹：

| Id | Player Id | Date       | Price |
|----|-----------|------------|-------|
| 1  | 1         | 2020-05-07 | 115   |
| 2  | 1         | 2020-05-08 | 110   |
| 3  | 2         | 2020-05-07 | 431   |
| 4  | 2         | 2020-05-08 | 85    |
| 5  | 3         | 2020-05-07 | 102   |
| 6  | 3         | 2020-05-07 | 233   |

==**檢查資料表裡的每個欄位，確認它們是不是都和關鍵詞完全相關**==，如果不是的話，就把那些不完全相關的欄位移到獨立的資料表裡。

### 第三正規化 Third Normal Form (3NF)

==**所有非鍵值欄位的資料必須只能與主鍵有相關性，而非鍵值欄位之間彼此不能有相關性**==。



> 這邊有點和 2NF 搞混，我目前的理解是：他和主 key 有關聯沒錯，但又和其他欄位也有關聯，這時候就必須拆出去。
> [color=red]


## One-to-One

雖然一對一可以直接在同一個 table 做掉，但拆開 table 存放有個最大好處是：**權限控管**。例如：員工與他的密碼。

Resource 不同、力度不同的資料也可以用一對一的方式拆開。

## One-to-Many

例如：一個學生可以選擇很多課程。一對多的好處是，可以避免打錯字造成對不上的情況，如果今天課程改名字，也僅只需修改一個地方。

## Many-to-Many

好處是做操作時只需要動一個地方，第一個案例不好的點是，如果要新增一個學生選了什麼課，就要在兩邊的操作，很容易有誤。

:x: ![](https://i.imgur.com/Nz29DZD.png =500x)
:o: ![](https://i.imgur.com/wdyxXHT.png =500x)
Junction table
Intermediary table

## ACID

為確保 Transaction 正確可靠，具備四個特性：

 - Atomicity 原子性

   只有兩種可能發生，第一種是全部完成 commit，第二種是全部不完成 rollback，在出錯之後會恢復至交易之前的狀態，如同還沒執行此筆交易。

 - Consistency 一致性

   A 轉了 10 元給 B，結果 B 只拿到 5 元就是不一致，這時候資料庫比須取消這項操作

 - Isolation 隔離性

   資料庫允許多筆交易同時進行，交易進行時未完成的交易資料並不會被其他交易使用，直到此筆交易完成。

 - Durability 持續性

   交易完成後對資料的修改是永久性的，資料不會因為系統重啟或錯誤而改變。