Changes between Version 7 and Version 8 of Normalization


Ignore:
Timestamp:
09/13/25 04:34:58 (7 days ago)
Author:
222003
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v7 v8  
    1 
    2 == Систематска анализа и нормализација на базата Synergymed
    3 
    4 ----
    5 Целосна и детална анализа на сите ентитети и релации во базата SynergyMed.\\
    6 
    7 Целта е да се докаже, со користење на функционални зависности, покривачи и суперклучеви, дека секоја релација ја задоволува Boyce–Codd Normal Form (BCNF).
    8 
    9 == Нормализација
    10 Првичниот дизајн не ја содржеше релацијата **Facility**. Наместо тоа, релацијата **Inventory** беше директно врзана со **Company**, според следниот модел:\\
    11 
    12 Inventory(id, company_id, code, ...)\\
    13 
    14 Функционалните зависности беа:\\
    15 - id → {company_id, code, ...}\\
    16 - code → id\\
    17 - company_id → code  \\
    18 \\
    19 Последната зависност company_id → code претставува проблем: левата страна (company_id) не е суперклуч, а детерминира друг атрибут. Ова е директно прекршување на условот за BCNF.
    20 
    21 **Доказ преку покривач:**\\
    22 - (company_id)⁺ = {company_id, code}  \\
    23 → не го покрива целиот сет на атрибути во Inventory.  \\
    24 - Значи company_id не е суперклуч, а сепак детерминира code.  \\
    25 - Следува: Inventory **не е во BCNF**.\\
    26 
    27 ----
    28 
    29 == Декомпозиција за да се постигне BCNF
    30 
    31 За да се елиминира прекршувањето, воведовме нова релација **Facility**. \\
    32 Сега добиваме:\\
    33 \\
    34 Facility(id, company_id, facility_name, code)  \\
    35 Inventory(id, facility_id, ...)\\
    36 \\
    37 Нови функционални зависности:\\
    38 - Во Facility:  \\
    39   id → {company_id, facility_name, code}  \\
    40   code → id  \\
    41   → во двата случаи левата страна е клуч → Facility е во BCNF.  \\
    42 \\
    43 - Во Inventory:  \\
    44   id → {facility_id, ...}  \\
    45   facility_id е уникатен → facility_id → id  \\
    46   → левата страна секогаш е клуч → Inventory е во BCNF.\\
    47 
    48 Со оваа декомпозиција овозможивме и полесно скалирање на апликацијата во иднина, што воедно беше и наша цел.
    49 
    50 ----
    51 
    52 == Идентификување на суперклучеви и нивните покривачи после нормализацијата
    53 
    54 **Users**\\
    55 Суперклуч: id\\
    56 id⁺ = {id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth}\\
    57 \\
    58 Суперклуч: username\\
    59 username⁺ = {username, id, first_name, last_name, hashed_password, e_mail, gender, date_created, date_of_birth}\\
    60 \\
    61 Суперклуч: e_mail\\
    62 e_mail⁺ = {e_mail, id, first_name, last_name, username, hashed_password, gender, date_created, date_of_birth}\\
    63 \\
    64 **Client**\\
    65 Суперклуч: user_id\\
    66 user_id⁺ = {user_id, is_verified}\\
    67 \\
    68 **Pharmacist**\\
    69 Суперклуч: user_id\\
    70 user_id⁺ = {user_id}\\
    71 \\
    72 **Admin**\\
    73 Суперклуч: user_id\\
    74 user_id⁺ = {user_id}\\
    75 \\
    76 **Company**\\
    77 Суперклуч: id\\
    78 id⁺ = {id, company_name, description, registration_number}\\
    79 \\
    80 Суперклуч: registration_number\\
    81 registration_number⁺ = {registration_number, id, company_name, description}\\
    82 \\
    83 **Pharmacy**\\
    84 Суперклуч: company_id\\
    85 company_id⁺ = {company_id}\\
    86 \\
    87 **Distributor**\\
    88 Суперклуч: company_id\\
    89 company_id⁺ = {company_id}\\
    90 \\
    91 **Manufacturer**\\
    92 Суперклуч: company_id\\
    93 company_id⁺ = {company_id}\\
    94 \\
    95 **!DeliveryCompany**\\
    96 Суперклуч: company_id\\
    97 company_id⁺ = {company_id}\\
    98 \\
    99 **Facility**\\
    100 Суперклуч: id\\
    101 id⁺ = {id, company_id, facility_name, code}\\
    102 \\
    103 Суперклуч: code\\
    104 code⁺ = {code, id, company_id, facility_name}\\
    105 \\
    106 **Inventory**\\
    107 Суперклуч: id\\
    108 id⁺ = {id, facility_id}\\
    109 \\
    110 Суперклуч: facility_id\\
    111 facility_id⁺ = {facility_id, id}\\
    112 \\
    113 **Medicine**\\
    114 Суперклуч: id\\
    115 id⁺ = {id, medicine_name, active_ingredient}\\
    116 \\
    117 **!BrandedMedicine**\\
    118 Суперклуч: id\\
    119 id⁺ = {id, manufacturer_id, name, price, description, dosage_form, strength, origin_country}\\
    120 \\
    121 **!BrandedMedicineImage**\\
    122 Суперклуч: id\\
    123 id⁺ = {id, branded_medicine_id, image}\\
    124 \\
    125 **!ContactInformation**\\
    126 Суперклуч: id\\
    127 id⁺ = {id, phone, address, user_id, facility_id}\\
    128 \\
    129 **!ClubCard**\\
    130 Суперклуч: id\\
    131 id⁺ = {id, user_id, club_program, points}\\
    132 \\
    133 **!PaymentMethod**\\
    134 Суперклуч: id\\
    135 id⁺ = {id, method_name}\\
    136 \\
    137 **Payment**\\
    138 Суперклуч: id\\
    139 id⁺ = {id, client_id, payment_method_id, payment_date, amount, status}\\
    140 \\
    141 **!ClientOrder**\\
    142 Суперклуч: id\\
    143 id⁺ = {id, client_id, delivery_company_id, payment_id, order_date, expected_arrival_date, status, total_price}\\
    144 \\
    145 Суперклуч: payment_id\\
    146 payment_id⁺ = {payment_id, id, client_id, delivery_company_id, order_date, expected_arrival_date, status, total_price}\\
    147 \\
    148 **!ShoppingCart**\\
    149 Суперклуч: id\\
    150 id⁺ = {id, client_id}\\
    151 \\
    152 **!SupplyOrder**\\
    153 Суперклуч: id\\
    154 id⁺ = {id, distributor_id, pharmacy_id, order_date, expected_arrival_date, status}\\
    155 \\
    156 **!HealthProfile**\\
    157 Суперклуч: id\\
    158 id⁺ = {id, client_id, blood_type}\\
    159 \\
    160 **!SensitiveClientData**\\
    161 Суперклуч: id\\
    162 id⁺ = {id, client_id, pharmacist_id, embg, portrait_photo, verification_status}\\
    163 \\
    164 **Prescription**\\
    165 Суперклуч: id\\
    166 id⁺ = {id, client_id, medicine_id, issued_by, issued_at, valid_to, embg}\\
    167 \\
    168 **ClientOrder_BrandedMedicine**\\
    169 Суперклуч: {order_id, branded_medicine_id}\\
    170 {order_id, branded_medicine_id}⁺ = {order_id, branded_medicine_id, quantity}\\
    171 \\
    172 **ShoppingCart_BrandedMedicine**\\
    173 Суперклуч: {shopping_cart_id, branded_medicine_id}\\
    174 {shopping_cart_id, branded_medicine_id}⁺ = {shopping_cart_id, branded_medicine_id, quantity}\\
    175 \\
    176 **SupplyOrder_BrandedMedicine**\\
    177 Суперклуч: {supply_order_id, branded_medicine_id}\\
    178 {supply_order_id, branded_medicine_id}⁺ = {supply_order_id, branded_medicine_id, quantity}\\
    179 \\
    180 **Inventory_BrandedMedicine**\\
    181 Суперклуч: {inventory_id, branded_medicine_id}\\
    182 {inventory_id, branded_medicine_id}⁺ = {inventory_id, branded_medicine_id, quantity, last_changed}\\
    183 \\
    184 **Pharmacy_Catalog**\\
    185 Суперклуч: {pharmacy_id, branded_medicine_id}\\
    186 {pharmacy_id, branded_medicine_id}⁺ = {pharmacy_id, branded_medicine_id}\\
    187 \\
    188 **Distributor_BrandedMedicine**\\
    189 Суперклуч: {distributor_id, branded_medicine_id}\\
    190 {distributor_id, branded_medicine_id}⁺ = {distributor_id, branded_medicine_id}\\
    191 \\
    192 **Branded_Medicine_InstanceOf_Medicine**\\
    193 Суперклуч: {branded_medicine_id, medicine_id}\\
    194 {branded_medicine_id, medicine_id}⁺ = {branded_medicine_id, medicine_id}\\
    195 \\
    196 **AllergicReaction_HealthProfile_Medicine**\\
    197 Суперклуч: {health_profile_id, medicine_id}\\
    198 {health_profile_id, medicine_id}⁺ = {health_profile_id, medicine_id, date_diagnosed, description, severity}\\
    199 \\
    200 **MedicineInteraction**\\
    201 Суперклуч: {medicine_id_1, medicine_id_2}\\
    202 {medicine_id_1, medicine_id_2}⁺ = {medicine_id_1, medicine_id_2, type, description, severity}\\
    203 
    204 ----
    205 
    206 == Проверка на BCNF
    207 
    208 **Users**\\
    209 Табелата Users ги чува сите основни податоци за корисниците. Примарен клуч е id, но истовремено username и e_mail се декларирани како уникатни и затоа претставуваат алтернативни клучеви. Функционалните зависности се: id → {first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth}, како и username → id и e_mail → id. Бидејќи секоја зависност има клуч (или кандидат клуч) на левата страна, секој атрибут е целосно функционално зависен од клучот. \\
    210 **Заклучок: Users е во BCNF.**\\
    211 \\
    212 **Client, Pharmacist, Admins**\\
    213 Овие три релации се специјализации на Users и го користат user_id како примарен клуч. Во Client, атрибутот is_verified зависи единствено од user_id. Кај Pharmacist и Admins нема дополнителни атрибути освен врската со Users. Затоа, за сите три релации, левата страна на секоја функционална зависност е суперклуч. \\
    214 **Заклучок: сите три релации се во BCNF.**\\
    215 \\
    216 **Company**\\
    217 Релацијата Company има примарен клуч id, но и registration_number е уникатен и претставува алтернативен клуч. Зависностите се: id → {company_name, description, registration_number} и registration_number → id. И во двата случаи левата страна е клуч, што гарантира исполнување на BCNF. \\
    218 **Заклучок: Company е во BCNF.**\\
    219 \\
    220 **Pharmacy, Distributor, Manufacturer, !DeliveryCompany**\\
    221 Овие четири релации се специјализации на Company и го користат company_id како примарен клуч. Немаат сопствени не-клучни атрибути, па единствената зависност е company_id → {}. Како што секогаш левата страна е клуч, **сите се во BCNF.**\\
    222 \\
    223 **Facility**\\
    224 Табелата Facility има два клуча: id и code (кој е уникатен). Зависностите се id → {company_id, facility_name, code} и code → id. Во двата случаи, левата страна е суперклуч, со што сите атрибути зависат целосно од клучевите. \\
    225 **Заклучок: Facility е во BCNF.**\\
    226 \\
    227 **Inventory**\\
    228 Релацијата Inventory има примарен клуч id и дополнително facility_id е уникатен, што создава уште еден алтернативен клуч. Зависностите се id → facility_id и facility_id → id. Ова е двонасочна зависност помеѓу два клуча. **Затоа релацијата е во BCNF.**\\
    229 \\
    230 **Medicine**\\
    231 Релацијата Medicine има едноставен примарен клуч id. Функционалната зависност е id → {medicine_name, active_ingredient}. Нема дополнителни уникатни ограничувања, па сите атрибути зависат исклучиво од клучот. \\
    232 **Заклучок: Medicine е во BCNF.**\\
    233 \\
    234 **!BrandedMedicine**\\
    235 Оваа релација го користи id како примарен клуч и содржи повеќе атрибути (manufacturer_id, name, price, description, dosage_form, strength, origin_country). Функционалната зависност е id → {сите останати атрибути}. Производителот може да има повеќе лекови, па manufacturer_id сам по себе не е клуч. Левата страна (id) е клуч, така што **!BrandedMedicine е во BCNF.**\\
    236 \\
    237 **!BrandedMedicineImage**\\
    238 Тука примарен клуч е id. Зависноста е id → {branded_medicine_id, image}. Бидејќи секој атрибут зависи од примарниот клуч, **релацијата е во BCNF.**\\
    239 \\
    240 **!ContactInformation**\\
    241 Примарен клуч е id. Дополнителното ограничување бара секоја контакт информација да се однесува на точно еден објект или точно еден корисник. Зависностите се id → {phone, address, user_id, facility_id}. Сите зависности се со клуч на левата страна, па **!ContactInformation е во BCNF.**\\
    242 \\
    243 **!ClubCard**\\
    244 Оваа релација има примарен клуч id. Сите останати атрибути (user_id, club_program, points) зависат единствено од овој клуч. Нема транзитивни зависности. Заклучок: **!ClubCard е во BCNF.**\\
    245 \\
    246 **!PaymentMethod**\\
    247 Со примарен клуч id, единствената зависност е id → method_name. **Затоа релацијата е во BCNF.**\\
    248 \\
    249 **Payment**\\
    250 Релацијата Payment има примарен клуч id. Атрибутите client_id, payment_method_id, payment_date, amount, status зависат директно од id. Нема други уникатни ограничувања што би создале транзитивни зависности. \\
    251 **Заклучок: Payment е во BCNF.**\\
    252 \\
    253 **!ClientOrder**\\
    254 Оваа релација има два кандидат клуча: id (PK) и payment_id (unique). Зависностите се id → {client_id, delivery_company_id, payment_id, order_date, expected_arrival_date, status, total_price} и payment_id → id. Бидејќи во двата случаи левата страна е клуч, **релацијата е во BCNF.**\\
    255 \\
    256 **!ShoppingCart**\\
    257 Примарен клуч е id. Единствената зависност е id → {client_id}. Бидејќи левата страна е клуч, **релацијата е во BCNF.**\\
    258 \\
    259 **!SupplyOrder**\\
    260 Примарен клуч е id. Сите останати атрибути (distributor_id, pharmacy_id, order_date, expected_arrival_date, status) зависат од овој клуч. \\
    261 **Заклучок: !SupplyOrder е во BCNF.**\\
    262 \\
    263 **!HealthProfile**\\
    264 Со примарен клуч id, останатите атрибути (client_id, blood_type) зависат исклучиво од клучот. \\
    265 **Заклучок: !HealthProfile е во BCNF.**\\
    266 \\
    267 **!SensitiveClientData**\\
    268 Примарен клуч е id. Сите останати атрибути (client_id, pharmacist_id, embg, portrait_photo, verification_status) зависат од него. \\
    269 **Затоа релацијата е во BCNF.**\\
    270 \\
    271 **Prescription**\\
    272 Примарен клуч е id. Функционалната зависност е id → {client_id, medicine_id, issued_by, issued_at, valid_to, embg}. Иако embg може да се повторува за повеќе рецепти, примарниот клуч секогаш е id, што гарантира BCNF. \\
    273 **Заклучок: Prescription е во BCNF.**\\
    274 \\
    275 **ClientOrder_BrandedMedicine**\\
    276 Оваа релација ги поврзува клиентските нарачки со брендираните лекови и содржи и атрибут quantity. Примарен клуч е составен: {order_id, branded_medicine_id}. Функционалната зависност е {order_id, branded_medicine_id} → {quantity}. Покривачот (order_id, branded_medicine_id)⁺ = {order_id, branded_medicine_id, quantity}, што ги содржи сите атрибути на релацијата. \\
    277 **Затоа ClientOrder_BrandedMedicine е во BCNF.**\\
    278 \\
    279 **ShoppingCart_BrandedMedicine**\\
    280 Оваа релација ги поврзува кошничките со брендираните лекови и содржи количество. Примарен клуч е {shopping_cart_id, branded_medicine_id}. Функционалната зависност е {shopping_cart_id, branded_medicine_id} → {quantity}. Покривачот на составниот клуч ги опфаќа сите атрибути, па нема парцијални ниту транзитивни зависности. **Заклучок: ShoppingCart_BrandedMedicine е во BCNF.**\\
    281 \\
    282 **SupplyOrder_BrandedMedicine**\\
    283 Оваа релација поврзува нарачки за снабдување со брендирани лекови и содржи quantity. Примарен клуч е {supply_order_id, branded_medicine_id}. Зависност: {supply_order_id, branded_medicine_id} → {quantity}. Покривачот на составниот клуч ги содржи сите атрибути. \\
    284 **Заклучок: SupplyOrder_BrandedMedicine е во BCNF.**\\
    285 \\
    286 **Inventory_BrandedMedicine**\\
    287 Оваа релација поврзува магацини со брендирани лекови и содржи {quantity, last_changed}. Примарен клуч е {inventory_id, branded_medicine_id}. Зависностите се {inventory_id, branded_medicine_id} → {quantity, last_changed}. Покривачот на составниот клуч ги содржи сите атрибути, што значи дека **е во BCNF.**\\
    288 \\
    289 **Pharmacy_Catalog**\\
    290 Релацијата ги поврзува аптеките со брендирани лекови. Примарен клуч е {pharmacy_id, branded_medicine_id}. Единствената зависност е составниот клуч → {} (нема дополнителни атрибути). Покривачот на клучот ги содржи сите атрибути, па **Pharmacy_Catalog е во BCNF.**\\
    291 \\
    292 **Distributor_BrandedMedicine**\\
    293 Оваа релација поврзува дистрибутери со брендирани лекови. Примарен клуч е {distributor_id, branded_medicine_id}. Нема дополнителни атрибути, па функционалната зависност е {distributor_id, branded_medicine_id} → {}. Бидејќи клучот ги покрива сите атрибути, **Distributor_BrandedMedicine е во BCNF.**\\
    294 \\
    295 **Branded_Medicine_InstanceOf_Medicine**\\
    296 Оваа релација ја врзува врската помеѓу брендирани и генерички лекови. Примарен клуч е {branded_medicine_id, medicine_id}. Зависноста е составниот клуч → {}. Покривачот на клучот ги содржи сите атрибути. \\
    297 **Заклучок: Branded_Medicine_InstanceOf_Medicine е во BCNF.**\\
    298 \\
    299 **AllergicReaction_HealthProfile_Medicine**\\
    300 Оваа релација ги поврзува здравствените профили со лекови што предизвикуваат алергиски реакции, и содржи дополнителни атрибути {date_diagnosed, description, severity}. Примарен клуч е {health_profile_id, medicine_id}. Функционалната зависност е {health_profile_id, medicine_id} → {date_diagnosed, description, severity}. Покривачот на составниот клуч ги содржи сите атрибути. **Затоа AllergicReaction_HealthProfile_Medicine е во BCNF.**\\
    301 \\
    302 **!MedicineInteraction**\\
    303 Оваа релација ги опишува интеракциите помеѓу парови лекови. Примарен клуч е {medicine_id_1, medicine_id_2}. Дополнителните атрибути се {type, description, severity}. Функционалната зависност е {medicine_id_1, medicine_id_2} → {type, description, severity}. Со оглед дека составниот клуч ги покрива сите атрибути, **!MedicineInteraction е во BCNF.**\\
    304 
    305 == Проверка на нормализација по промени поради Безбедност (Spring Security)
    306 
    307 Во релацијата Users ги додадовме: isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled — флагови што кореспондираат со UserDetails во Spring Security и се користат при автентикација.\\
    308 \\После промените имаме:\\
    309 **Users**\\
    310 Суперклуч: id\\
    311 id⁺ = {id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled}\\
    312 \\
    313 Суперклуч: username\\
    314 username⁺ = {username, id, first_name, last_name, hashed_password, e_mail, gender, date_created, date_of_birth, isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled}\\
    315 \\
    316 Суперклуч: e_mail\\
    317 e_mail⁺ = {e_mail, id, first_name, last_name, username, hashed_password, gender, date_created, date_of_birth, isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled}\\
    318 \\
    319 Со додавањето на безбедносните атрибути, сите нетривијални функционални зависности и натаму имаат клуч/суперклуч на лева страна => **Users останува во BCNF.**
     1==  Нормализација  ==
     2
     3Во нашата база ги имаме следните id: company_id, medicine_id, payment_method_id, user_id, facility_id, inventory_id, branded_medicine_id, branded_medicine_image_id, clubcard_id, contactinformation_id, healthprofile_id, supply_order_id, client_order_id, prescription_id, sensitiveclientdata_id, shopping_cart_id, payment_id, medicine_id_1, medicine_id_2.
     4
     5Следат функционалните зависимости (ФЗ) извлечени директно од дефинираните ентитети (левата страна е PK или композитен PK). За описните полиња кои имаат исто име во повеќе релации ќе ја ставиме името на релацијата или скратено име како превикс — на пример company_description, branded_description, mi_description, allergic_description... — ова е само за јасност во анализата;
     6
     7Исто така за user_id и client_id во заграда ќе ја пишуваме нивната улога за подобро следење на контекстот на релациите.
     8
     9
     10**company_id** -> company_name, company_description, registration_number
     11**medicine_id** -> medicine_name, medicine_active_ingredient
     12**payment_method_id** -> payment_method_name
     13**user_id** -> first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified
     14**facility_id** -> company_id, facility_name, facility_code
     15**inventory_id** -> facility_id
     16**medicine_id_1, medicine_id_2** -> mi_type, mi_description, mi_severity
     17**payment_id** -> user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status
     18**prescription_id** -> user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg
     19**sensitiveclientdata_id** -> user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status
     20**shopping_cart_id** -> user_id (улога: client)
     21**supply_order_id** -> company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id
     22**branded_medicine_id** -> company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country
     23**branded_medicine_image_id** -> branded_medicine_id, branded_image, is_main_image
     24**clubcard_id** -> user_id, club_program, points
     25**contactinformation_id** -> phone, contact_address, contact_user_id, contact_facility_id
     26**healthprofile_id** -> user_id (улога: client), blood_type
     27**inventory_id, branded_medicine_id** -> quantity, last_changed
     28**client_order_id** -> user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price
     29**client_order_id, branded_medicine_id** -> order_quantity
     30**company_id (улога: pharmacy), branded_medicine_id** -> /
     31**shopping_cart_id, branded_medicine_id** -> cart_quantity
     32**supply_order_id, branded_medicine_id** -> supply_quantity
     33**healthprofile_id, medicine_id** -> date_diagnosed, allergic_description, allergic_severity
     34**branded_medicine_id, medicine_id** -> /
     35**company_id (улога: distributor), branded_medicine_id** -> /
     36
     37**R** = { company_id, company_name, company_description, registration_number, medicine_id, medicine_name, medicine_active_ingredient, payment_method_id, payment_method_name, user_id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, facility_id, facility_name, facility_code, inventory_id, branded_medicine_id, branded_name, branded_price, branded_description, dosage_form, strength, origin_country, branded_medicine_image_id, branded_image, is_main_image, clubcard_id, club_program, points, contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id, healthprofile_id, blood_type, quantity, last_changed, client_order_id, payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price, order_quantity, shopping_cart_id, cart_quantity, supply_order_id, supply_order_date, supply_expected_arrival_date, supply_status, supply_quantity, payment_date, payment_amount, payment_status, prescription_id, issued_by, issued_at, valid_to, prescription_embg, sensitiveclientdata_id, sensitive_embg, portrait_photo, verification_status, medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity, date_diagnosed, allergic_description, allergic_severity, company_role_notes…, user_role_notes… }.
     38
     39**Лево**
     40branded_medicine_image_id
     41client_order_id
     42clubcard_id
     43company_id
     44contactinformation_id
     45facility_id
     46healthprofile_id
     47inventory_id
     48medicine_id
     49medicine_id_1
     50medicine_id_2
     51payment_id
     52payment_method_id
     53prescription_id
     54sensitiveclientdata_id
     55shopping_cart_id
     56supply_order_id
     57branded_medicine_id
     58user_id
     59
     60**Лево и десно**
     61company_id
     62medicine_id
     63payment_method_id
     64user_id
     65facility_id
     66inventory_id
     67branded_medicine_id
     68payment_id
     69
     70**Десно**
     71company_name, company_description, registration_number, medicine_name, medicine_active_ingredient, payment_method_name, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified, facility_name, facility_code, branded_name, branded_price, branded_description, dosage_form, strength, origin_country, branded_image, is_main_image, club_program, points, phone, contact_address, contact_user_id, contact_facility_id, blood_type, quantity, last_changed, client_order_date, client_expected_arrival_date, client_order_status, total_price, order_quantity, cart_quantity, supply_order_date, supply_expected_arrival_date, supply_status, supply_quantity, payment_date, payment_amount, payment_status, issued_by, issued_at, valid_to, prescription_embg, sensitive_embg, portrait_photo, verification_status, mi_type, mi_description, mi_severity, date_diagnosed, allergic_description, allergic_severity.
     72
     73== Покривачи за атрибутите од „Лево“ ==
     74
     75**branded_medicine_image_id+** = { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image, company_id, branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - **Не ги содржи сите атрибути.**
     76**client_order_id+** = { client_order_id, user_id, company_id, payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price, payment_method_id, payment_amount, payment_date, payment_status, payment_method_name } - **Не ги содржи сите атрибути.**
     77**clubcard_id+** = { clubcard_id, user_id, club_program, points, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified } - **Не ги содржи сите атрибути.**
     78**company_id+** = { company_id, company_name, company_description, registration_number } - **Не ги содржи сите атрибути.**
     79**contactinformation_id+** = { contactinformation_id, phone, contact_address, facility_id, facility_name, facility_code, company_id, company_name, company_description, registration_number, user_id, first_name, last_name, username } - **Не ги содржи сите атрибути.**
     80**facility_id+** = { facility_id, company_id, facility_name, facility_code, company_name, company_description, registration_number } - **Не ги содржи сите атрибути.**
     81**healthprofile_id+** = { healthprofile_id, user_id, blood_type, user_id, first_name, last_name, username } - **Не ги содржи сите атрибути.**
     82**inventory_id+** = { inventory_id, facility_id, facility_name, facility_code, company_id, company_name, company_description, registration_number } - **Не ги содржи сите атрибути.**
     83**medicine_id+** = { medicine_id, medicine_name, medicine_active_ingredient } - **Не ги содржи сите атрибути.**
     84**medicine_id_1+** = { medicine_id_1 } - **Не ги содржи сите атрибути.**
     85**medicine_id_2+** = { medicine_id_2 } - **Не ги содржи сите атрибути.**
     86**payment_id+** = { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status, payment_method_name } - **Не ги содржи сите атрибути.**
     87**payment_method_id+** = { payment_method_id, payment_method_name } - **Не ги содржи сите атрибути.**
     88**prescription_id+** = { prescription_id, user_id, medicine_id, issued_by, issued_at, valid_to, prescription_embg, medicine_name, medicine_active_ingredient } - **Не ги содржи сите атрибути.**
     89**sensitiveclientdata_id+** = { sensitiveclientdata_id, sensitive_embg, portrait_photo, verification_status, user_id, first_name, last_name } - **Не ги содржи сите атрибути.**
     90**shopping_cart_id+** = { shopping_cart_id, user_id, first_name, last_name } - **Не ги содржи сите атрибути**
     91**supply_order_id+** = { supply_order_id, supply_order_date, supply_expected_arrival_date, supply_status, facility_id, facility_name, company_id, company_name } - **Не ги содржи сите атрибути.**
     92**branded_medicine_id+** = { branded_medicine_id, company_id, branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - **Не ги содржи сите атрибути.**
     93**user_id+** = { user_id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified } - **Не ги содржи сите атрибути.**
     94
     95
     96
     97=== Kомбинирање на покривачите со цел да стигнеме до сите атрибути ===
     98{ client_order_id }+ додава: user_id, company_id, payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price, payment_method_id, payment_amount, payment_date, payment_status, payment_method_name. - **Не ги содржи сите атрибути.**
     99
     100{ client_order_id, branded_medicine_id }+ додава: order_quantity, branded_name, branded_price, branded_description, dosage_form, strength, company_id, origin_country. - **Не ги содржи сите атрибути.**
     101
     102{ client_order_id, branded_medicine_id, supply_order_id }+ додава: supply_quantity, supply_order_date, supply_expected_arrival_date, supply_status, company_id, company_id, facility_id, facility_name, facility_code, company_name, company_description, registration_number. - **Не ги содржи сите атрибути.**
     103
     104{ client_order_id, branded_medicine_id, supply_order_id, prescription_id }+ додава: prescription_id, user_id, medicine_id, issued_by, issued_at, valid_to, prescription_embg, medicine_name, medicine_active_ingredient. - **Не ги содржи сите атрибути.**
     105
     106{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id }+ додава: sensitiveclientdata_id, user_id, user_id, sensitive_embg, portrait_photo, verification_status. - **Не ги содржи сите атрибути.**
     107
     108{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2 }+ додава: mi_type, mi_description, mi_severity. - **Не ги содржи сите атрибути.**
     109
     110{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2, contactinformation_id }+ додава: contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id, facility_id, facility_name, facility_code, company_id, company_name, company_description, registration_number. - **Не ги содржи сите атрибути.**
     111
     112{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2, contactinformation_id, healthprofile_id, medicine_id }+ додава: date_diagnosed, allergic_description, allergic_severity. - **Не ги содржи сите атрибути.**
     113
     114{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2, contactinformation_id, healthprofile_id, medicine_id, branded_medicine_image_id }+ додава: branded_medicine_image_id, branded_image, is_main_image, branded_name, branded_price, branded_description, dosage_form, strength, company_id, origin_country. - **Не ги содржи сите атрибути.**
     115
     116{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2, contactinformation_id, healthprofile_id, medicine_id, branded_medicine_image_id, inventory_id }+ додава: quantity, last_changed, inventory_id, facility_id, facility_name, facility_code, company_id, company_name, company_description, registration_number. - **Не ги содржи сите атрибути.**
     117
     118{ client_order_id, branded_medicine_id, supply_order_id, prescription_id, sensitiveclientdata_id, medicine_id_1, medicine_id_2, contactinformation_id, healthprofile_id, medicine_id, branded_medicine_image_id, inventory_id, shopping_cart_id }+ додава: cart_quantity, shopping_cart_id, user_id. — **Со оваа комбинација унијата ги покрива сите атрибути на R.**
     119
     120Со оваа последна комбинација добивме унија која ја покрива целата шема R. Задоволена е 1НФ. Меѓутоа, не е задоволена 2НФ поради постоење на парцијални зависимости — некои примери се:
     121quantity, last_changed зависат од (inventory_id, branded_medicine_id) — делумна зависност ако останат во големата релација.
     122order_quantity зависи од (client_order_id, branded_medicine_id).
     123cart_quantity зависи од (shopping_cart_id, branded_medicine_id).
     124supply_quantity зависи од (supply_order_id, branded_medicine_id).
     125mi_type/mi_description/mi_severity зависат од (medicine_id_1, medicine_id_2).
     126
     127== Декомпозиција во 2НФ ==
     128За да ги отстраниме парцијалните зависиности ги делиме атрибутите во релации каде не-клучните атрибути целосно зависат од нивниот клуч:
     129company_id → company_name, company_description, registration_number
     130medicine_id → medicine_name, medicine_active_ingredient
     131payment_method_id → payment_method_name
     132user_id → first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified (Client)
     133facility_id → company_id, facility_name, facility_code
     134inventory_id → facility_id
     135branded_medicine_id → company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country
     136branded_medicine_image_id → branded_medicine_id, branded_image, is_main_image
     137clubcard_id → user_id, club_program, points
     138contactinformation_id → phone, contact_address, contact_user_id, contact_facility_id
     139healthprofile_id → user_id (улога: client), blood_type
     140inventory_id, branded_medicine_id → quantity, last_changed
     141client_order_id → user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price
     142client_order_id, branded_medicine_id → order_quantity
     143shopping_cart_id → user_id (улога: client)
     144shopping_cart_id, branded_medicine_id → cart_quantity
     145supply_order_id → company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id
     146supply_order_id, branded_medicine_id → supply_quantity
     147payment_id → user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status
     148prescription_id → user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg
     149sensitiveclientdata_id → user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status
     150medicine_id_1, medicine_id_2 → mi_type, mi_description, mi_severity
     151healthprofile_id, medicine_id → date_diagnosed, allergic_description, allergic_severity
     152branded_medicine_id, medicine_id → (врска бранд->лек)
     153company_id (улога: distributor), branded_medicine_id → (junction)
     154company_id (улога: pharmacy), branded_medicine_id → (junction)
     155
     156Со ваква декомпозиција ги извлекуваме следните релации:
     157R1 { company_id, company_name, company_description, registration_number } - **во BCNF**
     158R2 { medicine_id, medicine_name, medicine_active_ingredient } - **во BCNF**
     159R3 { payment_method_id, payment_method_name } - **во BCNF**
     160R4 { user_id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified } - **во BCNF**
     161R5 { facility_id, company_id, facility_name, facility_code } - **во BCNF**
     162R6 { inventory_id, facility_id } - **во BCNF**
     163R7 { branded_medicine_id, company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - **во BCNF**
     164R8 { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image } - **во BCNF**
     165R9 { clubcard_id, user_id, club_program, points } - **во BCNF**
     166R10 { contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id } - **во BCNF**
     167R11 { healthprofile_id, user_id (улога: client), blood_type } - **во BCNF**
     168R12 { inventory_id, branded_medicine_id, quantity, last_changed } - **во BCNF**
     169R13 { client_order_id, user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price } - **во BCNF**
     170R14 { client_order_id, branded_medicine_id, order_quantity } - **во BCNF**
     171R15 { shopping_cart_id, user_id (улога: client) } - **во BCNF**
     172R16 { shopping_cart_id, branded_medicine_id, cart_quantity } - **во BCNF**
     173R17 { supply_order_id, company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id } - **во BCNF**
     174R18 { supply_order_id, branded_medicine_id, supply_quantity } - **во BCNF**
     175R19 { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status } - **во BCNF**
     176R20 { prescription_id, user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg } - **во BCNF**
     177R21 { sensitiveclientdata_id, user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status } - **во BCNF**
     178R22 { medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity } - **во BCNF**
     179R23 { healthprofile_id, medicine_id, date_diagnosed, allergic_description, allergic_severity } - **во BCNF**
     180R24 { branded_medicine_id, medicine_id } (Branded_Medicine_InstanceOf_Medicine) - **во BCNF**
     181R25 { company_id (улога: distributor), branded_medicine_id } (Distributor_BrandedMedicine) - **во BCNF**
     182R26 { company_id (улога: pharmacy), branded_medicine_id } (Pharmacy_Catalog) - **во BCNF**
     183
     184
     185Проверка на 3НФ (транзитивни зависиности) и финална декомпозиција.
     186Сега ги проверуваме R1..R26 за транзитивни зависиности. Ако некаде постои транзитивност, ќе го декомпонираме дополнително.
     187Проверка на најважните случаи:
     188R7 (branded_medicine_id -> company_id (улога: manufacturer), …) — company_id е FK кон Company; Company е одвоена во R1, па нема транзитивна зависност во R7. R7 е во BCNF.
     189R5 (facility_id -> company_id, …) — company_… се во R1; нема транзитивност во R5.
     190R19 (payment_id -> payment_method_id, …) и R3 (payment_method_id -> payment_method_name) — се одделени: посебна релација за PaymentMethod (R3), а Payment држи само FK payment_method_id. Нема транзитивност во R19.
     191R12 (inventory_id, branded_medicine_id -> quantity, …) и R6 (inventory_id -> facility_id) — R6 и R12 се одделни; нема транзитивност во R12.
     192По проверка на секоја релација R1..R26 утврдуваме дека ниедна од нив не содржи внатрешни транзитивни зависиности (сите транзитивни детерминанти се извлечени во посебни релации: Company, PaymentMethod, Users, Facility, BrandedMedicine итн.). Следствено, R1..R26 се во 3НФ и BCNF.
     193
     194== Финални релации во BCNF ==
     195**Company** { company_id, company_name, company_description, registration_number } - **BCNF**
     196**Medicine** { medicine_id, medicine_name, medicine_active_ingredient } - **BCNF**
     197**PaymentMethod** { payment_method_id, payment_method_name } - **BCNF**
     198**Users** { user_id, first_name, last_name, username, hashed_password, e_mail, gender, date_created, date_of_birth, is_account_non_expired, is_account_non_locked, is_credentials_non_expired, is_enabled, is_verified } - **BCNF**
     199**Facility** { facility_id, company_id, facility_name, facility_code } - **BCNF**
     200**Inventory** { inventory_id, facility_id } - **BCNF**
     201**BrandedMedicine** { branded_medicine_id, company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - **BCNF**
     202**BrandedMedicineImage** { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image } - **BCNF**
     203**ClubCard** { clubcard_id, user_id, club_program, points } - **BCNF**
     204**ContactInformation** { contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id } - **BCNF**
     205**HealthProfile** { healthprofile_id, user_id (улога: client), blood_type } - **BCNF**
     206**Inventory_BrandedMedicine** { inventory_id, branded_medicine_id, quantity, last_changed } - **BCNF**
     207**ShoppingCart** { shopping_cart_id, user_id (улога: client) } - **BCNF**
     208**ShoppingCart_BrandedMedicine** { shopping_cart_id, branded_medicine_id, cart_quantity } - **BCNF**
     209**ClientOrder** { client_order_id, user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price } - **BCNF**
     210**ClientOrder_BrandedMedicine** { client_order_id, branded_medicine_id, order_quantity } - **BCNF**
     211**Payment** { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status } - **BCNF**
     212**Prescription** { prescription_id, user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg } - **BCNF**
     213**SensitiveClientData** { sensitiveclientdata_id, user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status } - **BCNF**
     214**SupplyOrder** { supply_order_id, company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id } - **BCNF**
     215**SupplyOrder_BrandedMedicine** { supply_order_id, branded_medicine_id, supply_quantity } - **BCNF**
     216**Pharmacy_Catalog** { company_id (улога: pharmacy), branded_medicine_id } - **BCNF**
     217**Distributor_BrandedMedicine** { company_id (улога: distributor), branded_medicine_id } - **BCNF**
     218**Branded_Medicine_InstanceOf_Medicine** { branded_medicine_id, medicine_id } - **BCNF**
     219**MedicineInteraction** { medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity } - **BCNF**
     220**AllergicReaction_HealthProfile_Medicine** { healthprofile_id, medicine_id, date_diagnosed, allergic_description, allergic_severity } - **BCNF**
     221
     222Дополнителни релациите Company и Client ги поделив на подтипови кои ги рефернецираат id-то на нивните родители. Оваа поделба ја правиме за подобра контекстуализација, и овие ентитети (освен Client) не соддржат дополнителни аттрибути. Сите во BCNF:
     223
     224**Admins** { user_id }
     225**Pharmacist** { user_id }
     226**Client** { user_id, is_verified }
     227**DeliveryCompany** { company_id }
     228**Distributor** { company_id }
     229**Manufacturer** { company_id }
     230**Pharmacy** { company_id }