Version 8 (modified by 7 days ago) ( diff ) | ,
---|
Нормализација
Во нашата база ги имаме следните 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.
Следат функционалните зависимости (ФЗ) извлечени директно од дефинираните ентитети (левата страна е PK или композитен PK). За описните полиња кои имаат исто име во повеќе релации ќе ја ставиме името на релацијата или скратено име како превикс — на пример company_description, branded_description, mi_description, allergic_description... — ова е само за јасност во анализата;
Исто така за user_id и client_id во заграда ќе ја пишуваме нивната улога за подобро следење на контекстот на релациите.
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, is_verified facility_id -> company_id, facility_name, facility_code inventory_id -> facility_id medicine_id_1, medicine_id_2 -> mi_type, mi_description, mi_severity payment_id -> user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status prescription_id -> user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg sensitiveclientdata_id -> user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status shopping_cart_id -> user_id (улога: client) supply_order_id -> company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id branded_medicine_id -> company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country branded_medicine_image_id -> branded_medicine_id, branded_image, is_main_image clubcard_id -> user_id, club_program, points contactinformation_id -> phone, contact_address, contact_user_id, contact_facility_id healthprofile_id -> user_id (улога: client), blood_type inventory_id, branded_medicine_id -> quantity, last_changed client_order_id -> user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price client_order_id, branded_medicine_id -> order_quantity company_id (улога: pharmacy), branded_medicine_id -> / shopping_cart_id, branded_medicine_id -> cart_quantity supply_order_id, branded_medicine_id -> supply_quantity healthprofile_id, medicine_id -> date_diagnosed, allergic_description, allergic_severity branded_medicine_id, medicine_id -> / company_id (улога: distributor), branded_medicine_id -> /
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… }.
Лево branded_medicine_image_id client_order_id clubcard_id company_id contactinformation_id facility_id healthprofile_id inventory_id medicine_id medicine_id_1 medicine_id_2 payment_id payment_method_id prescription_id sensitiveclientdata_id shopping_cart_id supply_order_id branded_medicine_id user_id
Лево и десно company_id medicine_id payment_method_id user_id facility_id inventory_id branded_medicine_id payment_id
Десно 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.
Покривачи за атрибутите од „Лево“
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 } - Не ги содржи сите атрибути. 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 } - Не ги содржи сите атрибути. 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 } - Не ги содржи сите атрибути. company_id+ = { company_id, company_name, company_description, registration_number } - Не ги содржи сите атрибути. 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 } - Не ги содржи сите атрибути. facility_id+ = { facility_id, company_id, facility_name, facility_code, company_name, company_description, registration_number } - Не ги содржи сите атрибути. healthprofile_id+ = { healthprofile_id, user_id, blood_type, user_id, first_name, last_name, username } - Не ги содржи сите атрибути. inventory_id+ = { inventory_id, facility_id, facility_name, facility_code, company_id, company_name, company_description, registration_number } - Не ги содржи сите атрибути. medicine_id+ = { medicine_id, medicine_name, medicine_active_ingredient } - Не ги содржи сите атрибути. medicine_id_1+ = { medicine_id_1 } - Не ги содржи сите атрибути. medicine_id_2+ = { medicine_id_2 } - Не ги содржи сите атрибути. payment_id+ = { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status, payment_method_name } - Не ги содржи сите атрибути. payment_method_id+ = { payment_method_id, payment_method_name } - Не ги содржи сите атрибути. prescription_id+ = { prescription_id, user_id, medicine_id, issued_by, issued_at, valid_to, prescription_embg, medicine_name, medicine_active_ingredient } - Не ги содржи сите атрибути. sensitiveclientdata_id+ = { sensitiveclientdata_id, sensitive_embg, portrait_photo, verification_status, user_id, first_name, last_name } - Не ги содржи сите атрибути. shopping_cart_id+ = { shopping_cart_id, user_id, first_name, last_name } - Не ги содржи сите атрибути supply_order_id+ = { supply_order_id, supply_order_date, supply_expected_arrival_date, supply_status, facility_id, facility_name, company_id, company_name } - Не ги содржи сите атрибути. branded_medicine_id+ = { branded_medicine_id, company_id, branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - Не ги содржи сите атрибути. 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 } - Не ги содржи сите атрибути.
Kомбинирање на покривачите со цел да стигнеме до сите атрибути
{ 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. - Не ги содржи сите атрибути.
{ client_order_id, branded_medicine_id }+ додава: order_quantity, branded_name, branded_price, branded_description, dosage_form, strength, company_id, origin_country. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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. - Не ги содржи сите атрибути.
{ 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.
Со оваа последна комбинација добивме унија која ја покрива целата шема R. Задоволена е 1НФ. Меѓутоа, не е задоволена 2НФ поради постоење на парцијални зависимости — некои примери се: quantity, last_changed зависат од (inventory_id, branded_medicine_id) — делумна зависност ако останат во големата релација. order_quantity зависи од (client_order_id, branded_medicine_id). cart_quantity зависи од (shopping_cart_id, branded_medicine_id). supply_quantity зависи од (supply_order_id, branded_medicine_id). mi_type/mi_description/mi_severity зависат од (medicine_id_1, medicine_id_2).
Декомпозиција во 2НФ
За да ги отстраниме парцијалните зависиности ги делиме атрибутите во релации каде не-клучните атрибути целосно зависат од нивниот клуч: 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, is_verified (Client) facility_id → company_id, facility_name, facility_code inventory_id → facility_id branded_medicine_id → company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country branded_medicine_image_id → branded_medicine_id, branded_image, is_main_image clubcard_id → user_id, club_program, points contactinformation_id → phone, contact_address, contact_user_id, contact_facility_id healthprofile_id → user_id (улога: client), blood_type inventory_id, branded_medicine_id → quantity, last_changed client_order_id → user_id (улога: client), company_id (улога: delivery), payment_id, client_order_date, client_expected_arrival_date, client_order_status, total_price client_order_id, branded_medicine_id → order_quantity shopping_cart_id → user_id (улога: client) shopping_cart_id, branded_medicine_id → cart_quantity supply_order_id → company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id supply_order_id, branded_medicine_id → supply_quantity payment_id → user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status prescription_id → user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg sensitiveclientdata_id → user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status medicine_id_1, medicine_id_2 → mi_type, mi_description, mi_severity healthprofile_id, medicine_id → date_diagnosed, allergic_description, allergic_severity branded_medicine_id, medicine_id → (врска бранд->лек) company_id (улога: distributor), branded_medicine_id → (junction) company_id (улога: pharmacy), branded_medicine_id → (junction)
Со ваква декомпозиција ги извлекуваме следните релации: R1 { company_id, company_name, company_description, registration_number } - во BCNF R2 { medicine_id, medicine_name, medicine_active_ingredient } - во BCNF R3 { payment_method_id, payment_method_name } - во BCNF 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 R5 { facility_id, company_id, facility_name, facility_code } - во BCNF R6 { inventory_id, facility_id } - во BCNF R7 { branded_medicine_id, company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - во BCNF R8 { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image } - во BCNF R9 { clubcard_id, user_id, club_program, points } - во BCNF R10 { contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id } - во BCNF R11 { healthprofile_id, user_id (улога: client), blood_type } - во BCNF R12 { inventory_id, branded_medicine_id, quantity, last_changed } - во BCNF 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 R14 { client_order_id, branded_medicine_id, order_quantity } - во BCNF R15 { shopping_cart_id, user_id (улога: client) } - во BCNF R16 { shopping_cart_id, branded_medicine_id, cart_quantity } - во BCNF R17 { supply_order_id, company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id } - во BCNF R18 { supply_order_id, branded_medicine_id, supply_quantity } - во BCNF R19 { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status } - во BCNF R20 { prescription_id, user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg } - во BCNF R21 { sensitiveclientdata_id, user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status } - во BCNF R22 { medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity } - во BCNF R23 { healthprofile_id, medicine_id, date_diagnosed, allergic_description, allergic_severity } - во BCNF R24 { branded_medicine_id, medicine_id } (Branded_Medicine_InstanceOf_Medicine) - во BCNF R25 { company_id (улога: distributor), branded_medicine_id } (Distributor_BrandedMedicine) - во BCNF R26 { company_id (улога: pharmacy), branded_medicine_id } (Pharmacy_Catalog) - во BCNF
Проверка на 3НФ (транзитивни зависиности) и финална декомпозиција. Сега ги проверуваме R1..R26 за транзитивни зависиности. Ако некаде постои транзитивност, ќе го декомпонираме дополнително. Проверка на најважните случаи: R7 (branded_medicine_id -> company_id (улога: manufacturer), …) — company_id е FK кон Company; Company е одвоена во R1, па нема транзитивна зависност во R7. R7 е во BCNF. R5 (facility_id -> company_id, …) — company_… се во R1; нема транзитивност во R5. R19 (payment_id -> payment_method_id, …) и R3 (payment_method_id -> payment_method_name) — се одделени: посебна релација за PaymentMethod (R3), а Payment држи само FK payment_method_id. Нема транзитивност во R19. R12 (inventory_id, branded_medicine_id -> quantity, …) и R6 (inventory_id -> facility_id) — R6 и R12 се одделни; нема транзитивност во R12. По проверка на секоја релација R1..R26 утврдуваме дека ниедна од нив не содржи внатрешни транзитивни зависиности (сите транзитивни детерминанти се извлечени во посебни релации: Company, PaymentMethod, Users, Facility, BrandedMedicine итн.). Следствено, R1..R26 се во 3НФ и BCNF.
Финални релации во BCNF
Company { company_id, company_name, company_description, registration_number } - BCNF Medicine { medicine_id, medicine_name, medicine_active_ingredient } - BCNF PaymentMethod { payment_method_id, payment_method_name } - BCNF 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 Facility { facility_id, company_id, facility_name, facility_code } - BCNF Inventory { inventory_id, facility_id } - BCNF BrandedMedicine { branded_medicine_id, company_id (улога: manufacturer), branded_name, branded_price, branded_description, dosage_form, strength, origin_country } - BCNF BrandedMedicineImage { branded_medicine_image_id, branded_medicine_id, branded_image, is_main_image } - BCNF ClubCard { clubcard_id, user_id, club_program, points } - BCNF ContactInformation { contactinformation_id, phone, contact_address, contact_user_id, contact_facility_id } - BCNF HealthProfile { healthprofile_id, user_id (улога: client), blood_type } - BCNF Inventory_BrandedMedicine { inventory_id, branded_medicine_id, quantity, last_changed } - BCNF ShoppingCart { shopping_cart_id, user_id (улога: client) } - BCNF ShoppingCart_BrandedMedicine { shopping_cart_id, branded_medicine_id, cart_quantity } - BCNF 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 ClientOrder_BrandedMedicine { client_order_id, branded_medicine_id, order_quantity } - BCNF Payment { payment_id, user_id (улога: client), payment_method_id, payment_date, payment_amount, payment_status } - BCNF Prescription { prescription_id, user_id (улога: client), medicine_id, issued_by, issued_at, valid_to, prescription_embg } - BCNF SensitiveClientData { sensitiveclientdata_id, user_id (улога: client), user_id (улога: pharmacist), sensitive_embg, portrait_photo, verification_status } - BCNF SupplyOrder { supply_order_id, company_id (улога: distributor), company_id (улога: pharmacy), supply_order_date, supply_expected_arrival_date, supply_status, facility_id } - BCNF SupplyOrder_BrandedMedicine { supply_order_id, branded_medicine_id, supply_quantity } - BCNF Pharmacy_Catalog { company_id (улога: pharmacy), branded_medicine_id } - BCNF Distributor_BrandedMedicine { company_id (улога: distributor), branded_medicine_id } - BCNF Branded_Medicine_InstanceOf_Medicine { branded_medicine_id, medicine_id } - BCNF MedicineInteraction { medicine_id_1, medicine_id_2, mi_type, mi_description, mi_severity } - BCNF AllergicReaction_HealthProfile_Medicine { healthprofile_id, medicine_id, date_diagnosed, allergic_description, allergic_severity } - BCNF
Дополнителни релациите Company и Client ги поделив на подтипови кои ги рефернецираат id-то на нивните родители. Оваа поделба ја правиме за подобра контекстуализација, и овие ентитети (освен Client) не соддржат дополнителни аттрибути. Сите во BCNF:
Admins { user_id } Pharmacist { user_id } Client { user_id, is_verified } DeliveryCompany { company_id } Distributor { company_id } Manufacturer { company_id } Pharmacy { company_id }