| Version 4 (modified by , 3 weeks ago) ( diff ) |
|---|
Нормализација
За табелите од нашата база на податоци, со цел разликување на самите 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
Функционални зависности:
- user_id-> profile_photo, email, username, full_name, password
- musical_entity_id-> title, genre, release_date, artist_id
- song_id-> musical_entity_id, link, album_id
- playlist_id-> cover, playlist_name, listener_id
- event_id-> event_name, location, venue, date, time, artist_id, admin_id
- (artist_id, musical_entity_id)-> role
- (listener_id, musical_entity_id)-> grade, comment
- non_admin_user_id-> user_id
- admin_id-> user_id
- listener_id-> non_admin_user_id
- artist_id-> non_admin_user_id
- album_id-> musical_entity_id
- (listener_id, playlist_id)-> /
- (playlist_id, song_id)-> /
- (follower_id, followee_id)-> /
- (event_id, artist_id)-> /
- (listener_id, musical_entity_id)-> /
- (listener_id, song_id, timestamp)-> /
Лево:
- song_id,
- playlist_id,
- event_id,
- follower_id,
- followee_id,
- timestamp
Десно:
- profile_photo, email, username, full_name, password,
- title, genre, release_date, link, cover, playlist_name,
- event_name, location, venue, date, time, role, grade, comment,
- timestamp
Лево и десно:
- user_id,
- musical_entity_id,
- artist_id,
- admin_id,
- listener_id,
- album_id
- Глобална релација
R={ user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, title, genre, release_date, link, cover, playlist_name, event_name, location, venue, date, time, role, grade, comment, timestamp, artist_id, admin_id, listener_id, album_id } --32
Функционални зависности:
- FD1: song_id-> musical_entity_id,link, album_id
- FD2: playlist_id-> cover, playlist_name, listener_id
- FD3: event_id-> event_name, location, venue, date, time, artist_id, admin_id
- FD4: (artist_id, musical_entity_id)-> role
- FD5: (listener_id, musical_entity_id)-> grade, comment
- FD6: non_admin_user_id-> user_id
- FD7: admin_id-> user_id
- FD8: listener_id-> non_admin_user_id
- FD9: artist_id-> non_admin_user_id
- FD10: album_id-> musical_entity_id
- FD11: (listener_id, playlist_id)-> /
- FD12: (playlist_id, song_id)-> /
- FD13: (follower_id, followee_id)-> /
- FD14: (event_id, artist_id)-> /
- FD15: (listener_id, musical_entity_id)-> /
- FD16: (listener_id, song_id, timestamp)-> /
- FD17: user_id -> profile_photo, email, username, full_name, password
- FD18: musical_entity_id -> title, genre, release_date, artist_id
- Покривачи
- song_id+ = {song_id, musical_entity_id, link, album_id} -> Не ги содржи сите атрибути
- playlist_id+ = {playlist_id, cover, playlist_name, listener_id} -> Не ги содржи сите атрибути
- event_id+ = {event_id, event_name, location, venue, date, time, artist_id, admin_id} -> Не ги содржи сите атрибути
- follower_id+ = {follower_id} -> Не ги содржи сите атрибути
- followee_id+ = {followee_id} -> Не ги содржи сите атрибути
- timestamp+ = {timestamp} -> Не ги содржи сите атрибути
Спојување Покривачи
Бидејќи атрибутите кои се наоѓаат само на левата страна не може да се изведат на никој друг начин, тие мора да бидат дел од примарниот клуч.
{song_id, playlist_id, event_id, follower_id, followee_id, timestamp}+ = {song_id, playlist_id, event_id, follower_id, followee_id,
link, album_id, cover, playlist_name, listener_id, musical_entity_id event_name, location, venue, date, time, artist_id, admin_id, user_id, non_admin_user_id, profile_photo, email, username, full_name, password, title, genre, release_date, role, grade, comment, timestamp}
Покривачот составен од сите атрибути кои се наоѓаат само од левата страна ги содржи сите атрибути на глобалната релација. Всушност тоа ни е и минимален суперклуч. Во нашиот случај ова ни е единствениот кандидат клуч, па оттаму тоа ни е и примарниот клуч на релацијата.
Избран примарен клуч: {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Бидејќи релацијата не содржи повеќевредносни атрибути, неуникатни атрибути, вредности од различен домен за еден атрибут, а притоа секоја редица е уникатно определена преку примарниот клуч, ја задоволува 1НФ, но не ја задоволува 2НФ поради постоење на парцијални зависности.
Идентификувани парцијални зависности што ја нарушуваат 2NF: FD1 -> musical_entity_id, link, album_id зависат само од song_id FD2 -> cover, playlist_name, listener_id зависат само од playlist_id FD3 -> event_name, location, venue, date, time, artist_id, admin_id зависат само од event_id
Декомпозиција во 2НФ
Најпрво ги групираме атрибутите само според клучевите од кои зависат.
- song_id-> musical_entity_id, link, album_id
- playlist_id-> cover, playlist_name, listener_id
- event_id-> event_name, location, venue, date, time, artist_id, admin_id
Декомпозиција во релации
-- Dali mi treba i song_id i musical_entity_id? Songs(song_id, musical_entity_id, link, album_id) pk: song_id
R1 = R - {link, album_id} R1 = {user_id, song_id, musical_entity_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, title, genre, release_date, cover, playlist_name, event_name, location, venue, date, time, role, grade, comment, timestamp, artist_id, admin_id, listener_id, }
R1_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконструира преку song_id Dependency preservation: FD1 е сочувана преку Songs
Playlists(playlist_id, cover, playlist_name, listener_id) pk: playlist_id
R2 = R1 - {cover, playlist_name, listener_id} R2 = {user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, title, genre, release_date, event_name, location, venue, date, time, role, grade, comment, timestamp, artist_id, admin_id}
R2_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконструира преку playlist_id Dependency preservation: FD2 е сочувана преку Playlists
Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) pk: event_id
R3 = R2 - {event_name, location, venue, date, time, artist_id, admin_id} R3 = {user_id, musical_entity_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, title, genre, release_date, role, grade, comment, timestamp}
R3_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконструира преку event_id Dependency preservation: FD3 е сочувана преку Events
Проверка за 3НФ
- Songs(song_id, musical_entity_id, link, album_id) -> има транзитивна завизсност преку
FD18: musical_entity_id -> title, genre, release_date, artist_id FD10: album_id-> musical_entity_id,
Декомпозиција: Songs(song_id,link, album_id) pk: song_id (fk -> Musical_Entities) Musical_Entities(musical_entity_id, title, genre, release_date, artist_id) pk: musical_entity_id Albums(album_id) pk: album_id (fk -> Musical_Entities)
R4 = R3 - {title, genre, release_date, musical_entity_id}
R4 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, role, grade, comment, timestamp}
R4_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконструира преку song_id Dependency preservation: Задржани се FD1, FD10 и FD18 преку Songs, Albums, Musical_Entities
- Playlists(playlist_id, cover, playlist_name, listener_id) -> задоволува 3НФ
- Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> задоволува 3НФ
Релации:
- Songs(song_id,link, album_id)
- Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
- Albums(album_id)
- Playlists(playlist_id, cover, playlist_name, listener_id)
- Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
- R4 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, profile_photo, email, username, full_name, password, role, grade, comment, timestamp}
--- zavisi od da se smeni so opredelen od
- FD17: R4 содржи атрибути кои зависат само од user_id, кој не е дел од примaрниот клуч -> нарушува 3НФ
Users(user_id, profile_photo, email, username, full_name, password) pk: user_id R5 = R4 - {profile_photo, email, username, full_name, password}
R5 = {user_id, song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, role, grade, comment, timestamp}
R5_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp} Lossless join: Релацијата може да се реконстроуира преку user_id Dependency preservation: FD17
- FD6: R5 содржи user_id кој зависи од non_admin_user_id, кој не е примарен клуч
Non_Admin_Users(user_id)
R6 = R5 - {user_id} R6 = {song_id, playlist_id, event_id, non_admin_user_id,
follower_id, followee_id, role, grade, comment, timestamp}
R6_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконстроуира преку non_admin_user_id Dependency preservation: FD6
- FD7: Admins(user_id)-> dali ova na primer treba da bide (admin_id, user_id)? Shto ke ni smeni toa?
pk: user_id (fk -> Users)
- FD8: non_admin_user_id зависи од listener_id што не е дел од примарниот клуч
Listeners(non_admin_user_id) pk: non_admin_user_id (fk -> Non_Admin_Users)
R7 = R6 - {non_admin_user_id} R7 = {song_id, playlist_id, event_id,
follower_id, followee_id, role, grade, comment, timestamp}
R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконстроуира преку listener_id Dependency preservation: FD8
- FD9: non_admin_user_id зависи од artist_id што не е дел од примарниот клуч
Artists(non_admin_user_id) pk: non_admin_user_id (fk -> Non_Admin_Users)
- role зависи од (artist_id, musical_entity_id) што не е целиот примарен клуч
Artist_Contributions(artist_id, musical_entity_id, role) pk(artist_id, musical_entity_id) (fk -> Artists, fk -> Musical_Entities)
R8 = R7 - {role} R7 = {song_id, playlist_id, event_id,
follower_id, followee_id, grade, comment, timestamp}
R7_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities Dependency preservation: FD4
- grade, comment зависат од (listener_id, musical_entity_id), што не е целиот примaрен клуч
Reviews(listener_id, musical_entity_id) pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
R9 = R8 - {grade, comment} R9 = {song_id, playlist_id, event_id,follower_id, followee_id, timestamp} R9_pk = {song_id, playlist_id, event_id, follower_id, followee_id, timestamp}
Lossless join: Релацијата може да се реконстроуира преку song_id -> Musical_Entities -- Како би било тука Lossless join, дали е можно бидејќи го отсртанивме listener_id Dependency preservation: FD5
-- Ако останат musical_entity_id, listener_id, admin_id, artist_id немаме како да стигнеме до истите релации, односно ќе имаме неклучни атрибути во глобалната релација.
Relacii:
- Songs(song_id,link, album_id)
- Musical_Entities(musical_entity_id, title, genre, release_date, artist_id)
- Albums(album_id)
- Playlists(playlist_id, cover, playlist_name, listener_id)
- Events(event_id, event_name, location, venue, date, time, artist_id, admin_id)
- Users(user_id, profile_photo, email, username, full_name, password)
- Non_Admin_Users(user_id)
- Listeners(non_admin_user_id)
- Admins(user_id)
- Artist_Contributions(artist_id, musical_entity_id, role)
- Reviews(listener_id, musical_entity_id)
- R9 = {song_id, playlist_id, event_id,
follower_id, followee_id, timestamp}
Декомпозиција на R9
Релацијата R9 ги содржи преостанатите атрибути кои формираат сложени примарни клучеви за меѓусебните врски на ентитетите. Бидејќи овие врски претставуваат независни повеќевредносни факти, ги декомпонираме во посебни релации (од FD11 до FD16).
- Follows(follower_id, followee_id)
pk: (follower_id, followee_id) (fk -> Non_Admin_Users, fk -> Non_Admin_Users)
- Saved_Playlists(listener_id, playlist_id)
pk: (listener_id, playlist_id) (fk -> Listeners, fk -> Playlists)
- Playlist_Songs(playlist_id, song_id)
pk: (playlist_id, song_id) (fk -> Playlists, fk -> Songs)
- Performs_At(event_id, artist_id)
pk: (event_id, artist_id) (fk -> Events, fk -> Artists)
- Likes(listener_id, musical_entity_id)
pk: (listener_id, musical_entity_id) (fk -> Listeners, fk -> Musical_Entities)
- Listens (listener_id, song_id, timestamp)
pk: (listener_id, song_id, timestamp) (fk -> Listeners, fk -> Songs)
Финални релации
- Songs(song_id,link, album_id) -> BCNF
- Musical_Entities(musical_entity_id, title, genre, release_date, artist_id) -> BCNF
- Albums(album_id) -> BCNF
- Playlists(playlist_id, cover, playlist_name, listener_id) -> BCNF
- Events(event_id, event_name, location, venue, date, time, artist_id, admin_id) -> BCNF
- Users(user_id, profile_photo, email, username, full_name, password) -> BCNF
- Non_Admin_Users(user_id) -> BCNF
- Listeners(non_admin_user_id) -> BCNF
- Admins(user_id) -> BCNF
- Artists(non_admin_user_id) -> BCNF
- Artist_Contributions(artist_id, musical_entity_id, role) -> BCNF
- Reviews(listener_id, musical_entity_id) -> BCNF
- Follows(follower_id, followee_id) -> BCNF
- Saved_Playlists(listener_id, playlist_id) -> BCNF
- Playlist_Songs(playlist_id, song_id) -> BCNF
- Performs_At(event_id, artist_id) -> BCNF
- Likes(listener_id, musical_entity_id) -> BCNF
- Listens (listener_id, song_id, timestamp) -> BCNF
Заклучок
Ги добивме истите релации од Фаза 2.
