wiki:Normalization

Нормализација и подобрувања на дизајнот

За табелите од нашата база на податоци, со цел разликување на самите 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}

Покривачи

  1. playlist_id+ = {playlist_id, playlist_name, playlist_cover, listener_id, user_id, full_name, email, password, username, profile_photo} -> Не ги содржи сите атрибути
  2. event_id+ = {event_id, event_name, location, venue, date, time, user_id, full_name, email, password, username, profile_photo} -> Не ги содржи сите атрибути
  3. 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} -> Не ги содржи сите атрибути
  4. timestamp+ = {timestamp} -> Не ги содржи сите атрибути
  5. 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

Декомпозиција во релации

  1. 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.

  1. 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

  1. 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

  1. Admins(admin_id, user_id)

Lossless join: Релацијата може да се реконструира преку join со admin_id

Dependency preservation: FD9 е сочувана преку новата релација Admins

Добиени релации:

  1. Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
  2. Songs(song_id, link, album_id)
  3. Events(event_id, event_name, location, venue, date, time, user_id)
  4. Admins(admin_id, user_id)
  5. 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НФ

  1. 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

  1. 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. Сите останати релации се добиени преку претходните декомпозиции.

  1. Events(event_id, event_name, location, venue, date, time, user_id) -> има транзитивна зависност преку FD1, но веќе направивме декомпозиција по FD1.
  1. Admins(admin_id, user_id) -> има транзитивна зависност преку FD1 и бидејќи admin_id е примарен клуч во Admins и надворешен клуч во Users, ја реформираме релацијата:

Admins(admin_id), каде admin_id е надворешен клуч во табелата Users.

Добиени релации:

  1. Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
  2. Songs(song_id, link, album_id)
  3. Events(event_id, event_name, location, venue, date, time, user_id)
  4. Admins(admin_id)
  5. Listeners(listener_id)
  6. Non_Admin_Users(non_admin_user_id)
  7. Users(user_id, profile_photo, email, username, full_name, password)
  8. Albums(album_id)
  9. Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
  10. Artists(artist_id)
  11. 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}
  1. Бидејќи 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

  1. Бидејќи 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.

Проверка за БКНФ:

Примарните клучеви се болдирани.

  1. Playlists(playlist_id, playlist_name, playlist_cover, listener_id) -> задоволува БКНФ
  2. Songs(song_id, link, album_id) -> задоволува БКНФ
  3. Events(event_id, event_name, location, venue, date, time, user_id) -> задоволува БКНФ
  4. Admins(admin_id) -> задоволува БКНФ
  5. Listeners(listener_id) -> задоволува БКНФ
  6. Non_Admin_Users(non_admin_user_id) -> задоволува БКНФ
  7. Users(user_id, profile_photo, email, username, full_name, password) -> задоволува БКНФ
  8. Albums(album_id) -> задоволува БКНФ
  9. Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id) -> задоволува БКНФ
  10. Artist_Contributions(artist_id, musical_entity_id, role) -> задоволува БКНФ
  11. Reviews(listener_id, musical_entity_id, grade, comment) -> задоволува БКНФ
  12. Artists(artist_id) -> задоволува БКНФ
  13. 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: Новодобиените релации не претставуваат функционални зависности.

Финални релации:

  1. Playlists(playlist_id, playlist_name, playlist_cover, listener_id)
  2. Songs(song_id, link, album_id)
  3. Events(event_id, event_name, location, venue, date, time, user_id)
  4. Admins(admin_id)
  5. Listeners(listener_id)
  6. Non_Admin_Users(non_admin_user_id)
  7. Users(user_id, profile_photo, email, username, full_name, password)
  8. Albums(album_id)
  9. Musical_Entities(musical_entity_id, title, genre, me_cover, release_date, artist_id)
  10. Artist_Contributions(artist_id, musical_entity_id, role)
  11. Reviews(listener_id, musical_entity_id, grade, comment)
  12. Artists(artist_id)
  13. Playlist_Songs(song_id, playlist_id)
  14. Performs_At (event_id, artist_id)
  15. Likes(listener_id, musical_entity_id)
  16. Follows(follower_id, followee_id)
  17. Saved_Playlists (listener_id, playlist_id)
  18. Listens (listener_id, song_id, timestamp)

Заклучок

При нормализацијата ги добивме истите релации од Фаза 2. Ова значи дека базата била соодветно моделирана.

Last modified 8 days ago Last modified on 02/20/26 12:01:24
Note: See TracWiki for help on using the wiki.