| Version 10 (modified by , 8 days 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.
Функционални зависности:
- FD1: user_id -> profile_photo, email, username, full_name, password
- FD2: musical_entity_id -> title, genre, me_cover, release_date, artist_id
- FD3: song_id -> link, album_id
- FD4: playlist_id -> playlist_cover, playlist_name, listener_id
- FD5: event_id -> event_name, location, venue, date, time, user_id
- FD6: (artist_id, musical_entity_id) -> role
- FD7: (listener_id, musical_entity_id) -> grade, comment
- FD8: non_admin_user_id -> user_id
- FD9: admin_id -> user_id
- FD10: listener_id -> non_admin_user_id
- FD11: artist_id -> non_admin_user_id
- FD12: album_id -> musical_entity_id
- FD13: (listener_id,song_id,timestamp) -> /
Лево: 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
Глобална релација
R={ 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}
Покривачи
- playlist_id+ = {playlist_id, playlist_name, playlist_cover, listener_id, user_id, full_name, email, password, username, profile_photo} -> Не ги содржи сите атрибути
- event_id+ = {event_id, event_name, location, venue, date, time, user_id, full_name, email, password, username, profile_photo} -> Не ги содржи сите атрибути
- 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} -> Не ги содржи сите атрибути
- timestamp+ = {timestamp} -> Не ги содржи сите атрибути
- admin_id+ = {admin_id, user_id, full_name, email, password, username, profile_photo } -> Не ги содржи сите атрибути
Спојување Покривачи
Бидејќи атрибутите кои се наоѓаат само на левата страна не може да се изведат на никој друг начин, тие мора да бидат дел од примарниот клуч.
{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}
Покривачот составен од сите атрибути кои се наоѓаат само од левата страна ги содржи сите атрибути на глобалната релација. Всушност тоа ни е и минимален суперклуч. Во нашиот случај ова ни е единствениот кандидат клуч, па оттаму тоа ни е и примарниот клуч на релацијата.
Избран примарен клуч: {playlist_id, event_id, song_id, timestamp, admin_id}
Проверка за 1НФ
Бидејќи релацијата не содржи повеќевредносни атрибути, неуникатни атрибути, вредности од различен домен за еден атрибут, а притоа секоја редица е уникатно определена преку примарниот клуч, ја задоволува 1НФ.
Проверка за 2НФ
R не ја задоволува 2НФ поради постоење на парцијални зависности, како на пример playlist_name, playlist_cover, listener_id кои зависат само од playlist_id, а не од целиот примарен клуч.
Декомпозиција по 2НФ
Најпрво ги групираме атрибутите само според клучевите од кои зависат.
- playlist_id -> playlist_name, playlist_cover, listener_id
- song_id -> link, album_id
- event_id -> event_name, location, venue, date, time, user_id
- admin_id -> user_id
Декомпозиција во релации
- Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
R1 = R - {playlist_name, playlist_cover}
R1 = { 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}
Lossless join: Релацијата може да се реконструира преку join со playlist_id.
Dependency preservation: FD4 е сочувана преку новата релација Playlists.
- Songs(song_id, link, album_id)
R2 = R1 - {link}
R2 = { 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}
Lossless join: Релацијата може да се реконструира преку join со song_id
Dependency preservation: FD3 е сочувана преку новата релација Songs
- Events(event_id, event_name, location, venue, date, time, user_id)
R3 = R2 - {event_name, location, venue, date, time}
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}
Lossless join: Релацијата може да се реконструира преку join со event_id
Dependency preservation: FD5 е сочувана преку новата релација Events
- Admins(admin_id, user_id)
Lossless join: Релацијата може да се реконструира преку join со admin_id
Dependency preservation: FD9 е сочувана преку новата релација Admins
Добиени релации:
- Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
- Songs(song_id, link, album_id)
- Events(event_id, event_name, location, venue, date, time, user_id)
- Admins(admin_id, user_id)
- 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 }
Проверка за 3НФ
Поради постоењето на транзитивни зависности во добиените релации, можеме да заклучиме дека е нарушена 3НФ. На пример: Playlists(playlist_id, playlist_name, playlist_cover, listener_id) има транзитивна зависност преку FD10: listener_id -> non_admin_user_id
Декомпозиција по 3НФ
Playlists(playlist_id, playlist_name, playlist_cover, listener_id)-> има транзитивна зависност прекуFD10: listener_id -> non_admin_user_id
Декомпозиција по FD10:
Listeners(listener_id, non_admin_user_id) -> има транзитивна зависност преку FD8: non_admin_user_id -> user_id
Декомпозиција по FD8:
Non_Admin_Users(non_admin_user_id, user_id)
Listeners(listener_id) - listener_id е всушност примарен клуч во релацијата Listeners и надворешен клуч во релацијата Non_Admin_Users;
Non_Admin_Users(non_admin_user_id, user_id) -> има транзитивна зависност преку FD1: user_id -> profile_photo, email, username, full_name, password
Декомпозиција по FD1:
Users(user_id, profile_photo, email, username, full_name, password)
Non_Admin_Users(non_admin_user_id) - non_admin_user_id е всушност примарен клуч во релацијата Non_Admin_Users и надворешен клуч во релацијата Users
R4 = R3 - {profile_photo, email, username, full_name, password}
R4 = { 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}
Lossless join: Релацијата може да се реконструира преку join со user_id
Dependency preservation: FD1 е сочувана преку новата релација Users
Songs(song_id, link, album_id)-> има транзитивна зависност прекуFD12: album_id -> musical_entity_id
Декомпозиција по FD12:
Albums(album_id, musical_entity_id) -> има транзитивна преку FD2: musical_entity_id-> title, genre, me_cover, release_date, artist_id
Lossless join: Релацијата може да се реконструира преку join со album_id
Dependency preservation: FD12 е сочувана преку новата релација Albums
Декомпозиција по FD2:
Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
Albums(album_id) - album_id е всушност примарен клуч во релацијата Albums и надворешен клуч во релацијата Musical_Entities.
R5 = R4 - {title, genre, me_cover, release_date}
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}
Lossless join: Релацијата може да се реконструира преку join со musical_entity_id
Dependency preservation: FD2 е сочувана преку новата релација Musical_Entities
Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id) -> има транзитивна зависност преку FD11: artist_id -> non_admin_user_id
Декомпозиција по FD11:
Artists(artist_id) - artist_id е всушност примарен клуч во релацијата Artists и надворешен клуч во релацијата Non_Admin_Users, каде е надворешен клуч во релацијата Users. Сите останати релации се добиени преку претходните декомпозиции.
Events(event_id, event_name, location, venue, date, time, user_id)-> има транзитивна зависност преку FD1, но веќе направивме декомпозиција по FD1.
Admins(admin_id, user_id)-> има транзитивна зависност преку FD1 и бидејќиadmin_idе примарен клуч воAdminsи надворешен клуч воUsers, ја реформираме релацијата:
Admins(admin_id), каде admin_id е надворешен клуч во табелата Users.
Добиени релации:
- Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
- Songs(song_id, link, album_id)
- Events(event_id, event_name, location, venue, date, time, user_id)
- Admins(admin_id)
- Listeners(listener_id)
- Non_Admin_Users(non_admin_user_id)
- Users(user_id, profile_photo, email, username, full_name, password)
- Albums(album_id)
- Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
- Artists(artist_id)
- 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}
- Бидејќи
roleе определен од(artist_id, musical_entity_id)-> имаме транзитивна зависност прекуFD6:(artist_id, musical_entity_id) -> role
Декомпозиција по FD6:
Artist_Contributions(artist_id, musical_entity_id, role)
R6 = R5 - {role} R6 = { 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}
Lossless join: Релацијата може да се реконструира преку join со (artist_id, musical_entity_id)
Dependency preservation: FD6 е сочувана преку новата релација Artist_Contributions
- Бидејќи
grade,commentсе определени од(listener_id, musical_entity_id)-> имаме транзитивна зависност прекуFD7: (listener_id, musical_entity_id) -> grade, comment
Декомпозиција по FD7:
Reviews(listener_id, musical_entity_id, grade, comment) R7 = R6 - {grade, comment} 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}
Lossless join: Релацијата може да се реконструира преку join со (listener_id, musical_entity_id).
Dependency preservation: FD7 е сочувана преку новата релација Reviews.
Проверка за БКНФ:
Примарните клучеви се болдирани.
- Playlists(playlist_id, playlist_name, playlist_cover, listener_id) -> задоволува БКНФ
- Songs(song_id, link, album_id) -> задоволува БКНФ
- Events(event_id, event_name, location, venue, date, time, user_id) -> задоволува БКНФ
- Admins(admin_id) -> задоволува БКНФ
- Listeners(listener_id) -> задоволува БКНФ
- Non_Admin_Users(non_admin_user_id) -> задоволува БКНФ
- Users(user_id, profile_photo, email, username, full_name, password) -> задоволува БКНФ
- Albums(album_id) -> задоволува БКНФ
- Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id) -> задоволува БКНФ
- Artist_Contributions(artist_id, musical_entity_id, role) -> задоволува БКНФ
- Reviews(listener_id, musical_entity_id, grade, comment) -> задоволува БКНФ
- Artists(artist_id) -> задоволува БКНФ
- 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} -> задоволува БКНФ
Проверка за 4НФ
Релацијата R7 не ја задоволува 4НФ бидејќи содржи мултивредносни зависности, како на пример listener_id →→ song_id, timestamp, што значи дека слушањата на песните се целосно независни од лајковите на песните.
Декомпозиција по 4НФ:
- Playlist_Songs (song_id, playlist_id)
- Performs_At (event_id, artist_id)
- Likes (listener_id, musical_entity_id)
- Follows (follower_id, followee_id)- во оваа релација
follower_idиfollowee_idсе всушност сложен примарен клуч и двете од нив се надворешни клучеви во релацијатаNon_Admin_Users. - Saved_Playlists (listener_id, playlist_id)
- Listens (listener_id, song_id, timestamp)
Lossless join: Доколку направиме join по заедничките атрибути на овие релации можеме да ја реконстроуираме R7.
Dependency preservation: Новодобиените релации не претставуваат функционални зависности.
Финални релации:
- Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
- Songs(song_id, link, album_id)
- Events(event_id, event_name, location, venue, date, time, user_id)
- Admins(admin_id)
- Listeners(listener_id)
- Non_Admin_Users(non_admin_user_id)
- Users(user_id, profile_photo, email, username, full_name, password)
- Albums(album_id)
- Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
- Artist_Contributions(artist_id, musical_entity_id, role)
- Reviews(listener_id, musical_entity_id, grade, comment)
- Artists(artist_id)
- Playlist_Songs(song_id, playlist_id)
- Performs_At (event_id, artist_id)
- Likes(listener_id, musical_entity_id)
- Follows(follower_id, followee_id)
- Saved_Playlists (listener_id, playlist_id)
- Listens (listener_id, song_id, timestamp)
Заклучок
При нормализацијата ги добивме истите релации од Фаза 2. Ова значи дека базата била соодветно моделирана.
