Changes between Version 5 and Version 6 of Normalization


Ignore:
Timestamp:
02/18/26 21:05:55 (10 days ago)
Author:
231136
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v5 v6  
    11= Нормализација
    22
    3 За табелите од нашата база на податоци, со цел разликување на самите id за секој ентитет,
    4 ќе ги преименуваме id атрибутите во <име_на_релација>_id.
    5 Со тоа добиваме: user_id, non_admin_user_id, admin_id, listener_id,
    6 musical_entity_id, song_id, artist_id, event_id, album_id, playlist_id
     3За табелите од нашата база на податоци, со цел разликување на самите id за секој ентитет, ќе ги преименуваме id атрибутите во **<име_на_релација>_id**.
     4Со тоа добиваме: **user_id, non_admin_user_id, admin_id, listener_id, musical_entity_id, song_id, artist_id, event_id, album_id, playlist_id**.
    75
    86== Функционални зависности:
    97
    10 - user_id-> profile_photo, email, username, full_name, password
    11 - musical_entity_id-> title, genre, release_date, artist_id
    12 - song_id-> musical_entity_id, link, album_id
    13 - playlist_id-> cover, playlist_name, listener_id
    14 - event_id-> event_name, location, venue, date, time, artist_id, admin_id
    15 - (artist_id, musical_entity_id)-> role
    16 - (listener_id, musical_entity_id)-> grade, comment
    17 
    18 
    19 - non_admin_user_id-> user_id
    20 - admin_id-> user_id
    21 - listener_id-> non_admin_user_id
    22 - artist_id-> non_admin_user_id
    23 - album_id-> musical_entity_id
    24 
    25 - (listener_id, playlist_id)-> /
    26 - (playlist_id, song_id)-> /
    27 - (follower_id, followee_id)-> /
    28 - (event_id, artist_id)-> /
    29 - (listener_id, musical_entity_id)-> /
    30 - (listener_id, song_id, timestamp)-> /
    31 
    32 
    33 Лево:
    34 - song_id,
    35 - playlist_id,
    36 - event_id,
    37 - follower_id,
    38 - followee_id,
    39 - timestamp
    40 
    41 
    42 Десно:
    43 - profile_photo, email, username, full_name, password,
    44 - title, genre, release_date, link, cover, playlist_name,
    45 - event_name, location, venue, date, time, role, grade, comment,
    46 - timestamp
    47 
    48 Лево и десно:
    49 - user_id,
    50 - musical_entity_id,
    51 - artist_id,
    52 - admin_id,
    53 - listener_id,
    54 - album_id
    55 
    56 
    57 
    58 1. Глобална релација
    59 
    60 
    61     R={ user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
    62         follower_id, followee_id, profile_photo, email, username, full_name, password,
    63         title, genre, release_date, link, cover, playlist_name, event_name, location, venue,
    64         date, time, role, grade, comment, timestamp, artist_id, admin_id, listener_id,
    65         album_id }
    66 
    67 
    68 Функционални зависности:
    69 - FD1: song_id-> musical_entity_id,link, album_id
    70 - FD2: playlist_id-> cover, playlist_name, listener_id
    71 - FD3: event_id-> event_name, location, venue, date, time, artist_id, admin_id
    72 - FD4: (artist_id, musical_entity_id)-> role
    73 - FD5: (listener_id, musical_entity_id)-> grade, comment
    74  
    75 - FD6: non_admin_user_id-> user_id
    76 - FD7: admin_id-> user_id
    77 - FD8: listener_id-> non_admin_user_id
    78 - FD9: artist_id-> non_admin_user_id
    79 - FD10: album_id-> musical_entity_id
    80 
    81 
    82 - FD11: (listener_id, playlist_id)-> /
    83 - FD12: (playlist_id, song_id)-> /
    84 - FD13: (follower_id, followee_id)-> /
    85 - FD14: (event_id, artist_id)-> /
    86 - FD15: (listener_id, musical_entity_id)-> /
    87 - FD16: (listener_id, song_id, timestamp)-> /
    88 - FD17: user_id -> profile_photo, email, username, full_name, password
    89 - FD18: musical_entity_id -> title, genre, release_date, artist_id
    90 
    91 - Покривачи
    92 
    93 
    94 1. song_id+ = {song_id, musical_entity_id, link, album_id} -> Не ги содржи сите атрибути
    95 2. playlist_id+ = {playlist_id, cover, playlist_name, listener_id} -> Не ги содржи сите атрибути
    96 3. event_id+ = {event_id, event_name, location, venue, date, time, artist_id, admin_id} -> Не ги содржи сите атрибути
    97 4. follower_id+ = {follower_id} -> Не ги содржи сите атрибути
    98 5. followee_id+ = {followee_id} -> Не ги содржи сите атрибути
    99 6. timestamp+ = {timestamp} -> Не ги содржи сите атрибути
    100 
    101 = Спојување Покривачи
     8
     9- FD1: user_id -> profile_photo, email, username, full_name, password
     10- FD3: musical_entity_id -> title, genre, me_cover, release_date, artist_id
     11- FD4: song_id -> link, album_id
     12- FD5: playlist_id -> playlist_cover, playlist_name, listener_id
     13- FD6: event_id -> event_name, location, venue, date, time, user_id
     14- FD7: (artist_id, musical_entity_id) -> role
     15- FD8: (listener_id, musical_entity_id) -> grade, comment
     16
     17- FD9: non_admin_user_id -> user_id
     18- FD10: admin_id -> user_id
     19- FD11: listener_id -> non_admin_user_id
     20- FD12: artist_id -> non_admin_user_id
     21- FD13: album_id -> musical_entity_id
     22- FD14: (listener_id,song_id,timestamp) -> /
     23
     24
     25**Лево**:
     26playlist_id, event_id, song_id, timestamp, admin_id
     27
     28
     29**Десно**:
     30profile_photo, email, username, full_name, password, title, genre, release_date, me_cover, link, playlist_cover, playlist_name, event_name, location, venue, date, time, role, grade, comment
     31
     32**Лево и десно**:
     33user_id, musical_entity_id, artist_id, non_admin_user_id, album_id, listener_id
     34
     35
     36
     37=== Глобална релација
     38
     39R={ playlist_id, event_id, song_id, timestamp, admin_id, profile_photo, email, username, full_name, password, title, genre, release_date, me_cover, link, playlist_cover, playlist_name, event_name, location, venue, date, time, role, grade, comment, user_id, musical_entity_id, artist_id, non_admin_user_id, album_id, listener_id}
     40   
     41
     42== Покривачи
     43
     44
     451. **playlist_id+** = {playlist_id, playlist_name, playlist_cover, listener_id, user_id, full_name, email, password, username, profile_photo} -> **Не ги содржи сите атрибути**
     462. **event_id+** = {event_id, event_name, location, venue, date, time, user_id, full_name, email, password, username, profile_photo} -> **Не ги содржи сите атрибути**
     473. **song_id+** = {song_id, link, album_id, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, user_id, full_name, email, password, username, profile_photo} -> **Не ги содржи сите атрибути**
     484. **timestamp+** = {timestamp} -> **Не ги содржи сите атрибути**
     495. **admin_id+** = {admin_id, user_id, full_name, email, password, username, profile_photo } -> **Не ги содржи сите атрибути**
     50
     51
     52
     53== Спојување Покривачи
    10254
    10355Бидејќи атрибутите кои се наоѓаат само на левата страна не може да се изведат на никој друг начин,
    10456тие мора да бидат дел од примарниот клуч.
    10557
    106 {song_id,
    107 playlist_id,
    108 event_id,
    109 follower_id,
    110 followee_id,
    111 timestamp}+ = {song_id, playlist_id, event_id, follower_id, followee_id,
    112     link, album_id, cover, playlist_name, listener_id, musical_entity_id
    113     event_name, location, venue, date, time, artist_id, admin_id,
    114     user_id, non_admin_user_id,
    115     profile_photo, email, username, full_name, password,
    116     title, genre, release_date,
    117     role,
    118     grade, comment,
    119     timestamp}
    120 
    121 Покривачот составен од сите атрибути кои се наоѓаат само од левата страна ги содржи
    122 сите атрибути на глобалната релација. Всушност тоа ни е и минимален суперклуч.
    123 Во нашиот случај ова ни е единствениот кандидат клуч, па оттаму
    124 тоа ни е и примарниот клуч на релацијата.
    125 
    126 
    127 
    128 
    129 
    130 Избран примарен клуч: {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    131 
    132 Бидејќи релацијата не содржи повеќевредносни атрибути,
    133 неуникатни атрибути, вредности од различен домен за еден атрибут,
    134 а притоа секоја редица е уникатно определена преку примарниот клуч,
    135 ја задоволува 1НФ,
    136 но не ја задоволува 2НФ поради постоење на парцијални зависности.
    137 
    138 Идентификувани парцијални зависности што ја нарушуваат 2NF:
    139 FD1 -> musical_entity_id, link, album_id зависат само од song_id
    140 FD2 -> cover, playlist_name, listener_id зависат само од playlist_id
    141 FD3 -> event_name, location, venue, date, time, artist_id, admin_id зависат само од event_id
    142 
    143 
     58**{playlist_id, event_id, song_id, timestamp, admin_id}+** = { playlist_id, event_id, song_id, timestamp, admin_id, playlist_name, playlist_cover, user_id, listener_id, full_name, email, password, username, profile_photo, event_name, location, venue, date, time, link, album_id, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, role, grade, comment}
     59
     60Покривачот составен од сите атрибути кои се наоѓаат само од левата страна ги содржи сите атрибути на глобалната релација. Всушност тоа ни е и минимален суперклуч.
     61Во нашиот случај ова ни е единствениот кандидат клуч, па оттаму тоа ни е и примарниот клуч на релацијата.
     62
     63
     64
     65Избран примарен клуч: **{playlist_id, event_id, song_id, timestamp, admin_id}**
     66
     67== Проверка за 1НФ
     68Бидејќи релацијата не содржи повеќевредносни атрибути, неуникатни атрибути, вредности од различен домен за еден атрибут, а притоа секоја редица е уникатно определена преку примарниот клуч, **ја задоволува 1НФ**.
     69
     70
     71== Проверка за 2НФ
     72R **не ја задоволува 2НФ** поради постоење на парцијални зависности, како на пример `playlist_name, playlist_cover, listener_id` кои зависат само од `playlist_id`, а не од целиот примарен клуч.
    14473
    14574
     
    14877Најпрво ги групираме атрибутите само според клучевите од кои зависат.
    14978
    150 - song_id-> musical_entity_id, link, album_id
    151 - playlist_id-> cover, playlist_name, listener_id
    152 - event_id-> event_name, location, venue, date, time, artist_id, admin_id
     79- playlist_id -> playlist_name, playlist_cover, listener_id
     80- song_id -> link, album_id
     81- event_id -> event_name, location, venue, date, time, user_id
     82- admin_id -> user_id
     83
    15384
    15485== Декомпозиција во релации
    15586
    156 
    157 Songs(song_id, musical_entity_id, link, album_id)
    158 pk: song_id
    159 
    160 R1 = R - {link, album_id}
    161 R1 = {user_id, song_id, musical_entity_id, playlist_id, event_id, non_admin_user_id,
    162         follower_id, followee_id, profile_photo, email, username, full_name, password,
    163         title, genre, release_date, cover, playlist_name, event_name, location, venue,
    164         date, time, role, grade, comment, timestamp, artist_id, admin_id, listener_id,
    165         }
    166 R1_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    167 
    168 Lossless join: Релацијата може да се реконструира преку song_id
    169 Dependency preservation: FD1 е сочувана преку Songs
    170 
    171 ----------------------------------------------------------------------------------
    172 Playlists(playlist_id, cover, playlist_name, listener_id)
    173 pk: playlist_id
    174 
    175 R2 = R1 - {cover, playlist_name, listener_id}
    176 R2 = {user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
    177         follower_id, followee_id, profile_photo, email, username, full_name, password,
    178         title, genre, release_date, event_name, location, venue,
    179         date, time, role, grade, comment, timestamp, artist_id, admin_id}
    180 R2_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    181 
    182 Lossless join: Релацијата може да се реконструира преку playlist_id
    183 Dependency preservation: FD2 е сочувана преку Playlists
    184 
    185 ----------------------------------------------------------------------------------
    186 
    187 Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
    188 pk: event_id
    189 
    190 R3 = R2 - {event_name, location, venue, date, time, artist_id, admin_id}
    191 R3 = {user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
    192         follower_id, followee_id, profile_photo, email, username, full_name, password,
    193         title, genre, release_date, role, grade, comment, timestamp}
    194 R3_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    195 
    196 Lossless join: Релацијата може да се реконструира преку event_id
    197 Dependency preservation: FD3 е сочувана преку Events
     871. **Playlists(playlist_id, playlist_name, playlist_cover, listener_id)**
     88
     89R1 = R - {playlist_name, playlist_cover}
     90
     91R1 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, full_name, email, password, username, profile_photo, event_name, location, venue, date, time, link, album_id, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, role, grade, comment}
     92
     93Lossless join: Релацијата може да се реконструира преку join со `playlist_id`.
     94
     95Dependency preservation: FD5 е сочувана преку новата релација `Playlists`.
     96
     97
     982. **Songs(song_id, link, album_id)**
     99
     100R2 = R1 - {link}
     101
     102R2 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, full_name, email, password, username, profile_photo, event_name, location, venue, date, time,musical_entity_id, title, genre, me_cover, release_date, artist_id,non_admin_user_id, role, grade, comment}
     103
     104Lossless join: Релацијата може да се реконструира преку join со `song_id`
     105
     106Dependency preservation: FD4 е сочувана преку новата релација `Songs`
     107
     108
     1093. **Events(event_id, event_name, location, venue, date, time, user_id)**
     110
     111R3 = R2 - {event_name, location, venue, date, time}
     112
     113R3 = {playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, full_name, email, password, username, profile_photo, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, role, grade, comment}
     114
     115Lossless join: Релацијата може да се реконструира преку join со `event_id`
     116
     117Dependency preservation: FD6 е сочувана преку новата релација `Events`
     118
     119
     1204. **Admins(admin_id, user_id)**
     121
     122Lossless join: Релацијата може да се реконструира преку join со `admin_id`
     123
     124Dependency preservation: FD10 е сочувана преку новата релација `Admins`
     125
     126
     127
     128Добиени релации:
     1291. Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
     1302. Songs(song_id, link, album_id)
     1313. Events(event_id, event_name, location, venue, date, time, user_id)
     1324. Admins(admin_id, user_id)
     1335. R3 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, full_name, email, password, username, profile_photo, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, role, grade, comment }
     134
     135
    198136
    199137== Проверка за 3НФ
    200 
    201 
    202 
    203 1. Songs(song_id, musical_entity_id, link, album_id) -> има транзитивна завизсност преку
    204 FD18: musical_entity_id -> title, genre, release_date, artist_id
    205 FD10: album_id-> musical_entity_id,
    206 
    207 
    208 Декомпозиција:
    209 Songs(song_id,link, album_id)
    210 pk: song_id (fk -> Musical_Entities)
    211 Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
    212 pk: musical_entity_id
    213 Albums(album_id)
    214 pk: album_id (fk -> Musical_Entities)
    215 
    216 R4 = R3 - {title, genre, release_date, musical_entity_id}
    217 
    218 R4 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
    219         follower_id, followee_id, profile_photo, email, username, full_name, password,
    220         role, grade, comment, timestamp}
    221 R4_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    222 
    223 Lossless join: Релацијата може да се реконструира преку song_id
    224 Dependency preservation: Задржани се FD1, FD10 и FD18 преку Songs, Albums, Musical_Entities
    225 
    226 2. Playlists(playlist_id, cover, playlist_name, listener_id) -> задоволува 3НФ
    227 
    228 3. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> задоволува 3НФ
    229 
    230 
    231 Релации:
    232 
    233 1. Songs(song_id,link, album_id)
    234 2. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
    235 3. Albums(album_id)
    236 4. Playlists(playlist_id, cover, playlist_name, listener_id)
    237 5. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
    238 6. R4 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
    239         follower_id, followee_id, profile_photo, email, username, full_name, password,
    240         role, grade, comment, timestamp}
    241 
    242 
    243 
    244 
    245 
    246 4. FD17: R4 содржи атрибути кои зависат само од user_id, кој не е дел од примaрниот клуч -> нарушува 3НФ
    247 
    248 Users(user_id, profile_photo, email, username, full_name, password)
    249 pk: user_id
    250 R5 = R4 - {profile_photo, email, username, full_name, password}
    251 
    252 R5 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
    253         follower_id, followee_id, role, grade, comment, timestamp}
    254        
    255 R5_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    256 Lossless join: Релацијата може да се реконстроуира преку user_id
    257 Dependency preservation: FD17
    258 
    259 
    260 5. FD6: R5 содржи user_id кој зависи од non_admin_user_id, кој не е примарен клуч
    261 Non_Admin_Users(user_id)
    262 
    263 
    264 R6 = R5 - {user_id}
    265 R6 = {song_id, playlist_id, event_id, non_admin_user_id,
    266         follower_id, followee_id, role, grade, comment, timestamp}
    267 R6_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    268 
    269 Lossless join: Релацијата може да се реконстроуира преку non_admin_user_id
    270 Dependency preservation: FD6
    271 
    272 6. FD7: Admins(user_id)-> dali ova na primer treba da bide (admin_id, user_id)? Shto ke ni smeni toa?
    273 pk: user_id (fk -> Users)
    274 
    275 7. FD8: non_admin_user_id зависи од listener_id што не е дел од примарниот клуч
    276 Listeners(non_admin_user_id)
    277 pk: non_admin_user_id (fk -> Non_Admin_Users)
    278 
    279 R7 = R6 - {non_admin_user_id}
    280 R7 = {song_id, playlist_id, event_id,
    281         follower_id, followee_id, role, grade, comment, timestamp}
    282 R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    283 
    284 Lossless join: Релацијата може да се реконстроуира преку listener_id
    285 Dependency preservation: FD8
    286 
    287 
    288 8. FD9: non_admin_user_id зависи од artist_id што не е дел од примарниот клуч
    289 Artists(non_admin_user_id)
    290 pk: non_admin_user_id (fk -> Non_Admin_Users)
    291 
    292 9. role зависи од (artist_id, musical_entity_id) што не е целиот примарен клуч
    293 Artist_Contributions(artist_id, musical_entity_id, role)
    294 pk(artist_id, musical_entity_id) (fk -> Artists, fk -> Musical_Entities)
    295 
    296 R8 = R7 - {role}
    297 R7 = {song_id, playlist_id, event_id,
    298         follower_id, followee_id, grade, comment, timestamp}
    299 R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    300 
    301 Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities
    302 Dependency preservation: FD4
    303 
    304 10. grade, comment зависат од (listener_id, musical_entity_id), што не е целиот примaрен клуч
    305 Reviews(listener_id, musical_entity_id)
    306 pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
    307 
    308 R9 = R8 - {grade, comment}
    309 R9 = {song_id, playlist_id, event_id,follower_id, followee_id, timestamp}
    310 R9_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
    311 
    312 Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities
    313 
    314 Dependency preservation: FD5
    315 
    316 
    317 немаме како да стигнеме до истите релации, односно ќе имаме
    318 неклучни атрибути во глобалната релација.
    319 
    320 Relacii:
    321 1. Songs(song_id,link, album_id)
    322 2. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
    323 3. Albums(album_id)
    324 4. Playlists(playlist_id, cover, playlist_name, listener_id)
    325 5. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
    326 6. Users(user_id, profile_photo, email, username, full_name, password)
    327 7. Non_Admin_Users(user_id)
    328 8. Listeners(non_admin_user_id)
    329 9. Admins(user_id)
    330 10. Artist_Contributions(artist_id, musical_entity_id, role)
    331 11. Reviews(listener_id, musical_entity_id)
    332 12. R9 = {song_id, playlist_id, event_id,
    333         follower_id, followee_id, timestamp}
    334 
    335 
    336 == Декомпозиција на R9
    337 
    338 Релацијата R9 ги содржи преостанатите атрибути кои
    339 формираат сложени примарни клучеви за меѓусебните врски на ентитетите.
    340 Бидејќи овие врски претставуваат независни повеќевредносни факти,
    341 ги декомпонираме во посебни релации (од FD11 до FD16).
    342 
    343 1. Follows(follower_id, followee_id)
    344 pk: (follower_id, followee_id) (fk -> Non_Admin_Users, fk -> Non_Admin_Users)
    345 
    346 2. Saved_Playlists(listener_id, playlist_id)
    347 pk: (listener_id, playlist_id) (fk -> Listeners, fk -> Playlists)
    348 
    349 3. Playlist_Songs(playlist_id, song_id)
    350 pk: (playlist_id, song_id) (fk -> Playlists, fk -> Songs)
    351 
    352 4. Performs_At(event_id, artist_id)
    353 pk: (event_id, artist_id) (fk -> Events, fk -> Artists)
    354 
    355 5. Likes(listener_id, musical_entity_id)
    356 pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
    357 
    358 6. Listens (listener_id, song_id, timestamp)
    359 pk: (listener_id, song_id, timestamp) (fk -> Listeners, fk -> Songs)
    360 
    361 
    362 == Финални релации
    363 
    364 1. Songs(song_id,link, album_id) -> BCNF
    365 2. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id) -> BCNF
    366 3. Albums(album_id) -> BCNF
    367 4. Playlists(playlist_id, cover, playlist_name, listener_id) -> BCNF
    368 5. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> BCNF
    369 6. Users(user_id, profile_photo, email, username, full_name, password) -> BCNF
    370 7. Non_Admin_Users(user_id) -> BCNF
    371 8. Listeners(non_admin_user_id) -> BCNF
    372 9. Admins(user_id) -> BCNF
    373 10. Artists(non_admin_user_id) -> BCNF
    374 11. Artist_Contributions(artist_id, musical_entity_id, role) -> BCNF
    375 12. Reviews(listener_id, musical_entity_id) -> BCNF
    376 13. Follows(follower_id, followee_id) -> BCNF
    377 14. Saved_Playlists(listener_id, playlist_id) -> BCNF
    378 15. Playlist_Songs(playlist_id, song_id) -> BCNF
    379 16. Performs_At(event_id, artist_id) -> BCNF
    380 17. Likes(listener_id, musical_entity_id) -> BCNF
    381 18. Listens (listener_id, song_id, timestamp) -> BCNF
     138Поради постоењето на транзитивни зависности во добиените релации, можеме да заклучиме дека **е нарушена 3НФ**. На пример: `Playlists(playlist_id, playlist_name, playlist_cover, listener_id)` има транзитивна зависност преку `FD11: listener_id -> non_admin_user_id`
     139
     140== Декомпозиција по 3НФ
     141
     1421. `Playlists(playlist_id, playlist_name, playlist_cover, listener_id)` -> има транзитивна зависност преку `FD11: listener_id -> non_admin_user_id`
     143
     144Декомпозиција по FD11:
     145
     146**Listeners(listener_id, non_admin_user_id)** -> има транзитивна зависност преку `FD9: non_admin_user_id -> user_id`
     147
     148Декомпозиција по FD9:
     149
     150**Non_Admin_Users(non_admin_user_id, user_id)**
     151
     152**Listeners(listener_id)** - `listener_id` е всушност примарен клуч во релацијата `Listeners` и надворешен клуч во релацијата `Non_Admin_Users`;
     153
     154`Non_Admin_Users(non_admin_user_id, user_id)` ->  има транзитивна зависност преку `FD1: user_id -> profile_photo, email, username, full_name, password`
     155
     156Декомпозиција по FD1:
     157
     158**Users(user_id, profile_photo, email, username, full_name, password)**
     159
     160`Non_Admin_Users(non_admin_user_id)` - `non_admin_user_id` е всушност примарен клуч во релацијата `Non_Admin_Users` и надворешен клуч во релацијата `Users`
     161
     162R4 = R3 - {profile_photo, email, username, full_name, password}
     163R4 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, musical_entity_id, title, genre, me_cover, release_date, artist_id, non_admin_user_id, role, grade, comment}
     164
     165Lossless join: Релацијата може да се реконструира преку join со `user_id`
     166
     167Dependency preservation: FD1 е сочувана преку новата релација `Users`
     168
     1692. `Songs(song_id, link, album_id)` -> има транзитивна зависност преку `FD13: album_id -> musical_entity_id`
     170
     171Декомпозиција по FD13:
     172
     173**Albums(album_id, musical_entity_id)** -> има транзитивна преку `FD3: musical_entity_id-> title, genre, me_cover, release_date, artist_id`
     174
     175Lossless join: Релацијата може да се реконструира преку join со `album_id`
     176
     177Dependency preservation: FD13 е сочувана преку новата релација `Albums`
     178
     179Декомпозиција по FD3:
     180
     181**Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)**
     182
     183`Albums(album_id)` - `album_id` е всушност примарен клуч во релацијата `Albums` и надворешен клуч во релацијата `Musical_Entities`.
     184
     185R5 = R4 - {title, genre, me_cover, release_date}
     186
     187R5 = { playlist_id, event_id, song_id, timestamp, admin_id,user_id, listener_id, album_id, musical_entity_id, artist_id, non_admin_user_id, role, grade, comment}
     188Lossless join: Релацијата може да се реконструира преку join со `musical_entity_id`
     189
     190Dependency preservation: FD3 е сочувана преку новата релација `Musical_Entities`
     191
     192`Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)` -> има транзитивна зависност преку `FD12: artist_id -> non_admin_user_id`
     193
     194Декомпозиција по FD12:
     195
     196**Artists(artist_id)** - `artist_id` е всушност примарен клуч во релацијата `Artists` и надворешен клуч во релацијата `Non_Admin_Users`, каде е надворешен клуч во релацијата `Users`. Сите останати релации се добиени преку претходните декомпозиции.
     197
     198
     1993. `Events(event_id, event_name, location, venue, date, time, user_id)` -> има транзитивна зависност преку FD1, но веќе направивме декомпозиција по FD1.
     200
     2014. `Admins(admin_id, user_id)` -> има транзитивна зависност преку FD1 и бидејќи `admin_id` е
     202примарен клуч во `Admins` и надворешен клуч во `Users`, ја реформираме релацијата:
     203
     204**Admins(admin_id)**, каде `admin_id` е надворешен клуч во табелата `Users`.
     205
     206
     207Добиени релации:
     208
     2091. Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
     2102. Songs(song_id, link, album_id)
     2113. Events(event_id, event_name, location, venue, date, time, user_id)
     2124. Admins(admin_id)
     2135. Listeners(listener_id)
     2146. Non_Admin_Users(non_admin_user_id)
     2157. Users(user_id, profile_photo, email, username, full_name, password)
     2168. Albums(album_id)
     2179. Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
     21810. Artists(artist_id)
     21911. R5 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, musical_entity_id, artist_id, non_admin_user_id, role, grade, comment}
     220
     221
     2225. Бидејќи `role` е определен од `(artist_id, musical_entity_id)` -> имаме транзитивна зависност преку `FD7:(artist_id, musical_entity_id) -> role`
     223
     224Декомпозиција по FD7:
     225
     226**Artist_Contributions(artist_id, musical_entity_id, role)**
     227
     228R6 = R5 - {role}
     229R6 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, musical_entity_id, artist_id, non_admin_user_id, grade, comment}
     230
     231Lossless join: Релацијата може да се реконструира преку join со `(artist_id, musical_entity_id)`
     232
     233Dependency preservation: FD7 е сочувана преку новата релација `Musical_Entities`
     234
     2356. Бидејќи `grade`, `comment` се определени од `(listener_id, musical_entity_id)` -> имаме транзитивна зависност преку `FD8: (listener_id, musical_entity_id) -> grade, comment`
     236
     237Декомпозиција по FD8:
     238
     239**Reviews(listener_id, musical_entity_id, grade, comment)**
     240R7 = R6 - {grade, comment}
     241R7 = { playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, musical_entity_id, artist_id, non_admin_user_id}
     242
     243Lossless join: Релацијата може да се реконструира преку join со `(listener_id, musical_entity_id)`.
     244
     245Dependency preservation: FD8 е сочувана преку новата релација `Reviews`.
     246
     247
     248== Проверка за БКНФ:
     249
     250Примарните клучеви се болдирани.
     251
     2521. Playlists(**playlist_id**, playlist_name, playlist_cover, listener_id) -> **задоволува БКНФ**
     2532. Songs(**song_id**, link, album_id) -> **задоволува БКНФ**
     2543. Events(**event_id**, event_name, location, venue, date, time, user_id) -> **задоволува БКНФ**
     2554. Admins(**admin_id**) -> **задоволува БКНФ**
     2565. Listeners(**listener_id**) -> **задоволува БКНФ**
     2576. Non_Admin_Users(**non_admin_user_id**) -> **задоволува БКНФ**
     2587. Users(**user_id**, profile_photo, email, username, full_name, password) -> **задоволува БКНФ**
     2598. Albums(**album_id**) -> **задоволува БКНФ**
     2609. Musical_Entities(**musical_entity_id**, title, genre, me_cover, release_date, artist_id) -> **задоволува БКНФ**
     26110. Artist_Contributions(**artist_id, musical_entity_id**, role) -> **задоволува БКНФ**
     26211. Reviews(**listener_id, musical_entity_id**, grade, comment) -> **задоволува БКНФ**
     26312. Artists(**artist_id**) -> **задоволува БКНФ**
     26413. R7 = { **playlist_id, event_id, song_id, timestamp, admin_id, user_id, listener_id, album_id, musical_entity_id, artist_id, non_admin_user_id**}  -> **задоволува БКНФ**
     265
     266
     267
     268== Проверка за 4НФ
     269
     270Релацијата R7 **не ја задоволува 4НФ** бидејќи содржи мултивредносни зависности, како на пример `listener_id →→ song_id, timestamp`, што значи дека слушањата на песните се целосно независни од лајковите на песните.
     271
     272== Декомпозиција по 4Нф:
     273
     274- **Playlist_Songs (song_id, playlist_id)**
     275- **Performs_At (event_id, artist_id)**
     276- **Likes (listener_id, musical_entity_id)
     277- **Follows (follower_id, followee_id)**- во оваа релација `follower_id` и `followee_id` се всушност сложен примарен клуч и двете од нив се надворешни клучеви во релацијата `Non_Admin_Users`.
     278- **Saved_Playlists (listener_id, playlist_id)**
     279- **Listens (listener_id, song_id, timestamp)**
     280
     281Lossless join: Доколку направиме join по заедничките атрибути на овие релации можеме
     282да ја реконстроуираме R7.
     283
     284Dependency preservation: Новодобиените релации не претставуваат функционални зависности.
     285
     286
     287Финални релации:
     288
     2891. Playlists(**playlist_id**, playlist_name, playlist_cover, listener_id)
     2902. Songs(**song_id**, link, album_id)
     2913. Events(**event_id**, event_name, location, venue, date, time, user_id)
     2924. Admins(**admin_id**)
     2935. Listeners(**listener_id**)
     2946. Non_Admin_Users(**non_admin_user_id**)
     2957. Users(**user_id**, profile_photo, email, username, full_name, password)
     2968. Albums(**album_id**)
     2979. Musical_Entities(**musical_entity_id**, title, genre, me_cover, release_date, artist_id)
     29810. Artist_Contributions(**artist_id, musical_entity_id**, role)
     29911. Reviews(**listener_id, musical_entity_id**, grade, comment)
     30012. Artists(**artist_id**)
     30113. Playlist_Songs(**song_id, playlist_id**)
     30214. Performs_At (**event_id, artist_id**)
     30315. Likes(**listener_id, musical_entity_id**)
     30416. Follows(**follower_id, followee_id**)
     30517. Saved_Playlists (**listener_id, playlist_id**)
     30618. Listens (**listener_id, song_id, timestamp**)
     307
    382308
    383309
    384310== Заклучок
    385 Ги добивме истите релации од Фаза 2.
     311При нормализацијата ги добивме истите релации од Фаза 2. Ова значи дека базата била соодветно
     312моделирана.