Changes between Version 4 and Version 5 of Normalization


Ignore:
Timestamp:
09/24/26 20:05:14 (4 days ago)
Author:
233149
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v4 v5  
    99created_at), атрибутите се преименувани така што во R нема две исти имиња:
    1010
    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значи функционална зависност.
    1829
    1930'''R''' = { user_id, user_name, embg, surname, index_no, bday, email, password,
    … …  
    119130sem_subject_id и passed_id се во однос 1:1 и секој од нив води до subject_id.
    120131
     132=== Проверка на затворачот на секој кандидат клуч
     133
     134За секое CK''i'' се пресметува затворачот CK''i''^+^ и се проверува дали
     135CK''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-те само-десно атрибути. Останува да се провери само кои од
     20614-те двострани атрибути можат да го дополнат K.
     207
     208Девет од нив '''веќе се содржани во K^+^''': contact_id, email, enrolled_id,
     209high_school_id, major_id, semester_id, semester_type, user_id, year. Ако
     210атрибутот A е во K^+^, тогаш (K ∪ {A})^+^ = K^+^, што има 45 атрибути, па таквото
     211множество не е суперклуч.
     212
     213Преостануваат точно петте кои не се во K^+^ и водат до предметот: subject_id,
     214sem_subject_id, passed_id, subject_code, subject_name - тоа се CK1-CK5. Секое
     215множество со два или повеќе додадени атрибути го содржи некој од нив, па не е
     216минимално.
     217
     218Заклучок: релацијата R има '''точно 5 кандидат клучеви''', сите со големина 6.
     219
    121220'''Избран примарен клуч:'''
    122221
    … …  
    135234зависат од дел од примарниот клуч, а не од целиот. На пример document_id →
    136235document_type, каде document_id е само еден дел од PK.
     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 ⋈ (сите издвоени релации)
    137263
    138264== 1НФ декомпозиција
    … …  
    163289
    164290 * Клуч: document_id
    165  * ''Lossless join'': спојувањето по document_id ја реконструира R, бидејќи document_id е клуч на Documents.
     291 * ''Lossless join'': '''R = Documents ⋈ R1''', спојување по '''Documents ∩ R1 = { document_id }'''. Тој пресек е клуч на '''Documents''' (FD19: document_id → сите останати атрибути на Documents), па важи (A ∩ B) → A и декомпозицијата е без загуба.
    166292 * ''Dependency preservation'': FD19 е сочувана во Documents.
    167293
    … …  
    173299
    174300 * Клуч: token_id
    175  * ''Lossless join'': спојување по token_id; token_id е клуч на Token.
     301 * ''Lossless join'': '''R1 = Token ⋈ R2''', спојување по '''Token ∩ R2 = { token_id, user_id }''' (и двата атрибути остануваат во R2). Тој пресек е суперклуч на '''Token''', бидејќи веќе token_id сам по FD20 ги определува сите атрибути на Token. Значи (A ∩ B) → A, па спојувањето е без загуба.
    176302 * ''Dependency preservation'': FD20 е сочувана во Token.
    177303
    … …  
    183309
    184310 * Клуч: payment_id
    185  * ''Lossless join'': спојување по payment_id.
     311 * ''Lossless join'': '''R2 = Payment ⋈ R3''', спојување по '''Payment ∩ R3 = { payment_id, enrolled_id }'''. Тој пресек е суперклуч на '''Payment''', бидејќи payment_id → enrolled_id, amount (FD21). Значи (A ∩ B) → A, па спојувањето е без загуба.
    186312 * ''Dependency preservation'': FD21 е сочувана во Payment.
    187313 * '''Забелешка:''' атрибутот user_id намерно '''не''' е дел од Payment. Види ја дискусијата за БКНФ подолу.
    … …  
    194320
    195321 * Клучеви: subject_id (примарен), subject_name, subject_code (алтернативни, поради FD11 и FD12)
    196  * ''Lossless join'': спојување по subject_id.
     322 * ''Lossless join'': '''R3 = Subjects ⋈ R4''', спојување по '''Subjects ∩ R4 = { subject_id }'''. Тој пресек е клуч на '''Subjects''' (FD10), па важи (A ∩ B) → A и спојувањето е без загуба.
    197323 * ''Dependency preservation'': FD10, FD11 и FD12 се сочувани во Subjects.
    198324
    … …  
    221347 * Клучеви: user_id (примарен), email (алтернативен, поради FD2)
    222348 * Транзитивна зависност: token_id → user_id → останатите атрибути на корисникот
    223  * ''Lossless join'': спојување по user_id.
     349 * ''Lossless join'': '''R4 = Users ⋈ R5''', спојување по '''Users ∩ R5 = { user_id }''' (email се отстранува од R5, па не е дел од пресекот). Тој пресек е клуч на '''Users''' (FD1), па важи (A ∩ B) → A и спојувањето е без загуба.
    224350 * ''Dependency preservation'': FD1 и FD2 се сочувани во Users.
    225351
    … …  
    231357
    232358 * Клучеви: high_school_id (примарен), user_id (алтернативен, поради FD3 - врската е 1:1)
    233  * ''Lossless join'': спојување по high_school_id.
     359 * ''Lossless join'': '''R5 = !HighSchool ⋈ R6''', спојување по '''!HighSchool ∩ R6 = { high_school_id, user_id }'''. Тој пресек е суперклуч на '''!HighSchool''' - секој од двата атрибути посебно е клуч (FD4, односно FD3 бидејќи врската е 1:1). Значи (A ∩ B) → A и спојувањето е без загуба.
    234360 * ''Dependency preservation'': FD3 и FD4 се сочувани во !HighSchool.
    235361
    … …  
    241367
    242368 * Клучеви: contact_id (примарен), user_id (алтернативен, поради FD5)
    243  * ''Lossless join'': спојување по contact_id.
     369 * ''Lossless join'': '''R6 = Contact ⋈ R7''', спојување по '''Contact ∩ R7 = { contact_id, user_id }'''. Тој пресек е суперклуч на '''Contact''' - contact_id е клуч по FD6, а user_id по FD5, бидејќи врската е 1:1. Значи (A ∩ B) → A и спојувањето е без загуба.
    244370 * ''Dependency preservation'': FD5 и FD6 се сочувани во Contact.
    245371
    … …  
    252378 * Клучеви: enrolled_id (примарен), (user_id, semester_id) (алтернативен, поради FD14)
    253379 * Транзитивна зависност: payment_id → enrolled_id → атрибутите на запишувањето
    254  * ''Lossless join'': спојување по enrolled_id.
     380 * ''Lossless join'': '''R7 = !EnrolledSemesters ⋈ R8''', спојување по '''!EnrolledSemesters ∩ R8 = { enrolled_id, user_id, major_id, semester_id }'''. Тој пресек е суперклуч на '''!EnrolledSemesters''', бидејќи веќе enrolled_id сам по FD13 ги определува сите нејзини атрибути. Значи (A ∩ B) → A и спојувањето е без загуба.
    255381 * ''Dependency preservation'': FD13 и FD14 се сочувани во !EnrolledSemesters.
    256382
    … …  
    263389 * Клуч: major_id
    264390 * Транзитивна зависност: enrolled_id → major_id → major_name
    265  * ''Lossless join'': спојување по major_id.
     391 * ''Lossless join'': '''R8 = Major ⋈ R9''', спојување по '''Major ∩ R9 = { major_id }'''. Тој пресек е клуч на '''Major''' (FD7), па важи (A ∩ B) → A и спојувањето е без загуба.
    266392 * ''Dependency preservation'': FD7 е сочувана во Major.
    267393
    … …  
    274400 * Клучеви: semester_id (примарен), (year, semester_type) (алтернативен, поради FD9)
    275401 * Транзитивна зависност: enrolled_id → semester_id → year, semester_type
    276  * ''Lossless join'': спојување по semester_id.
     402 * ''Lossless join'': '''R9 = !ActiveSemesters ⋈ R10''', спојување по '''!ActiveSemesters ∩ R10 = { semester_id }''' (year и semester_type се отстрануваат од R10). Тој пресек е клуч на '''!ActiveSemesters''' (FD8), па важи (A ∩ B) → A и спојувањето е без загуба.
    277403 * ''Dependency preservation'': FD8 и FD9 се сочувани во !ActiveSemesters.
    278404
    … …  
    284410
    285411 * Клучеви: sem_subject_id (примарен), (enrolled_id, subject_id) (алтернативен, поради FD16)
    286  * ''Lossless join'': спојување по sem_subject_id.
     412 * ''Lossless join'': '''R10 = !SemestersSubjects ⋈ R11''', спојување по '''!SemestersSubjects ∩ R11 = { sem_subject_id, enrolled_id, subject_id }'''. Тој пресек е суперклуч на '''!SemestersSubjects''', бидејќи веќе sem_subject_id сам по FD15 ги определува professor_id и signature. Значи (A ∩ B) → A и спојувањето е без загуба.
    287413 * ''Dependency preservation'': FD15 и FD16 се сочувани во !SemestersSubjects.
    288414
    … …  
    294420
    295421 * Клучеви: passed_id (примарен), sem_subject_id (алтернативен, поради FD18 - врската е 1:1)
    296  * ''Lossless join'': спојување по passed_id.
     422 * ''Lossless join'': '''R11 = !PassedSubjects ⋈ R12''', спојување по '''!PassedSubjects ∩ R12 = { passed_id, sem_subject_id }'''. Тој пресек е суперклуч на '''!PassedSubjects''' - passed_id е клуч по FD17, а sem_subject_id по FD18, бидејќи врската е 1:1. Значи (A ∩ B) → A и спојувањето е без загуба.
    297423 * ''Dependency preservation'': FD17 и FD18 се сочувани во !PassedSubjects.
    298424
    … …  
    305431 * Клуч: (major_id, subject_id)
    306432 * Зависноста FD22 има сложена лева страна која не е клуч на R12, што ја нарушува 3НФ.
    307  * ''Lossless join'': спојување по (major_id, subject_id).
     433 * ''Lossless join'': '''R12 = !MajorSubjects ⋈ R13''', спојување по '''!MajorSubjects ∩ R13 = { major_id, subject_id }'''. Тој пресек е клуч на '''!MajorSubjects''' (FD22), па важи (A ∩ B) → A и спојувањето е без загуба.
    308434 * ''Dependency preservation'': FD22 е сочувана во !MajorSubjects.
    309435
    … …  
    322448зависност во неа е суперклуч на таа релација.
    323449
    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) ⇒ БКНФ
    337463
    338464=== Пронајдено нарушување на БКНФ
    … …  
    357483 user_id се добива со спојување преку !EnrolledSemesters.
    358484
    359  * ''Lossless join'': enrolled_id е надворешен клуч кон !EnrolledSemesters, каде е клуч, па спојувањето е без загуба.
     485 * ''Lossless join'': оригиналната Payment(payment_id, user_id, enrolled_id, amount) се дели на '''Payment(payment_id, enrolled_id, amount)''' и '''!EnrolledSemesters(enrolled_id, user_id, …)'''. Спојувањето е по '''Payment ∩ !EnrolledSemesters = { enrolled_id }'''. Тој пресек е клуч на '''!EnrolledSemesters''' (FD13), па важи (A ∩ B) → B и спојувањето е без загуба. Атрибутот user_id се враќа со Payment ⋈ !EnrolledSemesters по enrolled_id.
    360486 * ''Dependency preservation'': FD21 останува сочувана, бидејќи payment_id → enrolled_id, amount е во Payment, а payment_id → user_id се изведува транзитивно преку FD13.
    361487
    … …  
    369495распоредот на професорите.
    370496
     497Повеќевредносните зависности кои важат во R13 се:
     498
     499 * '''MVD1''': user_id ↠ document_id
     500 * '''MVD2''': subject_id ↠ prerequisite_id
     501 * '''MVD3''': (semester_id, subject_id) ↠ teaching_prof_id
     502
     503Ниту една од трите лева страна не е суперклуч на R13, па R13 не е во 4НФ.
     504
    371505'''Декомпозиција по 4НФ:'''
    372506
    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
     536R13c '''не се задржува''' како посебна релација, бидејќи не носи нова информација.
     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 не се губи со оваа декомпозиција.
    383552
    384553== Финален резултат и дискусија
    … …  
    406575зависности и е без загуба при спојување.
    407576
     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
    408604=== Дискусија
    409605
    … …  
    433629релација). Токму таа проверка го откри нарушувањето кај Payment.
    434630
     631Со истата пресметка е потврдено дека затворачот на секој од петте кандидат клучеви
     632ги покрива сите 57 атрибути на R, дека ниту едно нивно вистинско подмножество не е
     633суперклуч, и дека не постои шести кандидат клуч.
     634
    435635== Историјат
    436636
    … …  
    439639 Откриено и отстрането нарушување на БКНФ во релацијата Payment.
    440640
     641 '''Верзија 2''' - По забелешки: додадена е целосна пресметка на затворачот за
     642 сите пет кандидат клучеви со проверка дека покриваат 57/57 атрибути, проверка на
     643 минималноста и доказ дека нема други кандидат клучеви. Кај секоја декомпозиција
     644 е прецизно наведено кои две релации се спојуваат, по кои заеднички атрибути и на
     645 која од нив тие се клуч, со посебен критериум за чекорите во 4НФ.
     646 Стрелката → е задржана исклучиво за функционални зависности; преименувањата,
     647 пресметките и заклучоците сега користат табела, односно ⇒.
     648
    441649== Статус
    442650