| | 1 | == Нормализација |
| | 2 | |
| | 3 | == Денормализирана форма на базата |
| | 4 | |
| | 5 | Постапката започнува од една единствена денормализирана релација '''R''' која ги |
| | 6 | содржи сите атрибути од ЕР моделот, како целата база да е сместена во една табела. |
| | 7 | |
| | 8 | Бидејќи во моделот повеќе ентитети имаат атрибут со исто име (id, name, type, |
| | 9 | created_at), атрибутите се преименувани така што во R нема две исти имиња: |
| | 10 | |
| | 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 (предметот кој е предуслов) |
| | 18 | |
| | 19 | '''R''' = { user_id, user_name, embg, surname, index_no, bday, email, password, |
| | 20 | role, quota, enrollment_year, user_created_at, high_school_id, gpa, hs_type, |
| | 21 | contact_id, city, municipality, address, phone_number, microsoft_email, major_id, |
| | 22 | major_name, semester_id, year, semester_type, subject_id, subject_name, |
| | 23 | subject_code, awarded_credits, dependency_credit, enrolled_id, enrolled_quota, |
| | 24 | note, student_comment, enrolled_created_at, last_change, completed, |
| | 25 | sem_subject_id, professor_id, signature, passed_id, grade, date_passed, |
| | 26 | document_id, document_type, document_body, document_cost, token_id, token_value, |
| | 27 | expires_at, is_valid, payment_id, amount, mandatory_semester, prerequisite_id, |
| | 28 | teaching_prof_id } |
| | 29 | |
| | 30 | Вкупно '''|R| = 57''' атрибути. |
| | 31 | |
| | 32 | == Функционални зависности |
| | 33 | |
| | 34 | Даден е каноничкиот покривач на множеството функционални зависности кои важат во R: |
| | 35 | |
| | 36 | * '''FD1''': user_id → user_name, embg, surname, index_no, bday, email, password, role, quota, enrollment_year, user_created_at |
| | 37 | * '''FD2''': email → user_id |
| | 38 | * '''FD3''': user_id → high_school_id |
| | 39 | * '''FD4''': high_school_id → user_id, gpa, hs_type |
| | 40 | * '''FD5''': user_id → contact_id |
| | 41 | * '''FD6''': contact_id → user_id, city, municipality, address, phone_number, microsoft_email |
| | 42 | * '''FD7''': major_id → major_name |
| | 43 | * '''FD8''': semester_id → year, semester_type |
| | 44 | * '''FD9''': (year, semester_type) → semester_id |
| | 45 | * '''FD10''': subject_id → subject_name, subject_code, awarded_credits, dependency_credit |
| | 46 | * '''FD11''': subject_name → subject_id |
| | 47 | * '''FD12''': subject_code → subject_id |
| | 48 | * '''FD13''': enrolled_id → user_id, enrolled_quota, major_id, note, student_comment, enrolled_created_at, last_change, completed, semester_id |
| | 49 | * '''FD14''': (user_id, semester_id) → enrolled_id |
| | 50 | * '''FD15''': sem_subject_id → enrolled_id, subject_id, professor_id, signature |
| | 51 | * '''FD16''': (enrolled_id, subject_id) → sem_subject_id |
| | 52 | * '''FD17''': passed_id → sem_subject_id, grade, date_passed |
| | 53 | * '''FD18''': sem_subject_id → passed_id, grade, date_passed |
| | 54 | * '''FD19''': document_id → document_type, document_body, document_cost |
| | 55 | * '''FD20''': token_id → user_id, token_value, expires_at, is_valid |
| | 56 | * '''FD21''': payment_id → user_id, enrolled_id, amount |
| | 57 | * '''FD22''': (major_id, subject_id) → mandatory_semester |
| | 58 | |
| | 59 | Следните комбинации не определуваат ниту еден атрибут, односно претставуваат чисти |
| | 60 | врски (сите атрибути се дел од клучот): |
| | 61 | |
| | 62 | * '''FD23''': (user_id, document_id) → ∅ |
| | 63 | * '''FD24''': (subject_id, prerequisite_id) → ∅ |
| | 64 | * '''FD25''': (teaching_prof_id, semester_id, subject_id) → ∅ |
| | 65 | |
| | 66 | Зависностите FD2, FD9, FD11, FD12, FD14, FD16 и FD17 произлегуваат од UNIQUE |
| | 67 | ограничувањата, а FD4 и FD6 од тоа што врските се 1:1. |
| | 68 | |
| | 69 | == Кандидат клучеви и примарен клуч |
| | 70 | |
| | 71 | '''Атрибути кои се појавуваат само лево''' (мора да бидат дел од секој кандидат клуч): |
| | 72 | |
| | 73 | document_id, token_id, payment_id, prerequisite_id, teaching_prof_id |
| | 74 | |
| | 75 | '''Атрибути кои се појавуваат само десно''' (не можат да бидат дел од кандидат клуч), 38 атрибути: |
| | 76 | |
| | 77 | address, amount, awarded_credits, bday, city, completed, date_passed, |
| | 78 | dependency_credit, document_body, document_cost, document_type, embg, |
| | 79 | enrolled_created_at, enrolled_quota, enrollment_year, expires_at, gpa, grade, |
| | 80 | hs_type, index_no, is_valid, last_change, major_name, mandatory_semester, |
| | 81 | microsoft_email, municipality, note, password, phone_number, professor_id, |
| | 82 | quota, role, signature, student_comment, surname, token_value, user_created_at, |
| | 83 | user_name |
| | 84 | |
| | 85 | '''Атрибути кои се појавуваат и лево и десно''' (кандидати за дополнување на клучот), 14 атрибути: |
| | 86 | |
| | 87 | contact_id, email, enrolled_id, high_school_id, major_id, passed_id, |
| | 88 | sem_subject_id, semester_id, semester_type, subject_code, subject_id, |
| | 89 | subject_name, user_id, year |
| | 90 | |
| | 91 | === Покривач на јадрото |
| | 92 | |
| | 93 | Нека '''K''' = { document_id, token_id, payment_id, prerequisite_id, teaching_prof_id }. |
| | 94 | |
| | 95 | '''K+''' содржи 45 од вкупно 57 атрибути. Не се добиваат: |
| | 96 | |
| | 97 | awarded_credits, date_passed, dependency_credit, grade, mandatory_semester, |
| | 98 | passed_id, professor_id, sem_subject_id, signature, subject_code, subject_id, |
| | 99 | subject_name |
| | 100 | |
| | 101 | Значи K сам по себе '''не е суперклуч'''. Причината е што ниту еден од атрибутите |
| | 102 | во K не води до предметот: до sem_subject_id се стигнува само преку |
| | 103 | (enrolled_id, subject_id) со FD16 или преку passed_id со FD17, а subject_id не се |
| | 104 | добива од ниту една зависност чија лева страна е во K+. |
| | 105 | |
| | 106 | === Кандидат клучеви |
| | 107 | |
| | 108 | Со додавање на еден атрибут од двостраните на K се добиваат следните минимални |
| | 109 | суперклучеви, односно кандидат клучеви: |
| | 110 | |
| | 111 | * '''CK1''' = K ∪ { subject_id } |
| | 112 | * '''CK2''' = K ∪ { sem_subject_id } |
| | 113 | * '''CK3''' = K ∪ { passed_id } |
| | 114 | * '''CK4''' = K ∪ { subject_code } |
| | 115 | * '''CK5''' = K ∪ { subject_name } |
| | 116 | |
| | 117 | CK4 и CK5 постојат затоа што subject_code и subject_name се UNIQUE, па се |
| | 118 | алтернативни идентификатори на предметот. CK2 и CK3 постојат затоа што |
| | 119 | sem_subject_id и passed_id се во однос 1:1 и секој од нив води до subject_id. |
| | 120 | |
| | 121 | '''Избран примарен клуч:''' |
| | 122 | |
| | 123 | PK = { document_id, token_id, payment_id, prerequisite_id, teaching_prof_id, subject_id } |
| | 124 | |
| | 125 | Избран е CK1 бидејќи subject_id е природниот идентификатор на предметот, додека |
| | 126 | sem_subject_id и passed_id се идентификатори на врски кои постојат само ако |
| | 127 | студентот го запишал, односно положил предметот. |
| | 128 | |
| | 129 | === Проверка во која нормална форма е R |
| | 130 | |
| | 131 | Релацијата R ја задоволува '''1НФ''': сите атрибути се атомични, нема |
| | 132 | повеќевредносни атрибути ниту повторувачки групи, и секоја редица е определена со PK. |
| | 133 | |
| | 134 | R '''не ја задоволува 2НФ''', бидејќи постојат парцијални зависности - атрибути кои |
| | 135 | зависат од дел од примарниот клуч, а не од целиот. На пример document_id → |
| | 136 | document_type, каде document_id е само еден дел од PK. |
| | 137 | |
| | 138 | == 1НФ декомпозиција |
| | 139 | |
| | 140 | Не е потребна декомпозиција. R е веќе во 1НФ: секој атрибут има атомична вредност |
| | 141 | од единствен домен, нема повторувачки групи и секоја редица е уникатно определена |
| | 142 | со примарниот клуч. |
| | 143 | |
| | 144 | == 2НФ декомпозиција |
| | 145 | |
| | 146 | '''Анализирана релација:''' R, PK = { document_id, token_id, payment_id, prerequisite_id, teaching_prof_id, subject_id } |
| | 147 | |
| | 148 | '''Парцијални зависности''' (лева страна е вистински подмножество на PK): |
| | 149 | |
| | 150 | * FD19: document_id → document_type, document_body, document_cost |
| | 151 | * FD20: token_id → token_value, expires_at, is_valid |
| | 152 | * FD21: payment_id → amount |
| | 153 | * FD10: subject_id → subject_name, subject_code, awarded_credits, dependency_credit |
| | 154 | |
| | 155 | Секоја од нив се издвојува во посебна релација. Атрибутите кои се клучеви или се |
| | 156 | потребни за поврзување остануваат и во преостанатата релација. |
| | 157 | |
| | 158 | === Декомпозиција по FD19 |
| | 159 | |
| | 160 | '''Documents'''(''__document_id__'', document_type, document_body, document_cost) |
| | 161 | |
| | 162 | R1 = R − { document_type, document_body, document_cost } |
| | 163 | |
| | 164 | * Клуч: document_id |
| | 165 | * ''Lossless join'': спојувањето по document_id ја реконструира R, бидејќи document_id е клуч на Documents. |
| | 166 | * ''Dependency preservation'': FD19 е сочувана во Documents. |
| | 167 | |
| | 168 | === Декомпозиција по FD20 |
| | 169 | |
| | 170 | '''Token'''(''__token_id__'', user_id, token_value, expires_at, is_valid) |
| | 171 | |
| | 172 | R2 = R1 − { token_value, expires_at, is_valid } |
| | 173 | |
| | 174 | * Клуч: token_id |
| | 175 | * ''Lossless join'': спојување по token_id; token_id е клуч на Token. |
| | 176 | * ''Dependency preservation'': FD20 е сочувана во Token. |
| | 177 | |
| | 178 | === Декомпозиција по FD21 |
| | 179 | |
| | 180 | '''Payment'''(''__payment_id__'', enrolled_id, amount) |
| | 181 | |
| | 182 | R3 = R2 − { amount } |
| | 183 | |
| | 184 | * Клуч: payment_id |
| | 185 | * ''Lossless join'': спојување по payment_id. |
| | 186 | * ''Dependency preservation'': FD21 е сочувана во Payment. |
| | 187 | * '''Забелешка:''' атрибутот user_id намерно '''не''' е дел од Payment. Види ја дискусијата за БКНФ подолу. |
| | 188 | |
| | 189 | === Декомпозиција по FD10 |
| | 190 | |
| | 191 | '''Subjects'''(''__subject_id__'', subject_name, subject_code, awarded_credits, dependency_credit) |
| | 192 | |
| | 193 | R4 = R3 − { subject_name, subject_code, awarded_credits, dependency_credit } |
| | 194 | |
| | 195 | * Клучеви: subject_id (примарен), subject_name, subject_code (алтернативни, поради FD11 и FD12) |
| | 196 | * ''Lossless join'': спојување по subject_id. |
| | 197 | * ''Dependency preservation'': FD10, FD11 и FD12 се сочувани во Subjects. |
| | 198 | |
| | 199 | '''Резултат по 2НФ:''' |
| | 200 | |
| | 201 | R4 = { user_id, user_name, embg, surname, index_no, bday, email, password, role, |
| | 202 | quota, enrollment_year, user_created_at, high_school_id, gpa, hs_type, |
| | 203 | contact_id, city, municipality, address, phone_number, microsoft_email, |
| | 204 | major_id, major_name, semester_id, year, semester_type, subject_id, |
| | 205 | enrolled_id, enrolled_quota, note, student_comment, enrolled_created_at, |
| | 206 | last_change, completed, sem_subject_id, professor_id, signature, passed_id, |
| | 207 | grade, date_passed, document_id, token_id, payment_id, mandatory_semester, |
| | 208 | prerequisite_id, teaching_prof_id } |
| | 209 | |
| | 210 | == 3НФ декомпозиција |
| | 211 | |
| | 212 | R4 не ја задоволува 3НФ поради транзитивни зависности: token_id → user_id → |
| | 213 | user_name, payment_id → enrolled_id → major_id → major_name, и слично. |
| | 214 | |
| | 215 | === Декомпозиција по FD1 |
| | 216 | |
| | 217 | '''Users'''(''__user_id__'', user_name, embg, surname, index_no, bday, email, password, role, quota, enrollment_year, user_created_at) |
| | 218 | |
| | 219 | R5 = R4 − { user_name, embg, surname, index_no, bday, email, password, role, quota, enrollment_year, user_created_at } |
| | 220 | |
| | 221 | * Клучеви: user_id (примарен), email (алтернативен, поради FD2) |
| | 222 | * Транзитивна зависност: token_id → user_id → останатите атрибути на корисникот |
| | 223 | * ''Lossless join'': спојување по user_id. |
| | 224 | * ''Dependency preservation'': FD1 и FD2 се сочувани во Users. |
| | 225 | |
| | 226 | === Декомпозиција по FD4 |
| | 227 | |
| | 228 | '''HighSchool'''(''__high_school_id__'', user_id, gpa, hs_type) |
| | 229 | |
| | 230 | R6 = R5 − { gpa, hs_type } |
| | 231 | |
| | 232 | * Клучеви: high_school_id (примарен), user_id (алтернативен, поради FD3 - врската е 1:1) |
| | 233 | * ''Lossless join'': спојување по high_school_id. |
| | 234 | * ''Dependency preservation'': FD3 и FD4 се сочувани во HighSchool. |
| | 235 | |
| | 236 | === Декомпозиција по FD6 |
| | 237 | |
| | 238 | '''Contact'''(''__contact_id__'', user_id, city, municipality, address, phone_number, microsoft_email) |
| | 239 | |
| | 240 | R7 = R6 − { city, municipality, address, phone_number, microsoft_email } |
| | 241 | |
| | 242 | * Клучеви: contact_id (примарен), user_id (алтернативен, поради FD5) |
| | 243 | * ''Lossless join'': спојување по contact_id. |
| | 244 | * ''Dependency preservation'': FD5 и FD6 се сочувани во Contact. |
| | 245 | |
| | 246 | === Декомпозиција по FD13 |
| | 247 | |
| | 248 | '''EnrolledSemesters'''(''__enrolled_id__'', user_id, enrolled_quota, major_id, note, student_comment, enrolled_created_at, last_change, completed, semester_id) |
| | 249 | |
| | 250 | R8 = R7 − { enrolled_quota, note, student_comment, enrolled_created_at, last_change, completed } |
| | 251 | |
| | 252 | * Клучеви: enrolled_id (примарен), (user_id, semester_id) (алтернативен, поради FD14) |
| | 253 | * Транзитивна зависност: payment_id → enrolled_id → атрибутите на запишувањето |
| | 254 | * ''Lossless join'': спојување по enrolled_id. |
| | 255 | * ''Dependency preservation'': FD13 и FD14 се сочувани во EnrolledSemesters. |
| | 256 | |
| | 257 | === Декомпозиција по FD7 |
| | 258 | |
| | 259 | '''Major'''(''__major_id__'', major_name) |
| | 260 | |
| | 261 | R9 = R8 − { major_name } |
| | 262 | |
| | 263 | * Клуч: major_id |
| | 264 | * Транзитивна зависност: enrolled_id → major_id → major_name |
| | 265 | * ''Lossless join'': спојување по major_id. |
| | 266 | * ''Dependency preservation'': FD7 е сочувана во Major. |
| | 267 | |
| | 268 | === Декомпозиција по FD8 |
| | 269 | |
| | 270 | '''ActiveSemesters'''(''__semester_id__'', year, semester_type) |
| | 271 | |
| | 272 | R10 = R9 − { year, semester_type } |
| | 273 | |
| | 274 | * Клучеви: semester_id (примарен), (year, semester_type) (алтернативен, поради FD9) |
| | 275 | * Транзитивна зависност: enrolled_id → semester_id → year, semester_type |
| | 276 | * ''Lossless join'': спојување по semester_id. |
| | 277 | * ''Dependency preservation'': FD8 и FD9 се сочувани во ActiveSemesters. |
| | 278 | |
| | 279 | === Декомпозиција по FD15 |
| | 280 | |
| | 281 | '''SemestersSubjects'''(''__sem_subject_id__'', enrolled_id, subject_id, professor_id, signature) |
| | 282 | |
| | 283 | R11 = R10 − { professor_id, signature } |
| | 284 | |
| | 285 | * Клучеви: sem_subject_id (примарен), (enrolled_id, subject_id) (алтернативен, поради FD16) |
| | 286 | * ''Lossless join'': спојување по sem_subject_id. |
| | 287 | * ''Dependency preservation'': FD15 и FD16 се сочувани во SemestersSubjects. |
| | 288 | |
| | 289 | === Декомпозиција по FD17 |
| | 290 | |
| | 291 | '''PassedSubjects'''(''__passed_id__'', sem_subject_id, grade, date_passed) |
| | 292 | |
| | 293 | R12 = R11 − { grade, date_passed } |
| | 294 | |
| | 295 | * Клучеви: passed_id (примарен), sem_subject_id (алтернативен, поради FD18 - врската е 1:1) |
| | 296 | * ''Lossless join'': спојување по passed_id. |
| | 297 | * ''Dependency preservation'': FD17 и FD18 се сочувани во PassedSubjects. |
| | 298 | |
| | 299 | === Декомпозиција по FD22 |
| | 300 | |
| | 301 | '''MajorSubjects'''(''__major_id__'', ''__subject_id__'', mandatory_semester) |
| | 302 | |
| | 303 | R13 = R12 − { mandatory_semester } |
| | 304 | |
| | 305 | * Клуч: (major_id, subject_id) |
| | 306 | * Зависноста FD22 има сложена лева страна која не е клуч на R12, што ја нарушува 3НФ. |
| | 307 | * ''Lossless join'': спојување по (major_id, subject_id). |
| | 308 | * ''Dependency preservation'': FD22 е сочувана во MajorSubjects. |
| | 309 | |
| | 310 | '''Резултат по 3НФ:''' |
| | 311 | |
| | 312 | R13 = { user_id, high_school_id, contact_id, major_id, semester_id, subject_id, |
| | 313 | enrolled_id, sem_subject_id, passed_id, document_id, token_id, payment_id, |
| | 314 | prerequisite_id, teaching_prof_id } |
| | 315 | |
| | 316 | Во R13 остануваат само идентификатори. Сите зависности со неклучна десна страна |
| | 317 | се веќе издвоени. |
| | 318 | |
| | 319 | == БКНФ |
| | 320 | |
| | 321 | Секоја од добиените релации се проверува дали секоја лева страна на функционална |
| | 322 | зависност во неа е суперклуч на таа релација. |
| | 323 | |
| | 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) → БКНФ |
| | 337 | |
| | 338 | === Пронајдено нарушување на БКНФ |
| | 339 | |
| | 340 | Ако релацијата Payment се дефинира како во Фаза 2: |
| | 341 | |
| | 342 | Payment(''__payment_id__'', user_id, enrolled_id, amount) |
| | 343 | |
| | 344 | тогаш во неа важи и зависноста '''enrolled_id → user_id''' (изведена од FD13), |
| | 345 | а enrolled_id '''не е''' клуч на Payment. Ова е нарушување на БКНФ и значи дека |
| | 346 | атрибутот user_id во Payment е редундантен: студентот е веќе определен преку |
| | 347 | запишувањето кое се плаќа. |
| | 348 | |
| | 349 | Практичната последица е можност за противречни податоци - ред во Payment може да |
| | 350 | тврди дека плаќањето е на еден студент, додека запишувањето на кое се однесува |
| | 351 | припаѓа на друг студент. Базата тоа не го спречува. |
| | 352 | |
| | 353 | '''Декомпозиција по enrolled_id → user_id:''' |
| | 354 | |
| | 355 | Payment(''__payment_id__'', enrolled_id, amount) |
| | 356 | |
| | 357 | user_id се добива со спојување преку EnrolledSemesters. |
| | 358 | |
| | 359 | * ''Lossless join'': enrolled_id е надворешен клуч кон EnrolledSemesters, каде е клуч, па спојувањето е без загуба. |
| | 360 | * ''Dependency preservation'': FD21 останува сочувана, бидејќи payment_id → enrolled_id, amount е во Payment, а payment_id → user_id се изведува транзитивно преку FD13. |
| | 361 | |
| | 362 | По оваа измена '''сите релации се во БКНФ'''. |
| | 363 | |
| | 364 | == 4НФ |
| | 365 | |
| | 366 | Преостанатата релација R13 содржи само идентификатори и во неа постојат |
| | 367 | повеќевредносни зависности кои се меѓусебно независни. На пример, документите кои |
| | 368 | ги побарал еден корисник се независни од предусловите меѓу предметите и од |
| | 369 | распоредот на професорите. |
| | 370 | |
| | 371 | '''Декомпозиција по 4НФ:''' |
| | 372 | |
| | 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'': трите нови релации не носат функционални зависности, туку само врски. |
| | 383 | |
| | 384 | == Финален резултат и дискусија |
| | 385 | |
| | 386 | === Нормализиран релациски модел |
| | 387 | |
| | 388 | 1. '''Users'''(''__user_id__'', user_name, embg, surname, index_no, bday, email, password, role, quota, enrollment_year, user_created_at) |
| | 389 | 2. '''HighSchool'''(''__high_school_id__'', user_id, gpa, hs_type) |
| | 390 | 3. '''Contact'''(''__contact_id__'', user_id, city, municipality, address, phone_number, microsoft_email) |
| | 391 | 4. '''Major'''(''__major_id__'', major_name) |
| | 392 | 5. '''ActiveSemesters'''(''__semester_id__'', year, semester_type) |
| | 393 | 6. '''Subjects'''(''__subject_id__'', subject_name, subject_code, awarded_credits, dependency_credit) |
| | 394 | 7. '''EnrolledSemesters'''(''__enrolled_id__'', user_id, enrolled_quota, major_id, note, student_comment, enrolled_created_at, last_change, completed, semester_id) |
| | 395 | 8. '''SemestersSubjects'''(''__sem_subject_id__'', enrolled_id, subject_id, professor_id, signature) |
| | 396 | 9. '''PassedSubjects'''(''__passed_id__'', sem_subject_id, grade, date_passed) |
| | 397 | 10. '''Documents'''(''__document_id__'', document_type, document_body, document_cost) |
| | 398 | 11. '''UserDocuments'''(''__user_id__'', ''__document_id__'') |
| | 399 | 12. '''Token'''(''__token_id__'', user_id, token_value, expires_at, is_valid) |
| | 400 | 13. '''Payment'''(''__payment_id__'', enrolled_id, amount) |
| | 401 | 14. '''MajorSubjects'''(''__major_id__'', ''__subject_id__'', mandatory_semester) |
| | 402 | 15. '''DependencySubject'''(''__subject_id__'', ''__prerequisite_id__'') |
| | 403 | 16. '''ProfessourSubjects'''(''__teaching_prof_id__'', ''__semester_id__'', ''__subject_id__'') |
| | 404 | |
| | 405 | Сите 16 релации се во БКНФ, декомпозицијата ги сочувува сите функционални |
| | 406 | зависности и е без загуба при спојување. |
| | 407 | |
| | 408 | === Дискусија |
| | 409 | |
| | 410 | Постапката на нормализација, спроведена независно од дизајнот на Фаза 2, даде |
| | 411 | '''практично ист резултат''' - истите 16 релации, со исти клучеви. Тоа значи дека |
| | 412 | ЕР моделот од Фаза 1 и релацискиот дизајн од Фаза 2 биле соодветно направени. |
| | 413 | |
| | 414 | Постои '''една разлика''', и таа е вистинска грешка во дизајнот од Фаза 2: |
| | 415 | |
| | 416 | * '''Фаза 2''': Payment(''__id__'', user_id, enrollment_id, amount) |
| | 417 | * '''По нормализација''': Payment(''__id__'', enrollment_id, amount) |
| | 418 | |
| | 419 | Атрибутот user_id е редундантен, бидејќи enrollment_id → user_id. Покрај |
| | 420 | редундантноста, ваквиот дизајн дозволува аномалија при ажурирање: плаќање може да |
| | 421 | биде запишано на еден студент, а да се однесува на запишување на друг студент, |
| | 422 | што базата не го спречува со ниту едно ограничување. |
| | 423 | |
| | 424 | За наредните фази се користи '''нормализираниот модел''', односно табелата payment |
| | 425 | повеќе не содржи user_id. Скриптите schema_creation.sql и data_load.sql, како и |
| | 426 | документацијата на Фаза 2, се ажурирани соодветно. |
| | 427 | |
| | 428 | === Забелешка за постапката |
| | 429 | |
| | 430 | Кандидат клучевите и проверката за БКНФ не се одредени само со разгледување, туку |
| | 431 | се пресметани програмски врз множеството функционални зависности (пресметка на |
| | 432 | покривач на атрибути и проверка дали секоја детерминанта е суперклуч во секоја |
| | 433 | релација). Токму таа проверка го откри нарушувањето кај Payment. |
| | 434 | |
| | 435 | == Користење на вештачка интелигенција |
| | 436 | |
| | 437 | [wiki:NormalizationAIUsage NormalizationAIUsage] |
| | 438 | |
| | 439 | == Историјат |
| | 440 | |
| | 441 | '''Верзија 1''' - Прва верзија на нормализацијата: денормализирана релација, |
| | 442 | функционални зависности, кандидат клучеви и декомпозиција до БКНФ и 4НФ. |
| | 443 | Откриено и отстрането нарушување на БКНФ во релацијата Payment. |
| | 444 | |
| | 445 | == Статус |
| | 446 | |
| | 447 | ''' [[span(style=color: #FF8000, Во тек )]] ''' |