###### tags: `database` # Assignment 1: Relational Models & Normal Form > Author: NTHU CS 109062264 楊子慶 > > Course: CS471000 Introduction to Database Systems > > Instructor: Shan-Hung Wu ## Problem 1 ### Problem Description * Scenario Let's say we want to design a database to manage the relationships between projects, professors, and students. - Each professor has an id, a name, and a rank. - Each project has a project number, a sponsor name (e.g. MOST), a starting date, an ending date, and a budget. - Each student has a student id, a name, and a degree program (Bachelor, Master or PhD). - Each project is managed by a professor. It is possible that a professor manages multiple projects. - Each student is supervised by a professor. It is possible that a professor supervises multiple students. - A student is able to work on a project. It is possible that a student participates in multiple projects. - It should record when a student starts working on a project, when he/she stops, and how much he/she is paid per month. * Question 1. Please design an ER model and draw an ER diagram for this scenario. (30 points) 2. Please design a relational model for this scenario with the following constraints. (30 points) - You should use SQL `CREATE TABLE` to present your schema. - You should `identify primary keys and foreign keys relationships` in your SQLs. - You can only use [data types in PostgreSQL][1]. - The relations should at least follow `the 3rd normal form`. [1]: https://www.postgresql.org/docs/14/datatype.html ### ER Model in ER Diagram Notice that - Ovals are attributes. - Rectangles (along with ovals) are entity classes. - Diamonds are relationships. - Relationships may also have attributes. - Primary keys are underlined. ```graphviz graph hw1 { rankdir = RL; Professors[shape=box]; pf_id[label=<<u>pf_id</u>>]; pf_id -- Professors; pf_name -- Professors; rn[label="rank"]; rn -- Professors; Students[shape=box]; s_id[label=<<u>s_id</u>>]; s_id -- Students; s_name -- Students; degree -- Students; Projects[shape=box]; proj_number[label=<<u>proj_number</u>>]; proj_number -- Projects; sponser_name -- Projects; start_date -- Projects; end_date -- Projects; budget -- Projects; Supervise[shape=diamond]; Professors -- Supervise; Supervise -- Students; Manage[shape=diamond]; Professors -- Manage; Manage -- Projects; Work_on[shape=diamond]; Work_on -- Students; Work_on -- Projects; start_work[label="start_work_date"]; end_work[label="end_work_date"]; payment_per_month -- Work_on; start_work -- Work_on; end_work -- Work_on; } ``` ### Relational Model in SQL form ```sql CREATE TABLE Professors ( pf_id INTEGER, pf_name VARCHAR(20), rank VARCHAR(30), PRIMARY KEY (pf_id) ); CREATE TABLE Students ( s_id INTEGER, s_name VARCHAR(20), degree VARCHAR(10), PRIMARY KEY (s_id) ); CREATE TABLE Projects ( proj_number INTEGER, sponsor_name VARCHAR(20), start_date Date, end_date Date, budget INTEGER, PRIMARY KEY (proj_number) ); CREATE TABLE Manage ( pf_id INTEGER, proj_number INTEGER, PRIMARY KEY (pf_id, proj_number), FOREIGN KEY (pf_id) REFERENCES Professors, FOREIGN KEY (proj_number) REFERENCES Projects ); CREATE TABLE Supervise ( s_id INTEGER, pf_id INTEGER, PRIMARY KEY (s_id, pf_id), FOREIGN KEY (s_id) REFERENCES Students, FOREIGN KEY (pf_id) REFERENCES Professors ); CREATE TABLE WorkOn { s_id INTEGER, proj_number INTEGER, start_work_date Date, end_work_date Date, payment_per_month INTEGER, PRIMARY KEY (s_id, proj_number), FOREIGN KEY (s_id) REFERENCES Students, FOREIGN KEY (proj_number) REFERENCES Projects } ``` ## Problem 2 ### Problem Description |forum_name|popularity|post_id|title|article|reply| |---|---|---|---|---|---| |Gossiping|100|131|Girlfriend|How can I get girlfriend ?|["Haha", "I don't know"] |Gossiping|100|252|Firends|I don't have a friend...|["Haha", "I can be", "QQ"] |Joke|23|46|Knock|Knock! Knock! ...|["Then?", "What's the point ?"] |Joke|23|151|Santa Claus|Hold! Hold! Hold!|["XDD"] Here are its functional dependencies: - forum_name -> popularity - {forum_name, post_id} -> {title, article, reply} Please decompose the table to make it **follow the 3rd normal form and identify which field(s) should be primary key(s)**. You must also keep the data in the table. You may add new fields to preserve the above relationships. (40 points) ### Decomposed Tables Underlined attributes are primary keys. * forum information table |<u>forum_name<u>|popularity| |---|---| |Gossiping|100| |Joke|23| * Article table (`article_id -> { forum_name, post_id }`) | <u>article_id<u> | forum_name| post_id | title | article | |:----------------:| ---------------- | ------------- | ----------- | -------------------------- | | 0 | Gossiping | 131 | Girlfriend | How can I get girlfriend ? | | 1 | Gossiping | 252 | Firends | I don't have a friend... | | 2 | Joke | 46 | Knock | Knock! Knock! ... | | 3 | Joke | 151 | Santa Claus | Hold! Hold! Hold!| * Reply table Since number of replies is unfixed for each articles, I split the reply message into a new table. |<u>reply_id<u>|article_id|reply| |---|---|---| |0|0|"Haha" |1|0|"I don't know" |2|1|"Haha" |3|1|"I can be" |4|1|"QQ" |5|2|"Then?" |6|2|"What's the point ?" |7|3|"XDD"