Changes between Version 3 and Version 4 of Normalization


Ignore:
Timestamp:
02/10/26 13:13:15 (3 weeks ago)
Author:
231136
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v3 v4  
    11= Нормализација
    2 За табелите од нашата база на податоци, со цел разликување на самите id за секој ентитет, ќе ги преименуваме id атрибутите во <име_на_релација>_id. Со тоа добиваме: user_id, non_admin_user_id, admin_id, listener_id, musical_entity_id, song_id, artist_id, event_id, album_id, playlist_id.
    3 
    4 === Функционални зависности
    5 **user_id** -> profile_photo, email, username, full_name, password[[br]]
    6 **musical_entity_id** -> title, genre, release_date, artist_id[[br]]
    7 **song_id** -> link, album_id[[br]]
    8 **playlist_id** -> cover, playlist_name, listener_id[[br]]
    9 **event_id** -> event_name, location, venue, date, time, artist_id, admin_id[[br]]
    10 **(artist_id, musical_entity_id)** -> role[[br]]
    11 **(listener_id, musical_entity_id)** -> grade, comment[[br]]
    12 **(listener_id, song_id)** -> timestamp[[br]]
    13 **non_admin_user_id** -> /[[br]]
    14 **admin_id** -> /[[br]]
    15 **listener_id** -> /[[br]]
    16 **artist_id** -> /[[br]]
    17 **album_id** -> /[[br]]
    18 **(listener_id, playlist_id)** -> /[[br]]
    19 **(playlist_id, song_id)** -> /[[br]]
    20 **(follower_id, followee_id)** -> /[[br]]
    21 **(event_id, artist_id)** -> /[[br]]
    22 **(listener_id, musical_entity_id)** -> /[[br]]
    23 
    24 **Лево:**[[br]]
    25 user_id,[[br]]
    26 musical_entity_id,[[br]]
    27 song_id,[[br]]
    28 playlist_id,[[br]]
    29 event_id,[[br]]
    30 non_admin_user_id,[[br]]
    31 follower_id,[[br]]
    32 followee_id[[br]]
    33 
    34 
    35 **Десно:**[[br]]
    36 profile_photo, email, username, full_name, password,[[br]]
    37 title, genre, release_date, link, cover, playlist_name,[[br]]
    38 event_name, location, venue, date, time, role, grade, comment,[[br]]
    39 timestamp[[br]]
    40 
    41 **Лево и десно:**[[br]]
    42 artist_id, [[br]]
    43 admin_id,[[br]]
    44 listener_id, [[br]]
    45 album_id[[br]]
    46 
    47 **Глобална релација** [[br]]
    48 **R**={ user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
    49 follower_id, followee_id, profile_photo, email, username, full_name, password,
    50 title, genre, release_date, link, cover, playlist_name, event_name, location, venue,
    51 date, time, role, grade, comment, timestamp, artist_id, admin_id, listener_id,
    52 album_id }
    53 
    54 == Покривачи
    55 1. **user_id+** = {user_id, profile_photo, email, username, full_name, password} -> **Не ги содржи сите атрибути**
    56 2. **musical_entity_id+** = {musical_entity_id, title, genre, release_date, artist_id, role} -> **Не ги содржи сите атрибути**
    57 3. **song_id+** = {song_id, link} -> **Не ги содржи сите атрибути**
    58 4. **playlist_id+** = {playlist_id, cover, playlist_name, listener_id} -> **Не ги содржи сите атрибути**
    59 5. **event_id+** = {event_id, event_name, location, venue, date, time, artist_id, admin_id} -> **Не ги содржи сите атрибути**
    60 6. **non_admin_user_id+** = {non_admin_user_id} -> **Не ги содржи сите атрибути**
    61 7. **follower_id+** = {follower_id} -> **Не ги содржи сите атрибути**
    62 8. **followee_id+** = {followee_id} -> **Не ги содржи сите атрибути**
    63 
    64 ==== Ги комбинираме покривачите за да дојдеме до сите атрибути:
    65 1. **{user_id, musical_entity_id}+** = {user_id,musical_entity_id, profile_photo, email, username, full_name, password, title, genre, release_date, artist_id, role} -> **Не ги содржи сите атрибути**
    66 
    67 2. **{user_id, musical_entity_id, song_id}+** = {user_id, musical_entity_id, song_id, profile_photo, email, username, full_name, password, title, genre, release_date, artist_id, role, link, album_id} -> **Не ги содржи сите атрибути**
    68                    
    69 3. **{user_id, musical_entity_id, song_id, playlist_id }+** = {user_id, musical_entity_id, song_id, playlist_id, profile_photo, email, username, full_name, password, title, genre, release_date, artist_id, role , link, album_id, cover, playlist_name, listener_id, grade, comment, timestamp } -> **Не ги содржи сите атрибути**
    70 
    71 
    72 4. **{user_id, musical_entity_id, song_id, playlist_id, event_id }+** = {user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, admin_id, profile_photo, email, username, full_name, password,title, genre, release_date,  role , link, album_id,cover, playlist_name, listener_id, grade, comment, timestamp,event_name, location, venue, date, time} -> **Не ги содржи сите атрибути**
    73  
    74 5. **{user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id}+**  = {user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id,  profile_photo, email, username, full_name, password,title, genre, release_date, role, link, album_id, cover, playlist_name, listener_id, grade, comment, timestamp, event_name, location, venue, date, time, admin_id } -> **Не ги содржи сите атрибути**
    75 
    76 6. **{user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id}+** = {user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id,  profile_photo, email, username, full_name, password,title, genre, release_date, role, link, album_id, cover, playlist_name, listener_id, grade, comment, timestamp, event_name, location, venue, date, time, admin_id } -> **Не ги содржи сите атрибути**
    77 
    78 
    79 7. **{user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id, followee_id}+** = {user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id, followee_id,  profile_photo, email, username, full_name, password,title, genre, release_date, role, link, album_idcover, playlist_name, listener_id, grade, comment, timestamp, event_name, location, venue, date, time, admin_id } -> **Не ги содржи сите атрибути**
    80 
    81 
    82 8. **{user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id, followee_id, non_admin_user_id}+** = {user_id, musical_entity_id, song_id, playlist_id, event_id, follower_id, followee_id, non_admin_user_id, profile_photo, email, username, full_name, password,title, genre, release_date, role, link, album_id, artist_id, cover, playlist_name, listener_id, grade, comment, timestamp, event_name, location, venue, date, time, admin_id } -> **Ги содржи сите атрибути**
    83 
    84 **Избран примарен клуч: {user_id, musical_entity_id, song_id, playlist_id, event_id, artist_id, follower_id, followee_id, non_admin_user_id}**[[br]]
    85 Релацијата ја задоволува **1НФ**, но не ја задоволува **2НФ** поради постоење на парцијални зависности.
    86 
    87 == Декомпозиција во 2НФ
    88 
    89 Најпрво ги групираме атрибутите само според клучевите од кои зависат.
    90 
    91 1. user_id-> profile_photo, email, username, full_name, password
    92 2. musical_entity_id-> title, genre, release_date, artist_id
    93 3. song_id-> link, album_id
    94 4. playlist_id-> cover, playlist_name, listener_id
    95 5. event_id-> event_name, location, venue, date, time, artist_id, admin_id
    96 
    97 == Декомпозиција во релации
     2
     3За табелите од нашата база на податоци, со цел разликување на самите id за секој ентитет,
     4ќе ги преименуваме id атрибутите во <име_на_релација>_id.
     5Со тоа добиваме: user_id, non_admin_user_id, admin_id, listener_id,
     6musical_entity_id, song_id, artist_id, event_id, album_id, playlist_id
     7
     8== Функционални зависности:
    989
    9910- user_id-> profile_photo, email, username, full_name, password
    10011- musical_entity_id-> title, genre, release_date, artist_id
    101 - song_id-> link, album_id
     12- song_id-> musical_entity_id, link, album_id
    10213- playlist_id-> cover, playlist_name, listener_id
    10314- event_id-> event_name, location, venue, date, time, artist_id, admin_id
    10415- (artist_id, musical_entity_id)-> role
    10516- (listener_id, musical_entity_id)-> grade, comment
    106 - (listener_id, song_id)-> timestamp
    107 
    108 **R1 - {user_id, profile_photo, email, username, full_name, password} -> BCNF**
    109 
    110 **R2 - {musical_entity_id, title, genre, release_date, artist_id} -> BCNF**
    111 
    112 **R3 - {song_id, link, album_id} -> BCNF**
    113 
    114 **R4 - {playlist_id, cover, playlist_name, listener_id} -> BCNF**
    115 
    116 **R5 - {event_id, event_name, location, venue, date, time, artist_id, admin_id} -> Не задоволува 3НФ**
    117 
    118 **R6  - {(artist_id, musical_entity_id), role} -> BCNF**
    119 
    120 **R7 - {(listener_id, musical_entity_id), grade, comment} -> BCNF**
    121 
    122 **R8 - {(listener_id, song_id), timestamp} -> BCNF**
    123 
    124 **R9 - {(follower_id, followee_id)} -> BCNF**
    125 
    126 **R10 - {(playlist_id, song_id)} -> BCNF**
    127 
    128 **R11 - {(listener_id, musical_entity_id)} -> BCNF**
    129 
    130 **R12 - {(listener_id, playlist_id)} -> BCNF**
    131 
    132 **R13 - {(event_id, artist_id)} -> BCNF**
    133 
    134 === Декомпозиција на R5
    135 
    136 Поради транзитивната зависност во **R5 (venue -> location)**, поточно секој venue секогаш ќе ја има истата локација,
    137 правиме декомпозиција во две релации:
    138 - **R5.1 {event_id, event_name, venue, date, time, artist_id, admin_id}**
    139 - **R14 {venue, location}**
     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
     581. Глобална релација
     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 } --32
     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
     941. song_id+ = {song_id, musical_entity_id, link, album_id} -> Не ги содржи сите атрибути
     952. playlist_id+ = {playlist_id, cover, playlist_name, listener_id} -> Не ги содржи сите атрибути
     963. event_id+ = {event_id, event_name, location, venue, date, time, artist_id, admin_id} -> Не ги содржи сите атрибути
     974. follower_id+ = {follower_id} -> Не ги содржи сите атрибути
     985. followee_id+ = {followee_id} -> Не ги содржи сите атрибути
     996. timestamp+ = {timestamp} -> Не ги содржи сите атрибути
     100
     101= Спојување Покривачи
     102
     103Бидејќи атрибутите кои се наоѓаат само на левата страна не може да се изведат на никој друг начин,
     104тие мора да бидат дел од примарниот клуч.
     105
     106{song_id,
     107playlist_id,
     108event_id,
     109follower_id,
     110followee_id,
     111timestamp}+ = {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:
     139FD1 -> musical_entity_id, link, album_id зависат само од song_id
     140FD2 -> cover, playlist_name, listener_id зависат само од playlist_id
     141FD3 -> event_name, location, venue, date, time, artist_id, admin_id зависат само од event_id
     142
     143
     144
     145
     146== Декомпозиција во 2НФ
     147
     148Најпрво ги групираме атрибутите само според клучевите од кои зависат.
     149
     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
     153
     154== Декомпозиција во релации
     155
     156-- Dali mi treba i song_id i musical_entity_id?
     157Songs(song_id, musical_entity_id, link, album_id)
     158pk: song_id
     159
     160R1 = R - {link, album_id}
     161R1 = {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        }
     166R1_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     167
     168Lossless join: Релацијата може да се реконструира преку song_id
     169Dependency preservation: FD1 е сочувана преку Songs
     170
     171----------------------------------------------------------------------------------
     172Playlists(playlist_id, cover, playlist_name, listener_id)
     173pk: playlist_id
     174
     175R2 = R1 - {cover, playlist_name, listener_id}
     176R2 = {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}
     180R2_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     181
     182Lossless join: Релацијата може да се реконструира преку playlist_id
     183Dependency preservation: FD2 е сочувана преку Playlists
     184
     185----------------------------------------------------------------------------------
     186
     187Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
     188pk: event_id
     189
     190R3 = R2 - {event_name, location, venue, date, time, artist_id, admin_id}
     191R3 = {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}
     194R3_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     195
     196Lossless join: Релацијата може да се реконструира преку event_id
     197Dependency preservation: FD3 е сочувана преку Events
    140198
    141199== Проверка за 3НФ
    142200
    143 **R1 - Клуч: user_id и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    144 
    145 **R2 - Клуч: musical_entity_id и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    146 
    147 **R3 - Клуч: song_id и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    148 
    149 **R4 - Клуч: playlist_id и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    150 
    151 **R5.1 - Клуч: event_id и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    152 
    153 **R6 - Клуч: (artist_id, musical_entity_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    154 
    155 **R7 - Клуч: (listener_id, musical_entity_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    156 
    157 **R8 - Клуч: (listener_id, song_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    158 
    159 **R9 - Клуч: (follower_id, followee_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    160 
    161 **R10 - Клуч: (playlist_id, song_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    162 
    163 **R11 - Клуч: (listener_id, musical_entity_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    164 
    165 **R12 - Клуч: (listener_id, playlist_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    166 
    167 **R13 - Клуч: (event_id, artist_id) и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    168 
    169 **R14 - Клуч: venue и сите атрибути зависат директно само од него. Релацијата е во BCNF**
    170 
    171 
    172 == Финални релации во BCNF
    173 1. **Users** {user_id, profile_photo, email, username, full_name, password}
    174 2. **Musical_Entities** {musical_entity_id, title, genre, release_date, artist_id}
    175 3. **Songs** {song_id, link, album_id}
    176 4. **Playlists** {playlist_id, cover, playlist_name, listener_id}
    177 5. **Events** {event_id, event_name, location, venue, date, time, artist_id, admin_id}
    178 6. **Artist_Contributions** {artist_id, musical_entity_id, role}
    179 7. **Reviews** {listener_id, musical_entity_id, grade, comment}
    180 8. **Listens** {listener_id, song_id, timestamp}
    181 9. **Follows** {follower_id, followee_id}
    182 10. **Playlist_Songs** {playlist_id, song_id}
    183 11. **Likes** {listener_id, musical_entity_id}
    184 12. **Saved_Playlists** {listener_id, playlist_id}
    185 13. **Performs_At** {event_id, artist_id}
    186 14. **Venues** {venue, location}
    187 
    188 ==  Дискусија на разликите од моделот во Фаза P2
    189 
    190 
    191 
    192 Процесот на нормализација го потврди концептуалниот дизајн од [[html(<a href="https://develop.finki.ukim.mk/projects/finkwave/wiki/RelationalDesign" ">Фаза 2</a>)]]. Ова значи
    193 дека ЕР дијаграмот е солидно сработен. Единствена нова релација која произлезе од
    194 нормализацијата е **R14 (Venues)**, од каде произлегува и функционалната зависност
    195 venue -> location
     201
     202
     2031. Songs(song_id, musical_entity_id, link, album_id) -> има транзитивна завизсност преку
     204FD18: musical_entity_id -> title, genre, release_date, artist_id
     205FD10: album_id-> musical_entity_id,
     206
     207
     208Декомпозиција:
     209Songs(song_id,link, album_id)
     210pk: song_id (fk -> Musical_Entities)
     211Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
     212pk: musical_entity_id
     213Albums(album_id)
     214pk: album_id (fk -> Musical_Entities)
     215
     216R4 = R3 - {title, genre, release_date, musical_entity_id}
     217
     218R4 = {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}
     221R4_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     222
     223Lossless join: Релацијата може да се реконструира преку song_id
     224Dependency preservation: Задржани се FD1, FD10 и FD18 преку Songs, Albums, Musical_Entities
     225
     2262. Playlists(playlist_id, cover, playlist_name, listener_id) -> задоволува 3НФ
     227
     2283. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> задоволува 3НФ
     229
     230
     231Релации:
     232
     2331. Songs(song_id,link, album_id)
     2342. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
     2353. Albums(album_id)
     2364. Playlists(playlist_id, cover, playlist_name, listener_id)
     2375. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
     2386. 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--- zavisi od da se smeni so opredelen od
     245
     2464. FD17: R4 содржи атрибути кои зависат само од user_id, кој не е дел од примaрниот клуч -> нарушува 3НФ
     247
     248Users(user_id, profile_photo, email, username, full_name, password)
     249pk: user_id
     250R5 = R4 - {profile_photo, email, username, full_name, password}
     251
     252R5 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
     253        follower_id, followee_id, role, grade, comment, timestamp}
     254       
     255R5_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     256Lossless join: Релацијата може да се реконстроуира преку user_id
     257Dependency preservation: FD17
     258
     259
     2605. FD6: R5 содржи user_id кој зависи од non_admin_user_id, кој не е примарен клуч
     261Non_Admin_Users(user_id)
     262
     263
     264R6 = R5 - {user_id}
     265R6 = {song_id, playlist_id, event_id, non_admin_user_id,
     266        follower_id, followee_id, role, grade, comment, timestamp}
     267R6_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     268
     269Lossless join: Релацијата може да се реконстроуира преку non_admin_user_id
     270Dependency preservation: FD6
     271
     2726. FD7: Admins(user_id)-> dali ova na primer treba da bide (admin_id, user_id)? Shto ke ni smeni toa?
     273pk: user_id (fk -> Users)
     274
     2757. FD8: non_admin_user_id зависи од listener_id што не е дел од примарниот клуч
     276Listeners(non_admin_user_id)
     277pk: non_admin_user_id (fk -> Non_Admin_Users)
     278
     279R7 = R6 - {non_admin_user_id}
     280R7 = {song_id, playlist_id, event_id,
     281        follower_id, followee_id, role, grade, comment, timestamp}
     282R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     283
     284Lossless join: Релацијата може да се реконстроуира преку listener_id
     285Dependency preservation: FD8
     286
     287
     2888. FD9: non_admin_user_id зависи од artist_id што не е дел од примарниот клуч
     289Artists(non_admin_user_id)
     290pk: non_admin_user_id (fk -> Non_Admin_Users)
     291
     2929. role зависи од (artist_id, musical_entity_id) што не е целиот примарен клуч
     293Artist_Contributions(artist_id, musical_entity_id, role)
     294pk(artist_id, musical_entity_id) (fk -> Artists, fk -> Musical_Entities)
     295
     296R8 = R7 - {role}
     297R7 = {song_id, playlist_id, event_id,
     298        follower_id, followee_id, grade, comment, timestamp}
     299R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     300
     301Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities
     302Dependency preservation: FD4
     303
     30410. grade, comment зависат од (listener_id, musical_entity_id), што не е целиот примaрен клуч
     305Reviews(listener_id, musical_entity_id)
     306pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
     307
     308R9 = R8 - {grade, comment}
     309R9 = {song_id, playlist_id, event_id,follower_id, followee_id, timestamp}
     310R9_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
     311
     312Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities
     313-- Како би било тука Lossless join, дали е можно бидејќи го отсртанивме listener_id
     314Dependency preservation: FD5
     315
     316-- Ако останат musical_entity_id, listener_id, admin_id, artist_id
     317немаме како да стигнеме до истите релации, односно ќе имаме
     318неклучни атрибути во глобалната релација.
     319
     320Relacii:
     3211. Songs(song_id,link, album_id)
     3222. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
     3233. Albums(album_id)
     3244. Playlists(playlist_id, cover, playlist_name, listener_id)
     3255. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
     3266. Users(user_id, profile_photo, email, username, full_name, password)
     3277. Non_Admin_Users(user_id)
     3288. Listeners(non_admin_user_id)
     3299. Admins(user_id)
     33010. Artist_Contributions(artist_id, musical_entity_id, role)
     33111. Reviews(listener_id, musical_entity_id)
     33212. 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
     3431. Follows(follower_id, followee_id)
     344pk: (follower_id, followee_id) (fk -> Non_Admin_Users, fk -> Non_Admin_Users)
     345
     3462. Saved_Playlists(listener_id, playlist_id)
     347pk: (listener_id, playlist_id) (fk -> Listeners, fk -> Playlists)
     348
     3493. Playlist_Songs(playlist_id, song_id)
     350pk: (playlist_id, song_id) (fk -> Playlists, fk -> Songs)
     351
     3524. Performs_At(event_id, artist_id)
     353pk: (event_id, artist_id) (fk -> Events, fk -> Artists)
     354
     3555. Likes(listener_id, musical_entity_id)
     356pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
     357
     3586. Listens (listener_id, song_id, timestamp)
     359pk: (listener_id, song_id, timestamp) (fk -> Listeners, fk -> Songs)
     360
     361
     362== Финални релации
     363
     3641. Songs(song_id,link, album_id) -> BCNF
     3652. Musical_Entities(musical_entity_id, title, genre, release_date, artist_id) -> BCNF
     3663. Albums(album_id) -> BCNF
     3674. Playlists(playlist_id, cover, playlist_name, listener_id) -> BCNF
     3685. Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> BCNF
     3696. Users(user_id, profile_photo, email, username, full_name, password) -> BCNF
     3707. Non_Admin_Users(user_id) -> BCNF
     3718. Listeners(non_admin_user_id) -> BCNF
     3729. Admins(user_id) -> BCNF
     37310. Artists(non_admin_user_id) -> BCNF
     37411. Artist_Contributions(artist_id, musical_entity_id, role) -> BCNF
     37512. Reviews(listener_id, musical_entity_id) -> BCNF
     37613. Follows(follower_id, followee_id) -> BCNF
     37714. Saved_Playlists(listener_id, playlist_id) -> BCNF
     37815. Playlist_Songs(playlist_id, song_id) -> BCNF
     37916. Performs_At(event_id, artist_id) -> BCNF
     38017. Likes(listener_id, musical_entity_id) -> BCNF
     38118. Listens (listener_id, song_id, timestamp) -> BCNF
     382
     383
     384== Заклучок
     385Ги добивме истите релации од Фаза 2.