| 11 | | * id → user_id, high_school_id, contact_id, major_id, semester_id, subject_id, enrolled_id, sem_subject_id, passed_id, document_id, token_id, payment_id |
| 12 | | * name → user_name, major_name, subject_name |
| 13 | | * type → hs_type, semester_type, document_type |
| 14 | | * created_at → user_created_at, enrolled_created_at |
| 15 | | * number → phone_number, index → index_no, body → document_body, cost → document_cost, token → token_value, quota → quota (на корисник) и enrolled_quota (на запишан семестар) |
| 16 | | * улогите на professor се разликуваат: professor_id (професор на конкретен запишан предмет) и teaching_prof_id (професор во распоредот по семестар) |
| 17 | | * dependency_id → prerequisite_id (предметот кој е предуслов) |
| | 11 | || '''Изворно име''' || '''Добива име во R''' || |
| | 12 | || id || user_id, high_school_id, contact_id, major_id, semester_id, subject_id, enrolled_id, sem_subject_id, passed_id, document_id, token_id, payment_id || |
| | 13 | || name || user_name, major_name, subject_name || |
| | 14 | || type || hs_type, semester_type, document_type || |
| | 15 | || created_at || user_created_at, enrolled_created_at || |
| | 16 | || number || phone_number || |
| | 17 | || index || index_no || |
| | 18 | || body || document_body || |
| | 19 | || cost || document_cost || |
| | 20 | || token || token_value || |
| | 21 | || quota || quota (на корисник) и enrolled_quota (на запишан семестар) || |
| | 22 | || professor || professor_id (професор на конкретен запишан предмет) и teaching_prof_id (професор во распоредот по семестар) || |
| | 23 | || dependency_id || prerequisite_id (предметот кој е предуслов) || |
| | 24 | |
| | 25 | '''Забелешка:''' табелата погоре е само преименување на атрибути заради избегнување |
| | 26 | двосмисленост во имињата, а '''не''' множество функционални зависности. Затоа |
| | 27 | тука намерно не е користена стрелката →, која во останатиот дел од страната секогаш |
| | 28 | значи функционална зависност. |
| | 132 | === Проверка на затворачот на секој кандидат клуч |
| | 133 | |
| | 134 | За секое CK''i'' се пресметува затворачот CK''i''^+^ и се проверува дали |
| | 135 | CK''i''^+^ = R, односно дали ги покрива сите 57 атрибути. Се користи стандардниот |
| | 136 | алгоритам: се тргнува од самото множество и се применува FD чија лева страна е |
| | 137 | веќе содржана, сè додека има промена. |
| | 138 | |
| | 139 | Заедничкиот дел за сите пет клучеви е K^+^, кој беше пресметан погоре и содржи 45 |
| | 140 | атрибути. Затоа за секој CK''i'' се прикажува само што се додава над K^+^, |
| | 141 | односно дали се добиваат сите 12 атрибути кои недостасуваат во K^+^. |
| | 142 | |
| | 143 | '''CK1^+^ = (K ∪ { subject_id })^+^''' |
| | 144 | |
| | 145 | 1. Почетно: K ∪ { subject_id } |
| | 146 | 2. Сите чекори од пресметката на K^+^ важат и тука ⇒ вкупно 45 атрибути + subject_id = 46 |
| | 147 | 3. FD10: subject_id → subject_name, subject_code, awarded_credits, dependency_credit ⇒ вкупно 50 |
| | 148 | 4. FD16: (enrolled_id, subject_id) → sem_subject_id ''(enrolled_id е добиен преку FD21)'' ⇒ вкупно 51 |
| | 149 | 5. FD15: sem_subject_id → professor_id, signature ⇒ вкупно 53 |
| | 150 | 6. FD18: sem_subject_id → passed_id, grade, date_passed ⇒ вкупно 56 |
| | 151 | 7. FD22: (major_id, subject_id) → mandatory_semester ''(major_id е добиен преку FD13)'' ⇒ вкупно 57 |
| | 152 | |
| | 153 | '''CK1^+^ = R (57/57)''' ⇒ CK1 е суперклуч. |
| | 154 | |
| | 155 | '''CK2^+^ = (K ∪ { sem_subject_id })^+^''' |
| | 156 | |
| | 157 | 1. Почетно: K ∪ { sem_subject_id }, плус чекорите на K^+^ ⇒ вкупно 46 |
| | 158 | 2. FD15: sem_subject_id → enrolled_id, subject_id, professor_id, signature ⇒ вкупно 48 ''(enrolled_id веќе е во K^+^)'' |
| | 159 | 3. FD10: subject_id → subject_name, subject_code, awarded_credits, dependency_credit ⇒ вкупно 52 |
| | 160 | 4. FD18: sem_subject_id → passed_id, grade, date_passed ⇒ вкупно 55 |
| | 161 | 5. FD22: (major_id, subject_id) → mandatory_semester ⇒ вкупно 56 |
| | 162 | 6. Останува уште sem_subject_id самиот, кој е во почетното множество ⇒ вкупно 57 |
| | 163 | |
| | 164 | '''CK2^+^ = R (57/57)''' ⇒ CK2 е суперклуч. |
| | 165 | |
| | 166 | '''CK3^+^ = (K ∪ { passed_id })^+^''' |
| | 167 | |
| | 168 | 1. Почетно: K ∪ { passed_id }, плус чекорите на K^+^ ⇒ вкупно 46 |
| | 169 | 2. FD17: passed_id → sem_subject_id, grade, date_passed ⇒ вкупно 49 |
| | 170 | 3. FD15: sem_subject_id → enrolled_id, subject_id, professor_id, signature ⇒ вкупно 52 |
| | 171 | 4. FD10: subject_id → subject_name, subject_code, awarded_credits, dependency_credit ⇒ вкупно 56 |
| | 172 | 5. FD22: (major_id, subject_id) → mandatory_semester ⇒ вкупно 57 |
| | 173 | |
| | 174 | '''CK3^+^ = R (57/57)''' ⇒ CK3 е суперклуч. |
| | 175 | |
| | 176 | '''CK4^+^ = (K ∪ { subject_code })^+^''' |
| | 177 | |
| | 178 | 1. Почетно: K ∪ { subject_code }, плус чекорите на K^+^ ⇒ вкупно 46 |
| | 179 | 2. FD12: subject_code → subject_id ⇒ вкупно 47 |
| | 180 | 3. Од чекор 3 натаму пресметката е идентична со CK1 ⇒ вкупно 57 |
| | 181 | |
| | 182 | '''CK4^+^ = R (57/57)''' ⇒ CK4 е суперклуч. |
| | 183 | |
| | 184 | '''CK5^+^ = (K ∪ { subject_name })^+^''' |
| | 185 | |
| | 186 | 1. Почетно: K ∪ { subject_name }, плус чекорите на K^+^ ⇒ вкупно 46 |
| | 187 | 2. FD11: subject_name → subject_id ⇒ вкупно 47 |
| | 188 | 3. Од чекор 3 натаму пресметката е идентична со CK1 ⇒ вкупно 57 |
| | 189 | |
| | 190 | '''CK5^+^ = R (57/57)''' ⇒ CK5 е суперклуч. |
| | 191 | |
| | 192 | === Проверка на минималноста |
| | 193 | |
| | 194 | Суперклучот е кандидат клуч само ако ниту едно негово вистинско подмножество не е |
| | 195 | суперклуч. За секој CK''i'' = K ∪ { X } се проверуваат двата случаја: |
| | 196 | |
| | 197 | * '''Отстранување на X''': останува K, а веќе е покажано дека K^+^ има 45 < 57 атрибути. Значи K не е суперклуч и X е неопходен. |
| | 198 | * '''Отстранување на било кој атрибут од K''': петте атрибути document_id, token_id, payment_id, prerequisite_id и teaching_prof_id се појавуваат '''само на лева страна''' во сите FD1-FD25. Атрибут кој никогаш не стои десно не може да се изведе од ниту една зависност, па мора да припаѓа на секој суперклуч. Значи ниту еден од нив не смее да се отстрани. |
| | 199 | |
| | 200 | Според тоа сите пет множества се '''минимални суперклучеви''', односно кандидат клучеви. |
| | 201 | |
| | 202 | === Проверка дека нема други кандидат клучеви |
| | 203 | |
| | 204 | Секој кандидат клуч мора да го содржи K (петте само-лево атрибути) и не смее да |
| | 205 | содржи ниту еден од 38-те само-десно атрибути. Останува да се провери само кои од |
| | 206 | 14-те двострани атрибути можат да го дополнат K. |
| | 207 | |
| | 208 | Девет од нив '''веќе се содржани во K^+^''': contact_id, email, enrolled_id, |
| | 209 | high_school_id, major_id, semester_id, semester_type, user_id, year. Ако |
| | 210 | атрибутот A е во K^+^, тогаш (K ∪ {A})^+^ = K^+^, што има 45 атрибути, па таквото |
| | 211 | множество не е суперклуч. |
| | 212 | |
| | 213 | Преостануваат точно петте кои не се во K^+^ и водат до предметот: subject_id, |
| | 214 | sem_subject_id, passed_id, subject_code, subject_name - тоа се CK1-CK5. Секое |
| | 215 | множество со два или повеќе додадени атрибути го содржи некој од нив, па не е |
| | 216 | минимално. |
| | 217 | |
| | 218 | Заклучок: релацијата R има '''точно 5 кандидат клучеви''', сите со големина 6. |
| | 219 | |
| | 236 | |
| | 237 | == Критериум за спојување без загуба |
| | 238 | |
| | 239 | Секоја декомпозиција подолу дели една релација R''i'' на точно две релации, A и B. |
| | 240 | За секоја од нив експлицитно се наведува: |
| | 241 | |
| | 242 | 1. '''по кои атрибути се спојуваат''', односно пресекот A ∩ B; |
| | 243 | 2. '''на која од двете релации тој пресек е (супер)клуч'''. |
| | 244 | |
| | 245 | Користен е критериумот на Хит (''Heath''): декомпозицијата на R''i'' на A и B е |
| | 246 | без загуба ако и само ако важи |
| | 247 | |
| | 248 | (A ∩ B) → A '''или''' (A ∩ B) → B |
| | 249 | |
| | 250 | односно ако заедничките атрибути се суперклуч на барем едната од двете релации. |
| | 251 | Тогаш A ⋈ B = R''i'', при што спојувањето е природно спојување по '''целиот''' |
| | 252 | пресек A ∩ B, а не по произволен атрибут. |
| | 253 | |
| | 254 | Кај 4НФ функционалната зависност не е доволна, па таму се користи проширениот |
| | 255 | критериум: декомпозицијата е без загуба ако важи повеќевредносната зависност |
| | 256 | (A ∩ B) ↠ A, односно (A ∩ B) ↠ B. |
| | 257 | |
| | 258 | Во целата постапка секој чекор ја дели тековната релација R''i'' на новоиздвоената |
| | 259 | релација и остатокот R''i+1'', па конечната шема се реконструира со редоследно |
| | 260 | спојување наназад: |
| | 261 | |
| | 262 | R = R1 ⋈ Documents = R2 ⋈ Token ⋈ Documents = … = R13 ⋈ (сите издвоени релации) |
| 324 | | * Users - детерминанти user_id и email, обата се кандидат клучеви → БКНФ |
| 325 | | * !HighSchool - детерминанти high_school_id и user_id, обата се кандидат клучеви → БКНФ |
| 326 | | * Contact - детерминанти contact_id и user_id, обата се кандидат клучеви → БКНФ |
| 327 | | * Major - детерминанта major_id → БКНФ |
| 328 | | * !ActiveSemesters - детерминанти semester_id и (year, semester_type) → БКНФ |
| 329 | | * Subjects - детерминанти subject_id, subject_name, subject_code, сите кандидат клучеви → БКНФ |
| 330 | | * !EnrolledSemesters - детерминанти enrolled_id и (user_id, semester_id) → БКНФ |
| 331 | | * !SemestersSubjects - детерминанти sem_subject_id и (enrolled_id, subject_id) → БКНФ |
| 332 | | * !PassedSubjects - детерминанти passed_id и sem_subject_id → БКНФ |
| 333 | | * Documents - детерминанта document_id → БКНФ |
| 334 | | * Token - детерминанта token_id → БКНФ |
| 335 | | * Payment - детерминанта payment_id → БКНФ |
| 336 | | * !MajorSubjects - детерминанта (major_id, subject_id) → БКНФ |
| | 450 | * Users - детерминанти user_id и email, обата се кандидат клучеви ⇒ БКНФ |
| | 451 | * !HighSchool - детерминанти high_school_id и user_id, обата се кандидат клучеви ⇒ БКНФ |
| | 452 | * Contact - детерминанти contact_id и user_id, обата се кандидат клучеви ⇒ БКНФ |
| | 453 | * Major - детерминанта major_id ⇒ БКНФ |
| | 454 | * !ActiveSemesters - детерминанти semester_id и (year, semester_type) ⇒ БКНФ |
| | 455 | * Subjects - детерминанти subject_id, subject_name, subject_code, сите кандидат клучеви ⇒ БКНФ |
| | 456 | * !EnrolledSemesters - детерминанти enrolled_id и (user_id, semester_id) ⇒ БКНФ |
| | 457 | * !SemestersSubjects - детерминанти sem_subject_id и (enrolled_id, subject_id) ⇒ БКНФ |
| | 458 | * !PassedSubjects - детерминанти passed_id и sem_subject_id ⇒ БКНФ |
| | 459 | * Documents - детерминанта document_id ⇒ БКНФ |
| | 460 | * Token - детерминанта token_id ⇒ БКНФ |
| | 461 | * Payment - детерминанта payment_id ⇒ БКНФ |
| | 462 | * !MajorSubjects - детерминанта (major_id, subject_id) ⇒ БКНФ |
| 373 | | * '''!UserDocuments'''(''__user_id__'', ''__document_id__'') - од FD23 |
| 374 | | * '''!DependencySubject'''(''__subject_id__'', ''__prerequisite_id__'') - од FD24 |
| 375 | | * '''!ProfessourSubjects'''(''__teaching_prof_id__'', ''__semester_id__'', ''__subject_id__'') - од FD25 |
| 376 | | |
| 377 | | Останатите идентификатори од R13 (high_school_id, contact_id, major_id, |
| 378 | | enrolled_id, sem_subject_id, passed_id, token_id, payment_id) веќе се примарни |
| 379 | | клучеви во претходно издвоените релации, па не формираат нова релација. |
| 380 | | |
| 381 | | * ''Lossless join'': спојување по заедничките атрибути ја враќа R13. |
| 382 | | * ''Dependency preservation'': трите нови релации не носат функционални зависности, туку само врски. |
| | 507 | === Чекор 1 - издвојување по MVD1 |
| | 508 | |
| | 509 | '''!UserDocuments'''(''__user_id__'', ''__document_id__'') - од FD23 |
| | 510 | |
| | 511 | R13a = R13 − { document_id } |
| | 512 | |
| | 513 | * ''Lossless join'': '''R13 = !UserDocuments ⋈ R13a''', спојување по '''!UserDocuments ∩ R13a = { user_id }'''. Пресекот не е клуч на ниту една од двете, но важи MVD1: user_id ↠ document_id, односно множеството документи што ги побарал еден корисник не зависи од ниту еден друг атрибут во R13a. Според критериумот за 4НФ (A ∩ B) ↠ A, па спојувањето е без загуба. |
| | 514 | |
| | 515 | === Чекор 2 - издвојување по MVD2 |
| | 516 | |
| | 517 | '''!DependencySubject'''(''__subject_id__'', ''__prerequisite_id__'') - од FD24 |
| | 518 | |
| | 519 | R13b = R13a − { prerequisite_id } |
| | 520 | |
| | 521 | * ''Lossless join'': '''R13a = !DependencySubject ⋈ R13b''', спојување по '''!DependencySubject ∩ R13b = { subject_id }'''. Важи MVD2: subject_id ↠ prerequisite_id, бидејќи предусловите на еден предмет се исти без оглед на тоа кој студент го запишал. Значи (A ∩ B) ↠ A и спојувањето е без загуба. |
| | 522 | |
| | 523 | === Чекор 3 - издвојување по MVD3 |
| | 524 | |
| | 525 | '''!ProfessourSubjects'''(''__teaching_prof_id__'', ''__semester_id__'', ''__subject_id__'') - од FD25 |
| | 526 | |
| | 527 | R13c = R13b − { teaching_prof_id } |
| | 528 | |
| | 529 | * ''Lossless join'': '''R13b = !ProfessourSubjects ⋈ R13c''', спојување по '''!ProfessourSubjects ∩ R13c = { semester_id, subject_id }'''. Важи MVD3: (semester_id, subject_id) ↠ teaching_prof_id, бидејќи распоредот кој професор предава кој предмет во кој семестар е независен од конкретното запишување. Значи (A ∩ B) ↠ A и спојувањето е без загуба. |
| | 530 | |
| | 531 | === Преостанатата релација |
| | 532 | |
| | 533 | R13c = { user_id, high_school_id, contact_id, major_id, semester_id, subject_id, |
| | 534 | enrolled_id, sem_subject_id, passed_id, token_id, payment_id } |
| | 535 | |
| | 536 | R13c '''не се задржува''' како посебна релација, бидејќи не носи нова информација. |
| | 537 | Секој нејзин атрибут е функционално определен од друг атрибут кој веќе постои во |
| | 538 | некоја од издвоените релации: |
| | 539 | |
| | 540 | * token_id → user_id (FD20), веќе во '''Token''' |
| | 541 | * payment_id → enrolled_id (FD21), веќе во '''Payment''' |
| | 542 | * enrolled_id → user_id, major_id, semester_id (FD13), веќе во '''!EnrolledSemesters''' |
| | 543 | * sem_subject_id → enrolled_id, subject_id (FD15), веќе во '''!SemestersSubjects''' |
| | 544 | * passed_id → sem_subject_id (FD17), веќе во '''!PassedSubjects''' |
| | 545 | * user_id → high_school_id, contact_id (FD3, FD5), веќе во '''!HighSchool''' и '''Contact''' |
| | 546 | |
| | 547 | Значи R13c = π(Token ⋈ Payment ⋈ !EnrolledSemesters ⋈ !SemestersSubjects ⋈ |
| | 548 | !PassedSubjects ⋈ !HighSchool ⋈ Contact), при што секое спојување е по атрибут кој |
| | 549 | е клуч на едната страна. Затоа нејзиното отстранување е без загуба на информација. |
| | 550 | |
| | 551 | * ''Dependency preservation'': трите нови релации не носат функционални зависности, туку само врски, па ниту една FD не се губи со оваа декомпозиција. |
| | 577 | === Преглед на спојувањата |
| | 578 | |
| | 579 | Табелата ги сумира сите спојувања со кои се реконструира првичната релација R. |
| | 580 | Колоната ''Клуч на'' покажува на која релација заедничките атрибути се |
| | 581 | (супер)клуч, што е услов за спојување без загуба. |
| | 582 | |
| | 583 | || '''Релација A''' || '''Релација B''' || '''Спојување по (A ∩ B)''' || '''Клуч на''' || '''Основа''' || |
| | 584 | || Documents || R1 || document_id || Documents || FD19 || |
| | 585 | || Token || R2 || token_id, user_id || Token || FD20 || |
| | 586 | || Payment || R3 || payment_id, enrolled_id || Payment || FD21 || |
| | 587 | || Subjects || R4 || subject_id || Subjects || FD10 || |
| | 588 | || Users || R5 || user_id || Users || FD1 || |
| | 589 | || !HighSchool || R6 || high_school_id, user_id || !HighSchool || FD3, FD4 || |
| | 590 | || Contact || R7 || contact_id, user_id || Contact || FD5, FD6 || |
| | 591 | || !EnrolledSemesters || R8 || enrolled_id, user_id, major_id, semester_id || !EnrolledSemesters || FD13 || |
| | 592 | || Major || R9 || major_id || Major || FD7 || |
| | 593 | || !ActiveSemesters || R10 || semester_id || !ActiveSemesters || FD8 || |
| | 594 | || !SemestersSubjects || R11 || sem_subject_id, enrolled_id, subject_id || !SemestersSubjects || FD15 || |
| | 595 | || !PassedSubjects || R12 || passed_id, sem_subject_id || !PassedSubjects || FD17, FD18 || |
| | 596 | || !MajorSubjects || R13 || major_id, subject_id || !MajorSubjects || FD22 || |
| | 597 | || !UserDocuments || R13a || user_id || ''(MVD)'' || MVD1 || |
| | 598 | || !DependencySubject || R13b || subject_id || ''(MVD)'' || MVD2 || |
| | 599 | || !ProfessourSubjects || R13c || semester_id, subject_id || ''(MVD)'' || MVD3 || |
| | 600 | |
| | 601 | Кај првите тринаесет редови важи функционалната зависност (A ∩ B) → A, а кај |
| | 602 | последните три повеќевредносната (A ∩ B) ↠ A, што е условот за 4НФ. |
| | 603 | |