== Функционални карактеристики и нормализација === Поделба на доменот според типот на евиденција Поради комплексноста на моделот на базата, речиси е невозможно сите податоци да се стават во една табела. Затоа проблемот на нормализација ќе го поделиме на повеќе делови. Логичната поделба на табелите се заснова на улогите и процесите во системот: '''корисници, резервации, ресторани и мени производи.''' Корисниците имаат директна интеракција со табелата reservations, а потоа може да се поврзат со tables и restaurants за да се добијат информации за ресторанот и масата што ја резервирале. Со тоа се формира агрегирана табела која може да ја наречеме: '''Резервации со корисници и маси''' Релацијата е создадена за да ги поврзе информациите за масите со соодветните ресторани. Ова овозможува брз и ефикасен пристап до сите маси во даден ресторан.'''Маси и ресторани''' Со оглед на разновидноста на менито и поврзаните тагови (на пример, кујна или тип на јадење), потребно е да се структурираат податоците на начин што ќе овозможи лесно филтрирање и пребарување. '''Мени и мени тагови''' Со цел поефикасно следење на нарачките направени во текот на резервацијата, оваа релација ги поврзува преднарачаните производи со корисникот и резервацијата. '''Преднарачани производи (Preordered Items)''' === 1. Oпределување на важечките функциски зависности Тргнуваме од список во кој сите атрибути имаат различни имиња. За таа цел атрибутите кои што имаат исти имиња ги преименувавме. Во продолжение е списокот на атрибути кои што се преименувани. * id (Кај ентитетот pre_ordered_items) -> preorderedItemId * name (Кај ентитетот pre_ordered_items) -> preorderedItemName * status (Кај ентитетот reservations) -> reservationStatus * id (Кај ентитетот reservations) -> reservationHistoryId * status (Кај ентитетот reservation_history) -> reservationStatus * id (Кај ентиетот menu_tags) -> menuTagId * id (Кај ентитетот users) -> userId * category (Кај ентитетот menus) -> menuCategory * location (Кај ентитетот tables) -> tableLocation === 2. Резервации со корисници и маси ||reservation_id || reservation_date || time_from || time_to || number_of_people || user_id || user_name || table_id || table_number || restaurant_id || restaurant_name || restaurant_location ||1 || 2025-05-01 ||18:00 ||20:00 ||4 ||101 ||Ana ||11 ||1 ||201 ||Gino’s ||Skopje, Centar|| ||2 ||2025-05-02 ||19:30 ||21:00 ||2 ||102 ||Marko ||12 ||2 ||202 ||Sushico ||Skopje, Karposh|| ||3 ||2025-05-03 ||17:00 ||18:30 ||3 ||103 ||Elena ||13 ||3 ||203 ||Bella Italia ||Skopje, Aerodrom|| '''R''' = { reservation_id, reservation_date, time_from, time_to, number_of_people, user_id, user_name, table_id, table_number, restaurant_id, restaurant_name, restaurant_location } '''Функциски зависности:''' * reservation_id → reservation_date, time_from, time_to, number_of_people, user_id, table_id * user_id → user_name * table_id → table_number, restaurant_id * restaurant_id → restaurant_name, restaurant_location '''Лево:''' reservation_id, user_id, table_id, restaurant_id '''Само десно (зависни атрибути):''' user_name, restaurant_name, restaurant_location, reservation_date, time_from, time_to, number_of_people, table_number '''Кандидат клуч:''' reservation_id '''Нормализација:''' ''' 1НФ – Прва нормална форма:''' Сите атрибути се атомски. '''2НФ – Втора нормална форма:''' Клучот reservation_id е едноставен, па нема парцијални зависности. '''3НФ – Трета нормална форма:''' Имаме транзитивни зависности: * reservation_id → table_id → restaurant_id → restaurant_name, restaurant_location * reservation_id → user_id → user_name Значи, атрибути зависат од не-примарен атрибут што зависи од клучот. Не е во 3НФ. '''BCNF:''' Не е во BCNF бидејќи постојат функционски зависности каде детерминантата не е суперклуч. * user_id → user_name * table_id → restaurant_id '''Декомпозицијa''' '''R1:Reservation''' { reservation_id, reservation_date, time_from, time_to, number_of_people, user_id, table_id } (во BCNF – клуч reservation_id) '''R2:User''' { user_id, user_name } (во BCNF – клуч user_id) '''R3: Table''' { table_id, table_number, restaurant_id } (во BCNF - клуч table_id) '''R4: Restaurant''' { restaurant_id, restaurant_name, restaurant_location } (во BCNF – клуч restaurant_id) === 3. Маси и ресторани ||table_id ||table_number ||restaurant_id ||restaurant_name ||restaurant_location|| ||11 ||1 ||201 ||Gino’s ||Skopje, Centar|| ||12 ||2 ||202 ||Sushico ||Skopje, Karposh|| ||13 ||3 ||203 ||Bella Italia ||Skopje, Aerodrom|| '''R'''= { table_id, table_number, restaurant_id, restaurant_name, restaurant_location } '''Функциски зависности:''' * table_id → table_number, restaurant_id * restaurant_id → restaurant_name, restaurant_location '''Лево:''' table_id, restaurant_id '''Само десно (зависни атрибути):''' table_number, restaurant_name, restaurant_location '''Кандидат клуч:''' table_id '''Нормализација:''' '''1НФ – Прва нормална форма:'''Сите атрибути се атомски. '''2НФ – Втора нормална форма: '''Клучот table_id е едноставен, па нема парцијални зависности. '''3НФ – Трета нормална форма: '''Имаме транзитивни зависности: * table_id → restaurant_id → restaurant_name, restaurant_location Значи, атрибути зависат од не-примарен атрибут што зависи од клучот. Не е во 3НФ. '''BCNF:''' Не е во BCNF бидејќи постојат функционски зависности каде детерминантата не е суперклуч. * restaurant_id → restaurant_name, restaurant_location '''Декомпозиција''' '''R1: Table''' { table_id, table_number, restaurant_id } (во BCNF – клуч table_id) '''R2: Restaurant''' { restaurant_id, restaurant_name, restaurant_location } (во BCNF – клуч restaurant_id) === 4. Мени и мени тагови || menu_id || menu_name || price || restaurant_id || restaurant_name || tag_id || tag_name || || 1 || Margarita Pizza || 400 || 201 || Gino’s || 1 || Italian || || 2 || California Roll || 550 || 202 ||Sushico ||2 || Japanese || || 3 || Carbonara || 470 || 201 || Gino’s || 1 || Italian || || 4 || Tiramisu || 300 || 201 || Gino’s || 3 || Dessert || '''R''' = { menu_id, menu_name, price, restaurant_id, restaurant_name, tag_id, tag_name } '''Функциски зависности:''' * menu_id → menu_name, price, restaurant_id * restaurant_id → restaurant_name * tag_id → tag_name '''Левo:''' * menu_id, restaurant_id, tag_id '''Десни атрибути (оние што се зависни):''' * menu_name, price, restaurant_name, tag_name '''Кандидат клуч:''' * menu_id (го одредува скоро сè) ''' Нормализација:''' '''1НФ – Прва нормална форма''': Сите атрибути се атомски '''2НФ – Втора нормална форма''' Клучот menu_id е едноставен, нема парцијални зависности '''3НФ – Трета нормална форма''' Постојат транзитивни зависности * menu_id → restaurant_id → restaurant_name * menu_id → tag_id → tag_name '''BCNF''' * restaurant_id и tag_id се детерминанти, а не се суперклучеви. '''Декомпозиција''' '''R1:Menu''' { menu_id, menu_name, price, restaurant_id, tag_id } '''R2:Restaurant''' { restaurant_id, restaurant_name } '''R3:MenuTag''' { tag_id, tag_name } === 5. Преднарачани производи (Preordered Items) со мени и резервација || preordered_item_id || quantity || reservation_id || reservation_date || user_id || user_name || menu_id || menu_name || price || || 1 || 2 || 1 || 2025-05-01 || 101 || Ana || 1 || Margarita Pizza || 400 || || 2 || 1 || 2 || 2025-05-02 || 102 || Marko || 2 || California Roll || 550 || || 3 || 3 || 3 || 2025-05-03 || 103 || Elena || 3 || Carbonara || 470 || '''R''' = { preordered_item_id, quantity, reservation_id, reservation_date, user_id, user_name, menu_id, menu_name, price } '''Функциски зависности:''' * preordered_item_id → quantity, reservation_id, menu_id * reservation_id → reservation_date, user_id * user_id → user_name * menu_id → menu_name, price '''Лево:''' * preordered_item_id, reservation_id, user_id, menu_id '''Само десно (зависни атрибути):''' * quantity, reservation_date, user_name, menu_name, price '''Нормализација:''' '''1НФ – Прва нормална форма''' Сите податоци се атомски и неделиви. '''2НФ – Втора нормална форма'''Kлучот е едноставен (preordered_item_id), нема парцијални зависности. '''Трета нормална форма''' имаме транзитивни зависности: * preordered_item_id → reservation_id → user_id → user_name * preordered_item_id → menu_id → menu_name, price '''BCNF''' Имаме детерминанти како reservation_id и menu_id кои не се суперклучеви во целата релација. '''Декомпозиција:''' '''R1:Preordred_Item''' { preordered_item_id, quantity, reservation_id, menu_id } '''R2: Reservation''' { reservation_id, reservation_date, user_id } '''R3: User''' { user_id, user_name } '''R4: Menu''' { menu_id, menu_name, price } === Дискусија Релацијата'''(Резервации со корисници и маси)''' ги инкорпорира сите потребни податоци за една резервација, но ја нарушува нормалната форма поради транзитивна зависност. Oва води до повторување на информации – ист корисник или ресторан ќе се појавува повеќепати, што го зголемува ризикот од несогласување на податоци (на пример, корисникот ќе има различни имиња во различни редови ако се направи грешка). Декомпозицијата ја разрешува оваа слабост. Преку изолирање на ентитетите User, Table, и Restaurant, се постигнува структурен и логички интегритет на базата, овозможувајќи: * Лесно ажурирање на корисник или ресторан без влијание врз резервациите Резервации со корисници и маси * R1(reservation_id, reservation_date, time_from, time_to, number_of_people, user_id, table_id) * R2(user_id, user_name) * R3(table_id, table_number, restaurant_id) * R4(restaurant_id, restaurant_name, restaurant_location) ---- Оваа табела претставува типичен пример каде што '''еден ресторан има повеќе маси'''. Без нормализација, информациите за ресторанот се повторуваат за секоја маса, што има неколку проблеми: * Се троши повеќе простор во базата. * Може да дојде до грешки – на пример, ист ресторан да се внесе со различно име кај различни маси. Со нормализацијата, се одвојуваат податоците за масите од податоците за рестораните, што носи повеќе предности: * Aко се смени име или локација, се менува на едно место. * Полесно се додаваат нови информации Маси и ресторани * R1(table_id, table_number, restaurant_id) * R2(restaurant_id, restaurant_name, restaurant_location) ---- Некои атрибути се повторуваат – на пример името на ресторан или името на тагот. Тоа создава вишок(редундантност) и ризик од неконзистентност. Со нормализација, ги раздвојуваме работите логично: Менито го врзуваме со ресторан и со категорија (таг), А името на ресторанот и името на категоријата ги чуваме само еднаш, посебно. '''Воведување на табела priceHistory:''' Целта на оваа табела е да се зачуваат претходните цени на артиклите од менито кога тие ќе се променат. Секој пат кога ќе се ажурира цената на артикл, автоматски ќе се снима старата цена во табелата priceHistory, заедно со временски печат. Мени и мени тагови * R1(menu_id, menu_name, price, restaurant_id, tag_id) * R2(restaurant_id, restaurant_name) * R3(tag_id, tag_name) ---- Во оваа релација'''(Преднарачани производи)''' се следи кои производи (од мени) биле однапред нарачани за конкретна резервација. Но со тоа што во една табела ги имаме и податоците за корисникот, резервацијата и производот, се појавуваат вишоци. Пример: исто мени или исто корисничко име може да се повторува. Со нормализација ја раздвојуваме секоја логична целина: Preordered_Item знае што и колку е однапред нарачано, Menu знае што е тоа што се нуди, Reservation води евиденција за кога и кој, User ги чува податоците за корисниците. '''Воспоставување врска меѓу PreorderedItems и Menu:''' Оваа врска ќе овозможи прецизно следење на тоа кој артикл точно е однапред нарачан. Врската ќе обезбеди целосна интеграција на податоците при ажурирање на цените и прикажување на историски податоци. Преднарачани производи (Preordered Items) со мени и резервација * R1(preordered_item_id, quantity, reservation_id, menu_id) * R2(reservation_id, reservation_date, user_id) * R3(user_id, user_name) * R4(menu_id, menu_name, price)