Informačné technológieInformation Technologies / Týždeň 2Week 2

Dátový modelThe data model

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í na NULL. 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 to NULL. 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.

1 : NRESTRICT1 : NCASCADE1 : NRESTRICT1 : NCASCADE1 : NRESTRICT1 : NRESTRICTdifficultiesPK idnamečíselníkcategoriesPK idnamečíselníkrecipesPK idtitleservingsprep_timeinstructionscreated_atFK difficulty_idhlavná entitarecipe_categoriesPK,FK recipe_idPK,FK category_idprepojkaingredientsPK idnamečíselníkrecipe_ingredientsPK,FK recipe_idPK,FK ingredient_idamountnoteFK unit_idprepojka s atribútmiunitsPK idnameabbreviationčíselník● strana 1 vzťahu · pri čiare je typ vzťahu a pravidlo ON DELETE

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.

1 : NRESTRICT1 : NCASCADE1 : NRESTRICT1 : NCASCADE1 : NRESTRICT1 : NRESTRICTdifficultiesPK idnamelookup tablecategoriesPK idnamelookup tablerecipesPK idtitleservingsprep_timeinstructionscreated_atFK difficulty_idmain entityrecipe_categoriesPK,FK recipe_idPK,FK category_idpivot tableingredientsPK idnamelookup tablerecipe_ingredientsPK,FK recipe_idPK,FK ingredient_idamountnoteFK unit_idpivot table with attributesunitsPK idnameabbreviationlookup table● the 1 side of a relationship · on the line: relationship type and ON DELETE rule

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.