Dnes navrhneš dátový model svojej aplikácie: zoznam tabuliek a vzťahov, z ktorých bude v ďalších týždňoch vznikať kód. Je to prvé zadanie (cv01). Pojmy k dátovému modelu sú v tabuľke pojmov v 1. týždni.
Today you design the data model of your application: the list of tables and relationships from which the code will grow in the following weeks. It is the first assignment (cv01). The data model terms are in the table of terms in week 1.
TeóriaTheory
Čo je dátový model
Dátový model je zoznam tabuliek databázy a vzťahov medzi nimi. Navrhuje sa skôr, než sa napíše prvý riadok kódu, lebo kód sa od tabuliek odvíja: každá tabuľka dostane svoju triedu (model), každý vzťah svoje metódy. Zle navrhnutá tabuľka sa v ôsmom týždni opravuje ťažko, dnes je to jedna veta v README.
V tomto predmete pracujeme s tromi druhmi tabuliek:
Hlavná entita (main entity) je tabuľka, okolo ktorej sa aplikácia točí. Má veľa stĺpcov, používatelia do nej pridávajú záznamy, upravujú ich a mažú. Vo vzore sú to recepty. V požičovni náradia by to boli výpožičky, v knižnici knihy, v evidencii zápasov zápasy.
Číselník (lookup table) je malá tabuľka s pevným zoznamom hodnôt, z ktorých si používateľ vyberá: kategórie, jednotky, obtiažnosti, typy. Má zvyčajne len id a name. Číselníky spravuje administrátor, bežný používateľ z nich len vyberá v rozbaľovacom zozname.
Prepojka (pivot table, junction table) spája dve tabuľky, keď jeden záznam môže patriť k viacerým záznamom druhej tabuľky a naopak. Recept má viac ingrediencií, ingrediencia je vo viacerých receptoch. Prepojka drží dvojice id, prípadne aj vlastné údaje o tej dvojici (množstvo, dátum, poznámku).
Kľúče a vzťahy
Každá tabuľka má primárny kľúč (primary key), stĺpec id, ktorý jednoznačne určuje záznam. Databáza ho prideľuje sama (AUTO_INCREMENT).
Cudzí kľúč (foreign key) je stĺpec, ktorý obsahuje id záznamu z inej tabuľky. Stĺpec difficulty_id v tabuľke recipes obsahuje id z tabuľky difficulties. Databáza stráži, že tam nemôže byť číslo, ktoré v druhej tabuľke neexistuje.
Podľa toho, ako sú tabuľky prepojené, rozlišujeme dva druhy vzťahov:
Vzťah 1:N (one-to-many): jeden záznam prvej tabuľky patrí k mnohým záznamom druhej. Jedna obtiažnosť má mnoho receptov, každý recept má práve jednu obtiažnosť. Rieši sa cudzím kľúčom priamo v tabuľke na strane N: recipes.difficulty_id.
Vzťah M:N (many-to-many): mnoho k mnohým na obidve strany. Recept má viac kategórií, kategória má viac receptov. Do žiadnej z dvoch tabuliek sa to nezmestí, preto vzniká prepojka recipe_categories s dvomi cudzími kľúčmi.
Čo sa stane pri mazaní
Pri každom cudzom kľúči databáza potrebuje vedieť, čo urobiť, keď sa zmaže záznam, na ktorý kľúč odkazuje. Určuje to pravidlo ON DELETE:
RESTRICT: mazanie sa odmietne. Obtiažnosť sa nedá zmazať, kým ju používa nejaký recept. Toto je predvolené správanie a je správne pre číselníky.CASCADE: závislé záznamy sa zmažú spolu s ním. Keď sa zmaže recept, zmažú sa aj jeho riadky v prepojkách, lebo prepojenie bez receptu nemá zmysel.SET NULL: cudzí kľúč sa nastaví naNULL. Záznam ostane, len stratí väzbu. Používa sa pri voliteľných väzbách.
Pri návrhu modelu ku každému cudziemu kľúču napíš, ktoré pravidlo platí a prečo. Pri obhajobe sa na to budeme pýtať.
Tvar tvojho projektu
Tvoj dátový model musí mať rovnaký tvar ako vzor, aby si každý týždeň vedel prenášať postup zo vzoru do svojho projektu:
- jedna hlavná entita,
- tri až štyri číselníky, z toho aspoň jeden pripojený na hlavnú entitu priamo (vzťah 1:N cez cudzí kľúč) a aspoň jeden cez prepojku (vzťah M:N),
- dve prepojky, z toho aspoň jedna s vlastným atribútom (množstvo, dátum, počet, poznámka).
Tabuľka používateľov pribudne v 7. týždni, teraz ju nenavrhuj. Téma nesmie byť recepty ani jedlo. Príklady tém, ktoré tvar spĺňajú: požičovňa náradia (výpožička × náradie s dátumom vrátenia), evidencia zápasov (zápas × hráč s počtom gólov), knižnica (výpožička × kniha s termínom), tréningový plán (tréning × cvik s počtom opakovaní), servis áut (zákazka × úkon s cenou), zbierka hier (hra × žáner, hra × platforma s rokom vydania).
What a data model is
A data model is the list of database tables and the relationships between them. It is designed before the first line of code is written, because the code follows the tables: every table gets its own class (a model), every relationship its own methods. A badly designed table is hard to fix in week eight; today it is one sentence in the README.
In this course we work with three kinds of tables:
The main entity is the table the application revolves around. It has many columns; users add, edit and delete its records. In the sample it is recipes. In a tool rental it would be loans, in a library books, in a match record matches.
A lookup table is a small table with a fixed list of values the user chooses from: categories, units, difficulties, types. It usually has only id and name. Lookup tables are managed by an administrator; a regular user only picks from them in a drop-down list.
A pivot table (junction table) connects two tables when one record can belong to several records of the other table and vice versa. A recipe has several ingredients; an ingredient is in several recipes. The pivot table holds pairs of ids and possibly its own data about the pair (amount, date, note).
Keys and relationships
Every table has a primary key, the column id, which identifies a record uniquely. The database assigns it itself (AUTO_INCREMENT).
A foreign key is a column containing the id of a record from another table. The column difficulty_id in the table recipes contains an id from the table difficulties. The database makes sure it can never hold a number that does not exist in the other table.
Depending on how tables are connected, we distinguish two kinds of relationships:
One-to-many (1:N): one record of the first table belongs to many records of the second. One difficulty has many recipes; each recipe has exactly one difficulty. It is solved by a foreign key directly in the table on the N side: recipes.difficulty_id.
Many-to-many (M:N): many to many on both sides. A recipe has several categories; a category has several recipes. This does not fit into either of the two tables, so a pivot table recipe_categories with two foreign keys is created.
What happens on delete
For every foreign key the database needs to know what to do when the record it points to is deleted. The ON DELETE rule decides:
RESTRICT: the delete is refused. A difficulty cannot be deleted while any recipe uses it. This is the default behaviour and it is right for lookup tables.CASCADE: dependent records are deleted together with it. When a recipe is deleted, its rows in the pivot tables go too, because a link without a recipe makes no sense.SET NULL: the foreign key is set toNULL. The record stays, it only loses the link. Used for optional links.
When designing the model, write for every foreign key which rule applies and why. We will ask about it at the defence.
The shape of your project
Your data model must have the same shape as the sample, so that every week you can transfer the procedure from the sample to your project:
- one main entity,
- three to four lookup tables, at least one of them connected to the main entity directly (a 1:N relationship through a foreign key) and at least one through a pivot table (an M:N relationship),
- two pivot tables, at least one of them with its own attribute (amount, date, count, note).
The users table is added in week 7; do not design it now. The topic must not be recipes or food. Examples of topics that fit the shape: a tool rental (loan × tool with a return date), a match record (match × player with goals scored), a library (loan × book with a due date), a training plan (workout × exercise with repetitions), a car service (job × operation with a price), a game collection (game × genre, game × platform with a release year).
UkážkyExamples
Ukážka 1: dátový model vzorového projektu
Vzorový projekt sú recepty. Takto vyzerá jeho dátový model, presne v tvare, ktorý má mať aj tvoj projekt. Vzťah 1:N je raz, vzťah M:N bez atribútu raz, vzťah M:N s atribútom raz.
Ten istý model zapísaný ako text:
recipes hlavná entita
id, title, servings, prep_time, instructions, created_at
difficulty_id → difficulties.id 1:N, ON DELETE RESTRICT
difficulties číselník, pripojený priamo (1:N)
id, name
categories číselník, pripojený cez prepojku (M:N)
id, name
ingredients číselník, pripojený cez prepojku s atribútmi
id, name
units číselník, použitý ako atribút prepojky
id, name, abbreviation
recipe_categories prepojka bez atribútov
recipe_id → recipes.id ON DELETE CASCADE
category_id → categories.id ON DELETE RESTRICT
recipe_ingredients prepojka s atribútmi
recipe_id → recipes.id ON DELETE CASCADE
ingredient_id → ingredients.id ON DELETE RESTRICT
amount, note
unit_id → units.id ON DELETE RESTRICT
Prečo práve tieto pravidlá: recept sa smie zmazať kedykoľvek a jeho riadky v prepojkách idú s ním (CASCADE). Kategória, ingrediencia ani jednotka sa nedajú zmazať, kým ich používa nejaký recept (RESTRICT), inak by v receptoch ostali odkazy na neexistujúce hodnoty.
V README.md na GitHube sa diagram kreslí zápisom Mermaid (erDiagram). GitHub ho zobrazí ako obrázok, v editore je to obyčajný text. Takto vyzerá model receptov v Mermaid; presne takýto blok bude mať aj tvoj README pre tvoju tému:
erDiagram
recipes ||--o{ recipe_categories : ""
categories ||--o{ recipe_categories : ""
recipes ||--o{ recipe_ingredients : ""
ingredients ||--o{ recipe_ingredients : ""
units ||--o{ recipe_ingredients : ""
difficulties ||--o{ recipes : ""
recipes {
int id PK
string title
int servings
int prep_time
text instructions
datetime created_at
int difficulty_id FK
}
difficulties { int id PK string name }
categories { int id PK string name }
ingredients { int id PK string name }
units { int id PK string name string abbreviation }
recipe_categories { int recipe_id PK,FK int category_id PK,FK }
recipe_ingredients { int recipe_id PK,FK int ingredient_id PK,FK decimal amount string note int unit_id FK }
Ukážka 2: prompt pre AI na návrh dátového modelu
Model si necháš navrhnúť od AI, ale zadanie musíš napísať tak, aby výsledok mal predpísaný tvar. Prompt preto vymenúva presne, čo má model obsahovať a v akej forme má byť odpoveď. Nežiadame SQL, to je téma budúceho týždňa; dnes chceme zoznam tabuliek so stĺpcami a vysvetlenie vzťahov, ktorému rozumieš a vieš ho obhájiť.
Navrhni dátový model relačnej databázy (MariaDB) pre webovú aplikáciu na tému: [DOPLŇ TÉMU].
Model musí mať presne tento tvar:
- jedna hlavná entita, do ktorej používateľ pridáva, upravuje a maže záznamy,
- tri až štyri číselníky (malé tabuľky s pevným zoznamom hodnôt, stĺpce id a name),
z toho aspoň jeden pripojený na hlavnú entitu priamo cudzím kľúčom (vzťah 1:N)
a aspoň jeden pripojený cez prepojku (vzťah M:N),
- dve prepojky (pivot tabuľky), z toho aspoň jedna s vlastným atribútom
(napríklad množstvo, dátum, počet alebo poznámka).
Tabuľku používateľov zatiaľ nenavrhuj.
Ku každej tabuľke napíš: názov v angličtine v množnom čísle (napr. tools, loans),
zoznam stĺpcov s dátovým typom a stručným popisom po slovensky,
primárny kľúč a cudzie kľúče.
Ku každému cudziemu kľúču napíš pravidlo ON DELETE (RESTRICT, CASCADE alebo SET NULL)
a jednou vetou zdôvodni, prečo práve toto.
Odpoveď napíš ako Markdown: pre každú tabuľku nadpis a tabuľku stĺpcov,
potom zoznam vzťahov (ktorá tabuľka, s ktorou, aký typ vzťahu)
a na koniec ER diagram v zápise Mermaid (blok ```mermaid s erDiagram),
v ktorom sú všetky tabuľky so stĺpcami a všetky vzťahy.
Nepíš SQL ani PHP, len návrh.
Prečo je prompt napísaný takto: tvar modelu je vymenovaný bod po bode, aby AI nemohla vynechať prepojku s atribútom ani dať všetky číselníky cez cudzí kľúč. Názvy tabuliek žiadame v angličtine v množnom čísle, lebo tak sa budú volať aj triedy v kóde. Zdôvodnenie ON DELETE žiadame preto, že ho budeš vysvetľovať pri obhajobe. Výstup je Markdown, aby sa dal vložiť priamo do README.md, a Mermaid diagram na konci žiadame preto, že GitHub ho v README zobrazí ako obrázok – uvidíš svoj model nakreslený bez ďalšieho nástroja.
Example 1: the data model of the sample project
The sample project is recipes. This is its data model, in exactly the shape your project should have. A 1:N relationship once, an M:N relationship without attributes once, an M:N relationship with attributes once.
The same model written as text:
recipes main entity
id, title, servings, prep_time, instructions, created_at
difficulty_id → difficulties.id 1:N, ON DELETE RESTRICT
difficulties lookup table, connected directly (1:N)
id, name
categories lookup table, connected through a pivot (M:N)
id, name
ingredients lookup table, connected through a pivot with attributes
id, name
units lookup table, used as a pivot attribute
id, name, abbreviation
recipe_categories pivot table without attributes
recipe_id → recipes.id ON DELETE CASCADE
category_id → categories.id ON DELETE RESTRICT
recipe_ingredients pivot table with attributes
recipe_id → recipes.id ON DELETE CASCADE
ingredient_id → ingredients.id ON DELETE RESTRICT
amount, note
unit_id → units.id ON DELETE RESTRICT
Why these rules: a recipe may be deleted at any time and its rows in the pivot tables go with it (CASCADE). A category, an ingredient or a unit cannot be deleted while any recipe uses it (RESTRICT); otherwise recipes would keep references to values that no longer exist.
In README.md on GitHub the diagram is drawn with the Mermaid notation (erDiagram). GitHub renders it as a picture; in the editor it is plain text. This is the recipes model in Mermaid; your README will have exactly such a block for your topic:
erDiagram
recipes ||--o{ recipe_categories : ""
categories ||--o{ recipe_categories : ""
recipes ||--o{ recipe_ingredients : ""
ingredients ||--o{ recipe_ingredients : ""
units ||--o{ recipe_ingredients : ""
difficulties ||--o{ recipes : ""
recipes {
int id PK
string title
int servings
int prep_time
text instructions
datetime created_at
int difficulty_id FK
}
difficulties { int id PK string name }
categories { int id PK string name }
ingredients { int id PK string name }
units { int id PK string name string abbreviation }
recipe_categories { int recipe_id PK,FK int category_id PK,FK }
recipe_ingredients { int recipe_id PK,FK int ingredient_id PK,FK decimal amount string note int unit_id FK }
Example 2: an AI prompt for designing the data model
You let the AI design the model, but you must write the request so that the result has the required shape. The prompt therefore lists exactly what the model must contain and in what form the answer should be. We do not ask for SQL, that is next week’s topic; today we want a list of tables with columns and an explanation of relationships that you understand and can defend.
Design a relational database data model (MariaDB) for a web application on the topic: [FILL IN THE TOPIC].
The model must have exactly this shape:
- one main entity into which the user adds, edits and deletes records,
- three to four lookup tables (small tables with a fixed list of values, columns id and name),
at least one of them connected to the main entity directly by a foreign key (1:N relationship)
and at least one connected through a pivot table (M:N relationship),
- two pivot tables, at least one of them with its own attribute
(for example amount, date, count or note).
Do not design a users table yet.
For every table write: the name in English in plural (e.g. tools, loans),
the list of columns with data type and a short description,
the primary key and the foreign keys.
For every foreign key write the ON DELETE rule (RESTRICT, CASCADE or SET NULL)
and justify in one sentence why this one.
Write the answer as Markdown: a heading and a column table for each table,
then a list of relationships (which table, with which, what type)
and at the end an ER diagram in Mermaid notation (a ```mermaid block with erDiagram)
containing all tables with their columns and all relationships.
Do not write SQL or PHP, only the design.
Why the prompt is written this way: the shape of the model is listed point by point so that the AI cannot leave out the pivot table with an attribute or connect all lookup tables through foreign keys. We ask for table names in English in plural because that is what the classes in the code will be called. We ask for the ON DELETE justification because you will explain it at the defence. The output is Markdown so that it can be pasted directly into README.md, and we ask for the Mermaid diagram at the end because GitHub renders it in the README as a picture – you will see your model drawn without any extra tool.
Úlohy na cvičenieLab tasks
Úlohy dostaneš aj ako zadanie cv01 v Classroom 50, sú v súbore README.md v tvojom repository.
Link na zadanie cv01: prijať zadanie (platí pre skupiny B. Stehlíkovej; ostatné skupiny dostanú link od svojho cvičiaceho)
Úloha 2.1: Kubeflow: príprava. Podľa návodu 04 Odovzdávanie, časť 1: otvor Kubeflow, skontroluj, že v Explorer je hore WEB, a skontroluj rozšírenia. Ak dole na stavovej lište nie je Go Live, rozšírenia sa po reštarte stratili. Vráti ich tento príkaz v termináli (jeden riadok):
code-server --install-extension Natizyskunk.sftp --install-extension yandeu.five-server --install-extension bmewburn.vscode-intelephense-client --install-extension mblode.twig-language-2
Potom F1, napíš reload, Developer: Reload Window. Nastavenie pripojenia na sigma.tuke.sk zostáva.
Úloha 2.2: Zadanie cv01. Prijmi zadanie cv01 v Classroom 50 (link je vyššie) a repository naklonuj do ~/web/it/cv01 podľa návodu 04 Odovzdávanie, časti 2 a 3. Do súboru index.php napíš jeden riadok PHP, ktorý vypíše tvoje meno a tému projektu. Ulož; uloženie v editore ide na sigma.tuke.sk samo. Otvor https://sigma.tuke.sk/student/meno.priezvisko/it/cv01/.
Úloha 2.3: Téma projektu. Vyber si tému svojej aplikácie. Nesmú to byť recepty ani jedlo. Téma musí umožniť tvar z teórie: jedna hlavná entita, tri až štyri číselníky, dve prepojky. Ak si nie si istý, opýtaj sa hneď; zmena témy o niekoľko týždňov znamená začať odznova.
Úloha 2.4: Dátový model cez AI. Prompt z Ukážky 2 vlož do AI a doplň svoju tému. Výsledok skontroluj podľa pravidiel tvaru: má hlavnú entitu? tri až štyri číselníky? aspoň jeden vzťah 1:N a aspoň jeden M:N? prepojku s atribútom? Čo nesedí, nechaj AI opraviť. Prečítaj každé zdôvodnenie ON DELETE, musíš ho vedieť povedať vlastnými slovami. Hotový model vlož do README.md v repository cv01 pod nadpis so svojou témou.
Úloha 2.5: Odovzdanie. Commit a push podľa návodu 04 Odovzdávanie, časť 5. Na GitHub skontroluj, že README.md obsahuje tému a dátový model a že sa Mermaid diagram zobrazí ako obrázok. Ak sa nezobrazí, blok má chybu, nechaj ju AI opraviť.
Úloha 2.6: Kontrola na sigma.tuke.sk. Podľa návodu 04 Odovzdávanie, časť 7: pravý klik na priečinok cv01, Upload Folder, potom otvor https://sigma.tuke.sk/student/meno.priezvisko/it/cv01/.
Hodnotenie: 1 bod. README.md s témou a dátovým modelom (vrátane Mermaid diagramu) v repository cv01 a index.php v tvojom webovom priestore na sigma.tuke.sk. V 3. týždni z modelu vytvoríš tabuľky a modely.
You also get the tasks as the assignment cv01 in Classroom 50; they are in the file README.md in your repository.
Link to the assignment cv01: accept the assignment (applies to B. Stehlíková’s groups; other groups get the link from their own lab teacher)
Task 2.1: Kubeflow: getting ready. Following guide 04 Submitting, part 1: open Kubeflow, check that Explorer shows WEB at the top, and check the extensions. If the status bar at the bottom does not show Go Live, the extensions were lost on restart. This command in the terminal (one line) brings them back:
code-server --install-extension Natizyskunk.sftp --install-extension yandeu.five-server --install-extension bmewburn.vscode-intelephense-client --install-extension mblode.twig-language-2
Then F1, type reload, Developer: Reload Window. The connection settings to sigma.tuke.sk stay.
Task 2.2: Assignment cv01. Accept the assignment cv01 in Classroom 50 (link above) and clone the repository into ~/web/it/cv01 following guide 04 Submitting, parts 2 and 3. In the file index.php write one line of PHP that prints your name and the topic of your project. Save; a save in the editor goes to sigma.tuke.sk by itself. Open https://sigma.tuke.sk/student/name.surname/it/cv01/.
Task 2.3: Project topic. Choose the topic of your application. It must not be recipes or food. The topic must allow the shape from the theory: one main entity, three to four lookup tables, two pivot tables. If you are not sure, ask right away; changing the topic a few weeks later means starting over.
Task 2.4: Data model with AI. Paste the prompt from Example 2 into an AI and fill in your topic. Check the result against the shape rules: does it have a main entity? three to four lookup tables? at least one 1:N and at least one M:N relationship? a pivot table with an attribute? Let the AI fix whatever does not fit. Read every ON DELETE justification; you must be able to say it in your own words. Put the finished model into README.md in the cv01 repository under a heading with your topic.
Task 2.5: Submitting. Commit and push following guide 04 Submitting, part 5. On GitHub check that README.md contains the topic and the data model and that the Mermaid diagram is rendered as a picture. If it is not, the block has an error; let the AI fix it.
Task 2.6: Check on sigma.tuke.sk. Following guide 04 Submitting, part 7: right-click the cv01 folder, Upload Folder, then open https://sigma.tuke.sk/student/name.surname/it/cv01/.
Grading: 1 point. README.md with the topic and the data model (including the Mermaid diagram) in the cv01 repository and index.php in your web space on sigma.tuke.sk. In week 3 you create the tables and models from the model.