---
# System prepended metadata

title: HW2B Report
tags: [DB]

---

---
tags: DB
---
<style>
    H1{
        text-align: center;  /* 題目置中 */
    }
    H4{
        text-align: right;  /* 題目置中 */
    }
    blockquote > P {    /* Blockquote 取消第一行兩格*/
        text-indent: 0;
    }
    .markdown-body > h4 {   /* 讓限制那行離上面近一點 */
        padding: 0;
        margin: 0;
    }
    .markdown-body > h1 {
        border-bottom: 0;
        padding: 0;

    }
</style>


# HW2B Report
#### 409410050 資工二 王謙靜

## part6
### relational schema
![](https://i.imgur.com/i5S59Ls.png)
### 建立table之DDL
**employee**
```sql
CREATE TABLE employee (
    e_id int PRIMARY KEY NOT NULL,
    e_name varchar(30) NOT NULL, 
    salary varchar(30) NOT NULL, 
    manager_id int, 
    CONSTRAINT manage_by_fk FOREIGN KEY (manager_id) REFERENCES employee(e_id)
);
```
**salesman**
```sql
CREATE TABLE salesmen(
    s_id int PRIMARY KEY NOT NULL,
    CONSTRAINT salesmen_fk FOREIGN KEY (s_id) REFERENCES employee(e_id)
);
```
**policies**
```sql
CREATE TABLE policies (
    p_id int PRIMARY KEY NOT NULL, 
    p_name varchar(30) NOT NULL, 
    beneficiary varchar(30) NOT NULL, 
    amount int NOT NULL,
    s_id int NOT NULL, 
    CONSTRAINT sold_fk FOREIGN KEY (s_id) REFERENCES salesmen(s_id)
);
```
### 假設
1. 會查詢salesmen有誰
2. 每個員工都可以找到至多一一個manager
### entity
**employee**:有三個attritube，且key是ID，故employee的table中有三個column: ++ID++, Name, Salary。
**policies**:有四個attritube，且P#是key，故policies的table中有四個column:++p_id++, p_name, beneficiary, amount。(由於無法以'#'命名，故將P#改名為p_id)
**salesmen**:繼承自employee，故其key為employee，因為可能會有查詢問說誰是salesmen，若不保留則無法得知。salesmen table中有一個column:++s_id++，且s_id是employee中e_id的foreign key，其有constraint限制每個salesmen都必須是employee。
### relation
**manage**:是一個一對多的關係，每個員工都可以找到至多一一個manager，故在employee中有另一column :manager_id，紀錄每個employee的manager，其有Foreign key指向employee，代表manager一定要是employee。
**sold**:是一對多的關係，每個policies都可以對應到唯一一個salesmen，故在policies中另有一個column: s_id，記錄其對應到的salesmen，其有Foreign key指向salesmen，檢查s_id是否在salesmen中。由於policies與sold之間有total participation所以s_id保證為空。
### 截圖
![](https://i.imgur.com/rasCjah.png)
![](https://i.imgur.com/pgVONF0.png)
![](https://i.imgur.com/kV4Bw4L.png)
![](https://i.imgur.com/h2fQjeR.png)
![](https://i.imgur.com/nlRiWsA.png)

## part7
圖一
![](https://i.imgur.com/t0k9Uql.png)

**R** : R有三個attritube，所以R table中有三個column: ++a++, b, c，其中a為key。
**S** : S是一個weak entity，所以要把owner entity的key也寫進S的table中，故S table中有兩個column:a, d，其中a, d合起來為一個key。
**T** : T繼承於S。故要把S的key也寫進T的table中，另有兩個attritube，故T table有四個column:a, d, f, g，其中a, d為key。
圖二
![](https://i.imgur.com/qiwGTSW.png)
**R** : R有三個attritube，所以R table中有三個column: ++a++, b, c，其中a為key。
**S** : 由於S relation兩邊為多對多，所以S table有兩個column: a, d，且以a, d兩者合併當作key
**T** : 由於T relation兩邊為多對多，所以T table有兩個column: a, d，且以a, d兩者合併當作key。而T另有兩attritube，故T table另有兩個column:f, g
**K**:由於k沒有其他的attritube，且所有k都會參加S relation，所以可以不用用另一個table紀錄，想知道k有誰有可以查詢所有S table的所有d。

## part8
### ER-diagram
![](https://i.imgur.com/BzxDw20.png)


### 假設
1. 每個位置(location)只會有一個科系(department)，且每個科系都要有位置。
2. 對於每個科系(department)需要另外記錄其所擁有的經費
3. 要記錄每個網球場上一次的維修時間(remain_time)
4. time slot中要記錄使用者的使用時間(use_time)
5. 每個學生都必定恰好有一個科系
6. 每個科系都一定會有教授和學生，且可能不只一個
7. 每個體育館都有球場
### entity
**user** : 透過`A user is identified by the NetID. We also record the name of the user.`的文字說明，我們可以知道有一個user entity，並有NetID作為key attritube以及u_name做non key attritube
**student** : 透過`We have three kinds of users: student, professor, and staff. Students additionally have a status recorded (such as freshman, sophomore, junior, senior, MS, PhD)`的說明，我們可以知道student其實是user的一種，因此student繼承了user(在圖上用ISA表示)，並另外有一個atrritube: status紀錄目前學生的年級。
**professor** : 透過`We have three kinds of users: student, professor, and staff.`的說明，我們可以知道professor繼承了user，故在圖上用ISA表示。透過`A professor additionally 
has a record of the rank (assistant professor, associate, 
etc.).`，可以知道另外有一個atrritube: rank紀錄目前教授的等級(教授、副教授...等)。
**staff** : 透過`We have three kinds of users: student, professor, and staff.`的文字說明，我們可以知道staff繼承了user，故在圖上用ISA表示。透過`We also record the title of a staff`的說明，可以知道staff要記錄其職稱，故另外有一個atrritube: title。
**department** : 透過`There are departments in the university.`以及`A professor can be affiliated with many 
departments.`可以知道需要紀錄department，且因professor可能有多個department，故department不能作為attritube存在professor的entity中。透過`A department is identified by its name.`以及假設2，可以知道department有一個key attritube: d_name以及non key attritube: funding。
**location** : 透過`A location is identified by its address. A department may reside in multiple locations.`由於一個department可能有多個location，所以不能夠以attritube的形式存在於ER-diagram中，故讓location成為一個entity並有address當作key。
**stadiums** :`The stadiums體育場 have unique names and can be at one location.` 得知需要一個stadiums entity，並以s_name當key，且另有一個名為location的attritube。
**tennis_court** : `A tennis court is identified by the name of the stadium that contains it, and its own court number.`可知有tennise_court entity是由stadiums的key以及自己的partial key: number合併當作key的entity，由於需要其他entity才能確定唯一，故tennis_court是weak entity，其identity relation是set_in(set_in為記錄球場與體育館的relation)。由於假設3，另外有一個atrritube:maintain_time。
**time** : `We keep track of reservation time slots by its date and hour.`可知有一個entity叫作time，他有date，和hour(分別表示日期與時間)，由於假設4之下，不同的date與hour可能會有不同的使用時間，所以time是一個weak entity。透過user或者tennise_court都可以唯一決定一個時間資料，故user與tennis_court都是time的owner entity，透過NetID或者tennis_court的key加上date和hour都可以唯一找到一組time，故time的identity relation可以是use或revserve。
### relation
**study_int** : 記錄學生與科系之間的關係，透過`A student can only belong to one department.`可以知道學生有唯一的科系且必定要有一個科系，故student與study_in之間有key constraint和total participation。因為假設每個科系都會有學生，所以department與study_in間有total participation，但因科系可能有不只一個學生，所以沒有key constraint。
**work_in** : 記錄教授與科系之間的關係，透過`A professor can be affiliated with many departments.`可知教授與科系為多對多的relation，可能有一個教授屬於多個科系，也可能有一個科系有多個教授，所以professor與work_in間和department與work_in之間都沒有key constraint。因為每個教授都必須要有科系，且每個科系都要有教授，所以professor與work_in間和department與work_in之間都有total participation。
**reside** : 記錄每個科系的位置，由於一個系可能有多個位置，且每個科系都要有至少一個位置，故department與reside間有total participation但沒有key constraint。因假設一個位置只會有一個科系，且不一定所有位置都是系館，所以location與reside之間只會有key constraint而沒有total participation。
**set_in** : 網球場與體育館的關係(網球場設立在體育館中)，因為網球場可以靠它找到唯一一個體育館，並且所有網球場都隸屬於體育館內，故set_in與tennis_court之間有total participation與key constraint。由於tennis_court必須透過set_in來找到一個體育館使自己是unique，故set_in是一個identity relation(relation 加粗)。由於每個體育館可能有多個球場，且每個體育館都要有球場，所以set_in與stadiums之間沒有key constraint，但有total participation
**use** : 記錄使用者與time的關係，因為每個使用者可能在不同時間使用球場，且非每個使用者都會使用球場(可能有人不會打網球)，故user與use之間沒有total participation以及key constraint。因為每一筆time都必須洽好屬於一個user，所以time與use之間有total participation以及key constraint。由於time可以透過use以及自己的partial key來唯一決定一筆資料，所以use是time的identity relation(use 加粗)。
**reserve** : 記錄time與球場的關係，因為每個球場可能在不同時間被使用，且非每個球場都會被使用(可能特別遠沒有人想用)，故tennis_court與reserve之間沒有total participation以及key constraint。因為每個預約的時間都必須恰好有一個球場，所以time與reserve之間有total participation以及key constraint。由於time可以透過tennis_court以及自己的partial key來唯一決定一筆資料，所以reserve是time的identity relation。

### relational schema
![](https://i.imgur.com/VRMwU0n.png)

**user**, **department**, **stadiums**, **location**: 因為他是strong entity，所以直接將它變成table，且把ER-diagram上的key當成table的key。
**student**, **professor**, **staff**:三者都繼承自user，把user的key當作table的key並加入對應各自atrritube的column。由於user一定要存在，才可能有student, professor, staff，所以NetID是Foreign key，必須要constraint才能確保student, professor, staff的合理性。
**study_in**:他是一個一對多的關係，每個學生都只會有一個科系，所以可以在student的table新增一個column記錄department的key。由於有total participation所以新增的column的值不會有NULL。d_name也是forign key，因此也需有constraint確定科系存在
**work_in**:多對多的關係，故將它畫成一個table，並把professor的key和department的key寫進table中，並把兩個column綁在一起當key。NetID與d_name都是foreign key，NetID是存professor，必須確定professor合法，才能有work_in關係，d_name則是存科系，同樣要確定科系合法，才能有work_in關係。
**reside**:一(department)對多(location)的relation，所以將deparment的值寫進location的另一個column中，由於location與reside之間沒有total participation，所以會有NULL。由於把department的key寫進reside，故新增的column也是foreign key。
**tennis_court**, **set_in**:他是一個weak entity，他的identity relation是set_in，owner entity是stadiums，所以把stadiums的key以及自己的partial key合在一起當key，並將另一個attritube轉換成column。其中s_name是foreign，他來自stadiums。
**time**, **use**, **reserve**:time是一個weak entity，user的key與time的partial key和tennis_court的key與time的partial key合起來都可以是time的key(use與reserve皆為identity relation)，在這裡我們選擇用user作為owner entity，因為key的數量較少，所以選擇user當owner entity。將user的key:NetID和time的partial key綁在一起，time的schema中有NetID, date, hour三個組合而成key，以及一個use_time column(attritube直接轉成column)。而reserve relation則另外處理，由於reserve是一(time)對多(tennis_court)的關係，所以我們可以在time table中新增column，並將tennis_court的key存在那個column中，由於有total participation，所以那個column為非空。其中NetID(來自user), s_name, c_number(來自tennis_court)為foreign key。

### DDL
**user**
```sql
CREATE TABLE user (
    NetID int PRIMARY KEY NOT NULL,
    u_name varchar(30) NOT NULL
);
```
**department**
```sql
CREATE TABLE department (
    d_name varchar(30) PRIMARY KEY NOT NULL,
    funding int NOT NULL
);
```
**student**
```sql
CREATE TABLE student (
    NetID int PRIMARY KEY NOT NULL,
    status varchar(30) NOT NULL,
    d_name varchar(30) NOT NULL,
    CONSTRAINT user_student_fk FOREIGN KEY (NetID) REFERENCES user(NetID),
    CONSTRAINT depart_student_fk FOREIGN KEY (d_name)
    REFERENCES department(d_name)
);
```
**professor**
```sql
CREATE TABLE professor (
    NetID int PRIMARY KEY NOT NULL,
    p_rank varchar(30) NOT NULL,
    CONSTRAINT user_professor_fk FOREIGN KEY (NetID) REFERENCES user(NetID)
);
```
**staff**
```sql
CREATE TABLE staff (
    NetID int PRIMARY KEY NOT NULL,
    title varchar(30) NOT NULL,
    CONSTRAINT user_staff_fk FOREIGN KEY (NetID) REFERENCES user(NetID)
);
```

**work_in**
```sql
CREATE TABLE work_in(
    NetID int NOT NULL, 
    d_name varchar(30)NOT NULL,
    PRIMARY KEY (NetId, d_name),
    FOREIGN KEY (NetID) REFERENCES professor(NetID),
    FOREIGN KEY (d_name) REFERENCES department(d_name)
);
```
**location**
```sql
CREATE TABLE location(
    address varchar(30) PRIMARY KEY NOT NULL,
    d_name varchar(30) NOT NULL,
    CONSTRAINT locate_fk FOREIGN KEY (d_name) REFERENCES department(d_name)
)
```
**stadiums**
```sql
CREATE TABLE stadiums(
    s_name varchar(30) PRIMARY KEY NOT NULL,
    address varchar(30) NOT NULL
)
```
**tennis_court**
```sql
CREATE TABLE tennis_court(
    s_name varchar(30)NOT NULL,
    c_number int NOT NULL,
    maintain_time varchar(30) NOT NULL,
    PRIMARY KEY (s_name, c_number),
    CONSTRAINT stadiums_fk FOREIGN KEY (s_name) REFERENCES stadiums(s_name)
)
```
**time**
```sql
CREATE TABLE time(
    NetID int  NOT NULL,
    date varchar(20) NOT NULL,
    hour int NOT NULL,
    use_time int NOT NULL,
    s_name varchar(30) NOT NULL,
    c_number int  NOT NULL,
    PRIMARY KEY (NetID, date, hour),
    UNIQUE KEY(s_name, c_number, date, hour),
    CONSTRAINT ti_stadiums_fk FOREIGN KEY (s_name, c_number)
    REFERENCES tennis_court(s_name, c_number),
    CONSTRAINT user_ti_fk FOREIGN KEY (NetID)
    REFERENCES user(NetID)
)
```

![](https://i.imgur.com/RztfkV7.png)
![](https://i.imgur.com/hHtyuYU.png)
![](https://i.imgur.com/Xb1C3zg.png)
![](https://i.imgur.com/5R2Vg07.png)
![](https://i.imgur.com/KR3cHly.png)
![](https://i.imgur.com/UxsWsiM.png)
![](https://i.imgur.com/q2vsvQX.png)
![](https://i.imgur.com/mkFtz1E.png)
![](https://i.imgur.com/Sas7MFE.png)
![](https://i.imgur.com/rtLM72x.png)


## part9
### ER-diagram
![](https://i.imgur.com/WalH4Pw.png)
### 假設
1. 一輛車只記錄一種顏色
2. 一輛車只有一個製造商
3. car與reservation的狀態都只記最新的
4. 每一個顧客只記一份payment_information, address, contact number
### entity
**car** : 一輛車要記錄license plate, manufacturer, model, made year, color, hourly, daily,monthly rates和status。由於對於每輛車來說這些值都是唯一的，所以car為entity有以上9個attritube，且題目有說到我們可以透過license plate辨認車子，所以我們可以把license_plate當作car的key
**customer** : 每位顧客要記錄 customer id, name, address, contact number, driving license number和payment information。由於對於每個顧客來說這些值都是唯一的，所以customer為entity有以上6個attritube，且題目有說到可以用id辨識客人，顧id是customer的key。
**reservation** :每筆預約訂單要記錄R_id(unique 
identification number), p_date(pick up date), p_time(pick up time) , r_date(return date), r_time(return time), amount, status，由於每個值都只有一個，所以都可以變成reservation的attritube(共7個attritube)，其中以R_id當key，因為他可以保證唯一。
### relation
**rent** : 記錄車與預約的關係。因為每個預約都必須恰好有一台車，所以reservation與rent間有total participation以及key constraint。因為可能有車沒被預約過，或者被不同訂單預約，所以既沒有total participation，也沒有key constraint。
**serve** : 記錄顧客與預約的關係。因為每個預約都必須恰好有一為顧客，所以reservation與serve間有total participation以及key constraint。因為可能有人沒預約過，或者預約多次，所以既沒有total participation，也沒有key constraint。
### relational schema
![](https://i.imgur.com/36SPkI2.png)


### DDL
**car**
```sql
CREATE TABLE car(
    license_plate varchar(30) PRIMARY KEY NOT NULL,     
    manufacturer  varchar(30) NOT NULL,
    model varchar(30) NOT NULL,
    made_year int NOT NULL,
    color varchar(30) NOT NULL,
    hourly_rates int NOT NULL,
    daily_rates int NOT NULL,
    monthly_rates int NOT NULL,
    status varchar(30) NOT NULL
);
```
**customer**
```sql
CREATE TABLE customer(
    id int PRIMARY KEY NOT NULL,
    address varchar(50),
    name varchar(30) NOT NULL,
    driving_license varchar(30) NOT NULL,
    payment_information varchar(30) NOT NULL,
    contact_number varchar(20) NOT NULL
);
```
**reservation**
```sql
CREATE TABLE reservation(
    R_id int PRIMARY KEY NOT NULL,
    amount int NOT NULL,
    p_date varchar(30) NOT NULL,
    p_time varchar(30) NOT NULL,
    r_date varchar(30) NOT NULL,
    r_time varchar(30) NOT NULL,
    status varchar(30) NOT NULL,
    license_plate varchar(30) NOT NULL,
    customer_id int NOT NULL,
    CONSTRAINT rent_fk FOREIGN KEY (license_plate) REFERENCES car(license_plate),
    CONSTRAINT serve_fk FOREIGN KEY (customer_id) REFERENCES customer(id)
);
```
**car** : car是strong entity所以直接將所有attritude變成column，並將key設為license_plate(ER-diagram上car的key)
**customer** : customer是strong entity所以直接將所有attritude變成column，並將key設為id(ER-diagram上customer的key)
**reservation** : reservation是strong entity，所以直接將attritube變成column，並將R_id設為key(ER-diagram上reservation的key)。
**rent** : 由於他是一(car)對多(reservation)的relation，所以直接把car的key放到reservation的table中，並設置foreign key，避免reservation訂到不在資料庫中的車，由於有total participation，所以reservation中的license_plate為not null
**serve** : 由於他是一(customer)對多(reservation)的relation，所以直接把customer的key放到reservation的table中(customer_id)，並設置foreign key，避免reservation與不在資料庫內的客人訂定預約，由於有total participation，所以reservation中的customer_id為not null

![](https://i.imgur.com/Hih6FkK.png)
![](https://i.imgur.com/mMTvH2W.png)
![](https://i.imgur.com/c1l5brB.png)

## 問題排解
mysql無法以`#`, `rank`命名
![](https://i.imgur.com/HDh3yeW.png)
![](https://i.imgur.com/bbozRCe.png)
rank 為mysql 語法之一
解法:換個名字

tennis_court的c_number不是key，無法用它來做foreign key
![](https://i.imgur.com/M35hk1R.png)
因為tennis 的key是s_name+c_number，所以c_number不能唯一指定一個tennis_court，所以foreign constraint會失敗，找不到唯一一個球場。
解決:把s_name和c_number綁再一起去做foreign key。

## reference
https://www.itread01.com/content/1546832286.html
https://discuss.codecademy.com/t/error-code-1822-failed-to-add-the-foreign-key-constraint-missing-index-for-constraint-employees-ibfk-1-in-the-referenced-table-departments-0-000-sec/559058
https://stackoverflow.com/questions/26329775/error-code-1822-failed-to-add-the-foreign-key-constaint-missing-index-for-con
