| 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 | **Лево** |
| | 40 | branded_medicine_image_id |
| | 41 | client_order_id |
| | 42 | clubcard_id |
| | 43 | company_id |
| | 44 | contactinformation_id |
| | 45 | facility_id |
| | 46 | healthprofile_id |
| | 47 | inventory_id |
| | 48 | medicine_id |
| | 49 | medicine_id_1 |
| | 50 | medicine_id_2 |
| | 51 | payment_id |
| | 52 | payment_method_id |
| | 53 | prescription_id |
| | 54 | sensitiveclientdata_id |
| | 55 | shopping_cart_id |
| | 56 | supply_order_id |
| | 57 | branded_medicine_id |
| | 58 | user_id |
| | 59 | |
| | 60 | **Лево и десно** |
| | 61 | company_id |
| | 62 | medicine_id |
| | 63 | payment_method_id |
| | 64 | user_id |
| | 65 | facility_id |
| | 66 | inventory_id |
| | 67 | branded_medicine_id |
| | 68 | payment_id |
| | 69 | |
| | 70 | **Десно** |
| | 71 | company_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НФ поради постоење на парцијални зависимости — некои примери се: |
| | 121 | quantity, last_changed зависат од (inventory_id, branded_medicine_id) — делумна зависност ако останат во големата релација. |
| | 122 | order_quantity зависи од (client_order_id, branded_medicine_id). |
| | 123 | cart_quantity зависи од (shopping_cart_id, branded_medicine_id). |
| | 124 | supply_quantity зависи од (supply_order_id, branded_medicine_id). |
| | 125 | mi_type/mi_description/mi_severity зависат од (medicine_id_1, medicine_id_2). |
| | 126 | |
| | 127 | == Декомпозиција во 2НФ == |
| | 128 | За да ги отстраниме парцијалните зависиности ги делиме атрибутите во релации каде не-клучните атрибути целосно зависат од нивниот клуч: |
| | 129 | company_id → company_name, company_description, registration_number |
| | 130 | medicine_id → medicine_name, medicine_active_ingredient |
| | 131 | payment_method_id → payment_method_name |
| | 132 | 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 (Client) |
| | 133 | facility_id → company_id, facility_name, facility_code |
| | 134 | inventory_id → facility_id |
| | 135 | branded_medicine_id → company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country |
| | 136 | branded_medicine_image_id → branded_medicine_id, branded_image, is_main_image |
| | 137 | clubcard_id → user_id, club_program, points |
| | 138 | contactinformation_id → phone, contact_address, contact_user_id, contact_facility_id |
| | 139 | healthprofile_id → user_id (улога: client), blood_type |
| | 140 | inventory_id, branded_medicine_id → quantity, last_changed |
| | 141 | client_order_id → user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price |
| | 142 | client_order_id, branded_medicine_id → order_quantity |
| | 143 | shopping_cart_id → user_id (улога: client) |
| | 144 | shopping_cart_id, branded_medicine_id → cart_quantity |
| | 145 | supply_order_id → company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id |
| | 146 | supply_order_id, branded_medicine_id → supply_quantity |
| | 147 | payment_id → user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status |
| | 148 | prescription_id → user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg |
| | 149 | sensitiveclientdata_id → user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status |
| | 150 | medicine_id_1, medicine_id_2 → mi_type, mi_description, mi_severity |
| | 151 | healthprofile_id, medicine_id → date_diagnosed, allergic_description, allergic_severity |
| | 152 | branded_medicine_id, medicine_id → (врска бранд->лек) |
| | 153 | company_id (улога: distributor), branded_medicine_id → (junction) |
| | 154 | company_id (улога: pharmacy), branded_medicine_id → (junction) |
| | 155 | |
| | 156 | Со ваква декомпозиција ги извлекуваме следните релации: |
| | 157 | R1 { company_id, company_name, company_description, registration_number } - **во BCNF** |
| | 158 | R2 { medicine_id, medicine_name, medicine_active_ingredient } - **во BCNF** |
| | 159 | R3 { payment_method_id, payment_method_name } - **во BCNF** |
| | 160 | R4 { 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** |
| | 161 | R5 { facility_id, company_id, facility_name, facility_code } - **во BCNF** |
| | 162 | R6 { inventory_id, facility_id } - **во BCNF** |
| | 163 | R7 { branded_medicine_id, company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - **во BCNF** |
| | 164 | R8 { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image } - **во BCNF** |
| | 165 | R9 { clubcard_id, user_id, club_program, points } - **во BCNF** |
| | 166 | R10 { contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id } - **во BCNF** |
| | 167 | R11 { healthprofile_id, user_id (улога: client), blood_type } - **во BCNF** |
| | 168 | R12 { inventory_id, branded_medicine_id, quantity, last_changed } - **во BCNF** |
| | 169 | R13 { client_order_id, user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price } - **во BCNF** |
| | 170 | R14 { client_order_id, branded_medicine_id, order_quantity } - **во BCNF** |
| | 171 | R15 { shopping_cart_id, user_id (улога: client) } - **во BCNF** |
| | 172 | R16 { shopping_cart_id, branded_medicine_id, cart_quantity } - **во BCNF** |
| | 173 | R17 { supply_order_id, company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id } - **во BCNF** |
| | 174 | R18 { supply_order_id, branded_medicine_id, supply_quantity } - **во BCNF** |
| | 175 | R19 { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status } - **во BCNF** |
| | 176 | R20 { prescription_id, user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg } - **во BCNF** |
| | 177 | R21 { sensitiveclientdata_id, user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status } - **во BCNF** |
| | 178 | R22 { medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity } - **во BCNF** |
| | 179 | R23 { healthprofile_id, medicine_id, date_diagnosed, allergic_description, allergic_severity } - **во BCNF** |
| | 180 | R24 { branded_medicine_id, medicine_id } (Branded_Medicine_InstanceOf_Medicine) - **во BCNF** |
| | 181 | R25 { company_id (улога: distributor), branded_medicine_id } (Distributor_BrandedMedicine) - **во BCNF** |
| | 182 | R26 { company_id (улога: pharmacy), branded_medicine_id } (Pharmacy_Catalog) - **во BCNF** |
| | 183 | |
| | 184 | |
| | 185 | Проверка на 3НФ (транзитивни зависиности) и финална декомпозиција. |
| | 186 | Сега ги проверуваме R1..R26 за транзитивни зависиности. Ако некаде постои транзитивност, ќе го декомпонираме дополнително. |
| | 187 | Проверка на најважните случаи: |
| | 188 | R7 (branded_medicine_id -> company_id (улога: manufacturer), …) — company_id е FK кон Company; Company е одвоена во R1, па нема транзитивна зависност во R7. R7 е во BCNF. |
| | 189 | R5 (facility_id -> company_id, …) — company_… се во R1; нема транзитивност во R5. |
| | 190 | R19 (payment_id -> payment_method_id, …) и R3 (payment_method_id -> payment_method_name) — се одделени: посебна релација за PaymentMethod (R3), а Payment држи само FK payment_method_id. Нема транзитивност во R19. |
| | 191 | R12 (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 } |