# DFU 02 ## Planning & Normalization --- ## Database Design ---- #### Step 1 Requirements analysis * Planning * System Definition ---- #### Step 2 Database Design * Conceptual model * Logical model * Physical model ---- #### Step 3 Implementation * Structure and Implementation * Data Implementation * Testing --- ## Entity Relations ---- ### Diagram Levels | Features | Conceptual | Logical | Physical | | :------- | :--------: | :------: | :------: | | Entities | ✓ | ✓ | ✓ | | Relationships | ✓ | ✓ | ✓ | | Attributes | | ✓ | ✓ | | Attributes Types | | ❕ | ✓ | | Keys | | ❕ | ✓ | ---- ### Entities Objects or concepts in the system that store data (e.g., Customer, Order). | Level | Description | | :---- | :--- | | Conceptual | Yes (broad, main concepts) | | Logical | Yes (detailed, refined) | | Physical | Yes (specific implementation) | ---- ### Relations Connections between entities that show how they interact. | Level | Description | | :---- | :--- | | Conceptual | Yes (high-level connections) | | Logical | Yes (with cardinalities) | | Physical | Yes (ready for implementation incl. composite tables) | ---- ### Attributes Properties of details that describe an entity (e.g. Customer Name, Order Date). | Level | Description | | :---- | :--- | | Conceptual | No (only focus on entities/relations) | | Logical | Yes (all attributes defined) | | Physical | Yes (attributes ready for implementation) | ---- ### Attribute Types The kind of data an attribute holds, such as text, number, or date. | Level | Description | | :---- | :--- | | Conceptual | No (not defined) | | Logical | Sometimes as abstract types (e.g. string, number) | | Physical | Yes (DBMS-specific types like VARCHAR, INT) | ---- ### Keys Unique identifiers that distinguish records and define relationships (e.g., primary key, foreign key). | Level | Description | | :---- | :--- | | Conceptual | No (not defined) | | Logical | Yes (primary keys, candidate keys) | | Physical | Yes (primary keys, foreign keys, unique constraints) | --- ## Diagram Syntax ---- ### Diagram Notations #### Common ERD Notation  ---- ### Diagram Notations #### IDEF1X Notation  ---- ### Cardinality Notation #### Chen Notation * Uses **numbers** or **words** near the relationship line * Examples: * `1` or `one` * `n` or `many` * Sometimes `(0,1)`, `(1,1)`, `(0,n)`, `(1,n)` for optionality and multiplicity ---- ### Crows Feet Notation * Uses symbols on the line ends *  ---- ### UML Class Diagram Style * Uses **multiplicity** ranges written as text near the line * Examples: * `1..1` (exactly one) * `0..1` (zero or one) * `0..*` (zero or many) * `1..*` (one or many) ---- ### ERD Notation vs level of detail | ERD Level | Best Notation | Why / When to use | | :-------- | :------------ | :---------------- | | Conceptual | Common ERD | Clear for stakeholders, shows entitites & relations without technical details | | Logical | IDEF1X + e.g. Crows Feet | Captures attributes, keys, and cardinalities. Crows = readable; IDEF1X = precise | | Physical | IDEF1X | Full enforcement of PKs, FKs, indexes, constraints. Matches DBMS implementation | --- ## Normalization --- ## 1NF (First Normal Form) ---- ### Hvad er 1NF? * 1NF er den første normalform i databasedesign. * Målet er at sikre atomiske værdier i tabeller * Ingen gentagne grupper eller multi-værdi felter * 1NF er grundlaget for de andre normalformer. ---- ### Krav for 1NF * Alle attributter skal være atomiske (ikke delelige) * Ingen gentagne kolonner (e.g. farve1, farve2) * Ingen multiværdier i samme celle * Alle rækker skal være unikke ---- ### Eksempel på overtrædelse af 1NF **Customers** | customerId | name | phones | | :--------- | :--- | :----- | | 1 | Mika | 12345678, 87654321 | | 2 | Anna | 23456789 | | 3 | Lars | 34567890, 09876543 | **Problemet:** feltet `phones` indeholder flere værdier ---- ### Løsning for 1NF
**Customer** | customerId | name | | :--------- | :--- | | 1 | Mika | | 2 | Anna | | 3 | Lars |
**CustomerPhones** | customerId | phone | | :--------- | :------- | | 1 | 12345678 | | 1 | 87654321 | | 2 | 23456789 | | 3 | 34567890 | | 3 | 09876543 |
- Telefonnumre er flyttet til en ny tabel - Relation via `customerId` ---- ### Opsummering af 1NF - 1NF sikrer ... - atomiske værdier - ingen gentagne kolonner - ingen multiværdier i samme felt - Løsningen er typisk flere tabeller ---- ## 1NF Opgaver [https://ucl.kjc.dk/dfu/dfu-02-exercises-1nf.html](/dfu/dfu-02-exercises-1nf.html) --- ## 2NF (Second Normal Form) ---- ### Hvad er 2NF? - 2NF fjerner **partielle funktionelle afhængigheder** - En ikke-nøgle-attribut må **ikke** være afhængig af **en del** af en sammensat primærnøgle - Hvisprimærnøglen er **enkel (èn kolonne)**, er tabellen i 2NF, så snart den er i 1NF ---- ### Terminologi (kort) - **Sammesat nøgle** = primærnøgle med flere kolonner - **Ikke-nøgle-attribut** = kolonne, der ikke er del af primærnøglen - **Partial funktionel afhængighed** = når en ikke-nøgle-attribut er afhængig af kun en del af en sammensat nøgle ---- ### Krav for 2NF - Tabellen skal være i 1NF - Tabellen skal have en sammensat primærnøgle - Ingen ikke-nøgle-attributter må være afhængige af kun en del af den sammensatte nøgle ---- ### Eksempel på overtrædelse af 2NF **OrderLines** | orderId | productId | productName | unitPrice | quantity | | :------ | :-------- | :---------- | :-------- | :------- | | 1 | 101 | Widget A | 9.99 | 2 | | 1 | 102 | Widget B | 19.99 | 1 | | 2 | 101 | Widget A | 9.99 | 1 | - PK: **(orderId, productId)** - `productName` og `unitPrice` afhænger kun af `productId`, ikke hele nøglen `(orderId, productId)` => **partial afhængighed** ---- ### Løsning for 2NF
**Products** | productId | productName | unitPrice | | :-------- | :---------- | :-------- | | 101 | Widget A | 9.99 | | 102 | Widget B | 19.99 |
**OrderLines** | orderId | productId | quantity | | :------ | :-------- | :------- | | 1 | 101 | 2 | | 1 | 102 | 1 | | 2 | 101 | 1 |
- Nu afhænger alle ikke-nøgle-attributter i **OrderLines** af hele den sammensatte nøgle (`orderId`, `productId`) - Produkternes beskrivende felter er flyttet til en separat **Products** tabel ---- ### Tommelfingerregler til 2NF - Har tabellen en **sammensat nøgle**? Tjek for partielle afhængigheder - Alt der **kun** afhænger af en **del** af nøglen, skal i en **egen tabel** - Har tabellen en **enkel nøgle**? 1NF => 2NF automatisk (partielle afhængigheder kan ikke opstå) ---- ### Opsummering af 2NF - Forudsætter **1NF** - 2NF: ignen **partielle** funktionelle afhængigheder - Relevans især ved **sammensat primærnøgle**; ved **enkel nøgle** gælder: 1NF => 2NF - Gevinst: mindre redundans og færre **opdaterings-/indsætnings-/sletningsanomalier** ---- ## 2NF Opgaver [https://ucl.kjc.dk/dfu/dfu-02-exercises-2nf.html](/dfu/dfu-02-exercises-2nf.html) --- ## 3NF (Third Normal Form) ---- ### Hvad er 3NF? - 3NF forudsætter at tabellen er i 2NF - 3NF fjerner **transitive funktionelle afhængigheder** - En ikke-nøgle-attribut må **ikke** være afhængig af en anden ikke-nøgle-attribut ---- ### Terminologi (kort) - **Transitiv funktionel afhængighed** = når en ikke-nøgle-attribut er afhængig af en anden ikke-nøgle-attribut - **Ikke-nøgle-attribut** = kolonne, der ikke er del af primærnøglen - **Funktionel afhængighed** = når værdien af én kolonne bestemmer værdien af en anden kolonne - **Primærnøgle** = kolonne(r) der unikt identificerer en række ---- ### Krav for 3NF - Tabellen skal være i 2NF - Ingen ikke-nøgle-attributter må være afhængige af andre ikke-nøgle-attributter - Alle ikke-nøgle-attributter skal være direkte afhængige af hele primærnøglen ---- ### Eksempel på overtrædelse af 3NF **Orders** | orderId (pk) | customerId | customerName | customerCity | | :----------- | :--------- | :----------- | :----------- | | 5001 | C10 | Mika | Copenhagen | | 5002 | C20 | Anna | Aarhus | - FDs (functional dependencies): `orderId -> customerId`, og `customerId -> customerName, customerCity` - Derfor: **orderId -> customerCity** (transitivt via customerId) -> brud på 3NF ---- ### Løsning for 3NF
**Customers** | customerId (pk) | customerName | customerCity | | :-------------- | :----------- | :----------- | | C10 | Mika | Copenhagen | | C20 | Anna | Aarhus |
**Orders** | orderId (pk) | customerId (fk) | | :----------- | :-------------- | | 5001 | C10 | | 5002 | C20 |
- Nu bestemmer **customerId** kundedata i **Customers**, og **Orders** refererer kun med FK - Transitiv afhængighed elimineret ---- ### Sådan opdager du 3NF-brud (i praksis) - Find **kandidatnøgler** og liste over forretnings FD's (funktionelle afhængigheder) - Alt, der beskriver en **anden entitet**, skal højst sandsynligt i **egen table** ---- ### Opsummering af 3NF - Forudsætter **2NF** - 3NF: ingen **transitive** funktionelle afhængigheder - Gevinst: mindre redundans, færre **opdaterings-/indsætnings-/sletningsanomalier** - Ofte den ønskede normalform i praksis ---- ## 3NF vs BCNF ### Hvad er forskellen (helt enkelt) ---- ### Først: hvad vil vi? - Minimere redundans og anamolier - Holde tabellerne nemme at validere med nøgler og FD's - Balancere **teori** (BCNF strammere) og **praktik** (3NF bevarer ofte regler) ---- ### BCNF (Boyce-Codd Normal Form) - **3NF** For hver FD `X -> A` gælder: - enten er **X** en (super) **nøgle** - eller **A** er **primary attribute** (en del af en kandidatnøgler) - **BCNF** For hver FD `X -> A` skal **X** være en (super nøgle) ingen undtagelser ---- ### Oversat - 3NF tillader èn undtagelse (hvis højresiden er "key-attribut") - BCNF tillader **ingen** undtagelser ---- ### Eksempel **Registrations** | studentId (pk) | courseId (pk) | instructor | | :------------- | :------------ | :--------- | | 1 | 101 | Dr. Smith | | 2 | 102 | Dr. Jones | | 1 | 103 | Dr. Smith | - FDs: `studentId, courseId -> instructor` og `instructor -> courseId` ---- ## Løsning
**Registrations** | studentId (pk) | courseId (pk) | | :------------- | :------------ | | 1 | 101 | | 2 | 102 | | 1 | 103 |
**Courses** | courseId (pk) | instructor | | :------------ | :--------- | | 101 | Dr. Smith | | 102 | Dr. Jones | | 103 | Dr. Smith |
- Nu er alle FD's i begge tabeller baseret på nøgler => både 3NF og BCNF - Hvis vi havde en FD `instructor -> studentId`, ville det være i 3NF (fordi `studentId` er en key attribut), ---- ## Opsummering af 3NF vs BCNF - **3NF** tillader undtagelser hvis højresiden er en key-attribut - **BCNF** kræver at alle FD's er baseret på nøgler - BCNF er en strengere form end 3NF - I praksis er 3NF ofte tilstrækkeligt og mere fleksibelt ---- ### 3NF Opgaver [https://ucl.kjc.dk/dfu/dfu-02-exercises-3nf.html](/dfu/dfu-02-exercises-3nf.html) --- ## Opgave ### Pizzageddon [https://ucl.kjc.dk/dfu/dfu-exercises-pizzageddon.html](/dfu/dfu-exercise-pizzageddon.html)