29 | | || reservation_id || user_id || table_id || reservation_date || check_in_from || check_in_to || number_of_people || restaurant_id || |
30 | | || 1 || 101 || 11 || 2025-05-01 || 18:00 || 20:00 || 4 ||201 || |
31 | | || 2 || 102 || 12 || 2025-05-02 || 19:30 || 21:00 || 2 ||202 || |
32 | | || 3 || 103 || 13 || 2025-05-03 || 17:00 || 18:30 || 3 ||203 || |
33 | | |
34 | | Во оваа релација, restaurant_id се повторува иако е функционски зависен од table_id, бидејќи секоја маса припаѓа на еден ресторан. |
35 | | |
36 | | ---- |
37 | | |
38 | | '''Функциски зависности:''' |
39 | | * reservation_id → user_id, table_id, restaurant_id, date, time, duration |
40 | | |
41 | | * table_id → restaurant_id |
42 | | |
43 | | '''Анализа на зависности:''' |
44 | | Само лево (детерминанти): |
45 | | * reservation_id |
46 | | |
47 | | * table_id |
48 | | |
49 | | Само десно (зависни атрибути): |
50 | | * restaurant_id, user_id, date, time, duration |
51 | | |
52 | | ---- |
53 | | |
54 | | Канонична покривка: |
55 | | Од reservation_id може да се добијат сите атрибути, затоа е кандидат клуч. |
56 | | |
57 | | ---- |
58 | | |
59 | | '''Анализа на нормализација:''' |
60 | | |
61 | | Прва нормална форма (1НФ): |
62 | | |
63 | | Сите атрибути се атомски, нема листи или вложени структури. '''Задоволена.''' |
64 | | |
65 | | Втора нормална форма (2НФ): |
66 | | |
67 | | Клучот е едноставен (reservation_id), па нема парцијални зависности. '''Задоволена.''' |
68 | | |
69 | | Трета нормална форма (3НФ): |
70 | | |
71 | | Се појавува транзитивна зависност: |
72 | | |
73 | | reservation_id → table_id → restaurant_id |
74 | | |
75 | | Значи, restaurant_id е транзитивно зависен од примарниот клуч (reservation_id), и '''релацијата не е во 3НФ.''' |
76 | | |
77 | | ----Декомпозиција: |
78 | | R1: Reservation (без дупликација на restaurant_id) |
79 | | |
80 | | * R1(reservation_id, user_id, table_id, date, time, duration) |
81 | | |
82 | | R2: Table (со поврзаност со ресторан) |
83 | | |
84 | | * R2(table_id, restaurant_id) |
85 | | |
86 | | ---- |
87 | | |
88 | | '''Финална анализа''' |
89 | | * Нема дуплицирање. |
90 | | |
91 | | * restaurant_id може да се добие преку JOIN со Table. |
92 | | |
93 | | === 3. Резервации со корисници и маси |
| 61 | |
| 62 | '''Кандидат клуч:''' reservation_id |
| 63 | |
| 64 | '''Нормализација:''' |
| 65 | |
| 66 | ''' 1НФ – Прва нормална форма:''' |
| 67 | Сите атрибути се атомски. |
| 68 | |
| 69 | '''2НФ – Втора нормална форма:''' |
| 70 | Клучот reservation_id е едноставен, па нема парцијални зависности. |
| 71 | |
| 72 | '''3НФ – Трета нормална форма:''' |
| 73 | Имаме транзитивни зависности: |
| 74 | |
| 75 | * reservation_id → table_id → restaurant_id → restaurant_name, restaurant_location |
| 76 | |
| 77 | * reservation_id → user_id → user_name |
| 78 | |
| 79 | Значи, атрибути зависат од не-примарен атрибут што зависи од клучот. Не е во 3НФ. |
| 80 | |
| 81 | '''BCNF:''' |
| 82 | Не е во BCNF бидејќи постојат функционски зависности каде детерминантата не е суперклуч. |
| 83 | |
| 84 | * user_id → user_name |
| 85 | |
| 86 | * table_id → restaurant_id |
| 87 | |
| 88 | '''Декомпозицијa''' |
| 89 | |
| 90 | '''R1:Reservation''' |
| 91 | |
| 92 | { reservation_id, reservation_date, time_from, time_to, number_of_people, user_id, table_id } |
| 93 | |
| 94 | (во BCNF – клуч reservation_id) |
| 95 | |
| 96 | '''R2:User''' |
| 97 | |
| 98 | { user_id, user_name } |
| 99 | |
| 100 | (во BCNF – клуч user_id) |
| 101 | |
| 102 | '''R3: Table''' |
| 103 | |
| 104 | { table_id, table_number, restaurant_id } |
| 105 | |
| 106 | (во BCNF - клуч table_id) |
| 107 | |
| 108 | '''R4: Restaurant''' |
| 109 | |
| 110 | { restaurant_id, restaurant_name, restaurant_location } |
| 111 | |
| 112 | (во BCNF – клуч restaurant_id) |
| 113 | |
| 114 | === 3. Маси и ресторани |
| 115 | ||table_id ||table_number ||restaurant_id ||restaurant_name ||restaurant_location|| |
| 116 | ||11 ||1 ||201 ||Gino’s ||Skopje, Centar|| |
| 117 | ||12 ||2 ||202 ||Sushico ||Skopje, Karposh|| |
| 118 | ||13 ||3 ||203 ||Bella Italia ||Skopje, Aerodrom|| |
| 119 | |
| 120 | '''R'''= { table_id, table_number, restaurant_id, restaurant_name, restaurant_location } |
| 121 | |
| 122 | '''Функциски зависности:''' |
| 123 | |
| 124 | * table_id → table_number, restaurant_id |
| 125 | |
| 126 | * restaurant_id → restaurant_name, restaurant_location |
| 127 | |
| 128 | '''Лево:''' |
| 129 | |
| 130 | table_id, restaurant_id |
| 131 | |
| 132 | '''Само десно (зависни атрибути):''' |
| 133 | |
| 134 | table_number, restaurant_name, restaurant_location |
| 135 | |
| 136 | '''Кандидат клуч:''' |
| 137 | table_id |
| 138 | |
| 139 | '''Нормализација:''' |
| 140 | |
| 141 | '''1НФ – Прва нормална форма:'''Сите атрибути се атомски. |
| 142 | |
| 143 | '''2НФ – Втора нормална форма: '''Клучот table_id е едноставен, па нема парцијални зависности. |
| 144 | |
| 145 | '''3НФ – Трета нормална форма: '''Имаме транзитивни зависности: |
| 146 | |
| 147 | * table_id → restaurant_id → restaurant_name, restaurant_location |
| 148 | |
| 149 | Значи, атрибути зависат од не-примарен атрибут што зависи од клучот. Не е во 3НФ. |
| 150 | |
| 151 | '''BCNF:''' |
| 152 | Не е во BCNF бидејќи постојат функционски зависности каде детерминантата не е суперклуч. |
| 153 | |
| 154 | * restaurant_id → restaurant_name, restaurant_location |
| 155 | |
| 156 | '''Декомпозиција''' |
| 157 | |
| 158 | '''R1: Table''' |
| 159 | |
| 160 | { table_id, table_number, restaurant_id } |
| 161 | |
| 162 | (во BCNF – клуч table_id) |
| 163 | |
| 164 | '''R2: Restaurant''' |
| 165 | |
| 166 | { restaurant_id, restaurant_name, restaurant_location } |
| 167 | |
| 168 | (во BCNF – клуч restaurant_id) |
| 169 | |
| 170 | === 4. Мени и мени тагови |
| 171 | || menu_id || menu_name || price || restaurant_id || restaurant_name || tag_id || tag_name || |
| 172 | || 1 || Margarita Pizza || 400 || 201 || Gino’s || 1 || Italian || |
| 173 | || 2 || California Roll || 550 || 202 ||Sushico ||2 || Japanese || |
| 174 | || 3 || Carbonara || 470 || 201 || Gino’s || 1 || Italian || |
| 175 | || 4 || Tiramisu || 300 || 201 || Gino’s || 3 || Dessert || |
| 176 | |
| 177 | '''R''' = { menu_id, menu_name, price, restaurant_id, restaurant_name, tag_id, tag_name } |
| 178 | |
| 179 | '''Функциски зависности:''' |
| 180 | * menu_id → menu_name, price, restaurant_id |
| 181 | |
| 182 | * restaurant_id → restaurant_name |
| 183 | |
| 184 | * tag_id → tag_name |
| 185 | |
| 186 | '''Левo:''' |
| 187 | |
| 188 | * menu_id, restaurant_id, tag_id |
| 189 | |
| 190 | '''Десни атрибути (оние што се зависни):''' |
| 191 | |
| 192 | * menu_name, price, restaurant_name, tag_name |
| 193 | |
| 194 | '''Кандидат клуч:''' |
| 195 | |
| 196 | * menu_id (го одредува скоро сè) |
| 197 | |
| 198 | ''' Нормализација:''' |
| 199 | |
| 200 | '''1НФ – Прва нормална форма''': Сите атрибути се атомски |
| 201 | |
| 202 | '''2НФ – Втора нормална форма''' Клучот menu_id е едноставен, нема парцијални зависности |
| 203 | |
| 204 | '''3НФ – Трета нормална форма''' Постојат транзитивни зависности |
| 205 | |
| 206 | * menu_id → restaurant_id → restaurant_name |
| 207 | |
| 208 | * menu_id → tag_id → tag_name |
| 209 | |
| 210 | '''BCNF''' |
| 211 | |
| 212 | * restaurant_id и tag_id се детерминанти, а не се суперклучеви. |
| 213 | |
| 214 | '''Декомпозиција''' |
| 215 | |
| 216 | '''R1:Menu''' |
| 217 | |
| 218 | { menu_id, menu_name, price, restaurant_id, tag_id } |
| 219 | |
| 220 | '''R2:Restaurant''' |
| 221 | |
| 222 | { restaurant_id, restaurant_name } |
| 223 | |
| 224 | '''R3:MenuTag''' |
| 225 | |
| 226 | { tag_id, tag_name } |
| 227 | |
| 228 | === 5. Преднарачани производи (Preordered Items) со мени и резервација |
| 229 | || preordered_item_id || quantity || reservation_id || reservation_date || user_id || user_name || menu_id || menu_name || price || |
| 230 | || 1 || 2 || 1 || 2025-05-01 || 101 || Ana || 1 || Margarita Pizza || 400 || |
| 231 | || 2 || 1 || 2 || 2025-05-02 || 102 || Marko || 2 || California Roll || 550 || |
| 232 | || 3 || 3 || 3 || 2025-05-03 || 103 || Elena || 3 || Carbonara || 470 || |
| 233 | |
| 234 | '''R''' = { preordered_item_id, quantity, reservation_id, reservation_date, user_id, user_name, menu_id, menu_name, price } |
| 235 | |
| 236 | '''Функциски зависности:''' |
| 237 | |
| 238 | * preordered_item_id → quantity, reservation_id, menu_id |
| 239 | |
| 240 | * reservation_id → reservation_date, user_id |
| 241 | |
| 242 | * user_id → user_name |
| 243 | |
| 244 | * menu_id → menu_name, price |
| 245 | |
| 246 | '''Лево:''' |
| 247 | * preordered_item_id, reservation_id, user_id, menu_id |
| 248 | |
| 249 | '''Само десно (зависни атрибути):''' |
| 250 | * quantity, reservation_date, user_name, menu_name, price |
| 251 | |
| 252 | '''Нормализација:''' |
| 253 | '''1НФ – Прва нормална форма''' Сите податоци се атомски и неделиви. |
| 254 | |
| 255 | '''2НФ – Втора нормална форма'''Kлучот е едноставен (preordered_item_id), нема парцијални зависности. |
| 256 | |
| 257 | '''Трета нормална форма''' имаме транзитивни зависности: |
| 258 | |
| 259 | * preordered_item_id → reservation_id → user_id → user_name |
| 260 | |
| 261 | * preordered_item_id → menu_id → menu_name, price |
| 262 | |
| 263 | '''BCNF''' |
| 264 | Имаме детерминанти како reservation_id и menu_id кои не се суперклучеви во целата релација. |
| 265 | |
| 266 | '''Декомпозиција:''' |
| 267 | |
| 268 | '''R1:Preordred_Item''' |
| 269 | { preordered_item_id, quantity, reservation_id, menu_id } |
| 270 | |
| 271 | === Дискусија |
| 272 | |
| 273 | Релацијата'''(Резервации со корисници и маси)''' ги инкорпорира сите потребни податоци за една резервација, но ја нарушува нормалната форма поради транзитивна зависност. Oва води до повторување на информации – ист корисник или ресторан ќе се појавува повеќепати, што го зголемува ризикот од несогласување на податоци (на пример, корисникот ќе има различни имиња во различни редови ако се направи грешка). |
| 274 | |
| 275 | Декомпозицијата ја разрешува оваа слабост. Преку изолирање на ентитетите User, Table, и Restaurant, се постигнува структурен и логички интегритет на базата, овозможувајќи: |
| 276 | |
| 277 | * Лесно ажурирање на корисник или ресторан без влијание врз резервациите |
| 278 | |
| 279 | ---- |
| 280 | |
| 281 | Оваа табела претставува типичен пример каде што '''еден ресторан има повеќе маси'''. Без нормализација, информациите за ресторанот се повторуваат за секоја маса, што има неколку проблеми: |
| 282 | |
| 283 | * Се троши повеќе простор во базата. |
| 284 | |
| 285 | * Може да дојде до грешки – на пример, ист ресторан да се внесе со различно име кај различни маси. |
| 286 | |
| 287 | Со нормализацијата, се одвојуваат податоците за масите од податоците за рестораните, што носи повеќе предности: |
| 288 | |
| 289 | * Aко се смени име или локација, се менува на едно место. |
| 290 | |
| 291 | * Полесно се додаваат нови информации |
| 292 | |
| 293 | ---- |
| 294 | |
| 295 | Некои атрибути се повторуваат – на пример името на ресторан или името на тагот. Тоа создава вишок(редундантност) и ризик од неконзистентност. |
| 296 | |
| 297 | Со нормализација, ги раздвојуваме работите логично: |
| 298 | |
| 299 | Менито го врзуваме со ресторан и со категорија (таг), |
| 300 | |
| 301 | А името на ресторанот и името на категоријата ги чуваме само еднаш, посебно. |
| 302 | |
| 303 | Овој пристап ја поедноставува базата, ја прави поефикасна и поотпорна на грешки при ажурирање. |