Changes between Version 7 and Version 8 of Normalization


Ignore:
Timestamp:
04/21/26 01:00:58 (11 days ago)
Author:
221296
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v7 v8  
    9191To determine a candidate key of the universal de-normalized relation, we identify a minimal set of identifiers whose closure determines all attributes of R.
    9292
    93 Because the universal relation combines several independent components of the system (subscriptions, payments, support tickets, course-category assignments, quiz attempts, and certificates), the candidate key must include one identifier from each independent component that is not functionally determined by another component..
    94 {{{#!comment It is not correct to simply collect all identifiers, because some identifiers are functionally determined by others. For example:
    95 application_id → clinic_id
    96 listing_id → animal_id, admin_id
    97 animal_id → owner_id
    98 owner_id → client_id
    99 healthrecord_id → appointment_id, animal_id
    100 appointment_id → clinic_id, animal_id
    101 
    102 
    103 Therefore, attributes such as clinic_id, animal_id, appointment_id, admin_id, owner_id, and client_id do not need to appear explicitly in the candidate key if they can already be derived from other identifiers.
     93Because the universal relation combines several independent components of the system (subscriptions, payments, support tickets, course-category assignments, quiz attempts, and certificates), the candidate key must include one identifier from each independent component that is not functionally determined by another component.
     94
    10495}}}
    10596
     
    10798
    10899{{{
    109 K = {notification_id, application_id, listing_id, healthrecord_id, review_id, saved_user_id, saved_listing_id}
     100K = {payment_id, ticket_id, course_id, category_id, attempt_id, certificate_id}
    110101}}}
    111102
     
    114105=== Closure proof for K
    115106{{{
    116 Let K = {notification_id, application_id, listing_id, healthrecord_id, review_id, saved_user_id, saved_listing_id}
     107Let K = {payment_id, ticket_id, course_id, category_id, attempt_id, certificate_id}
    117108
    118109Compute K+:
    119 Start: K+ = K
     110Start: K+ = {payment_id, ticket_id, course_id, category_id, attempt_id, certificate_id}
     111
     112From FD6:
     113payment_id → user_id, subscription_id, amount
     114Add: user_id, subscription_id, amount
    120115
    121116From FD5:
    122 notification_id → notification_type, notification_message, notification_created_at, is_read, user_id
    123 Add: notification_type, notification_message, notification_created_at, is_read, user_id
     117subscription_id → plan_id, start_date, end_date, subscription_status
     118Add: plan_id, start_date, end_date, subscription_status
     119
     120From FD4:
     121plan_id → plan_name, price, duration_months, access_type
     122Add: plan_name, price, duration_months, access_type
    124123
    125124From FD1:
    126 user_id → username, email, name, surname, full_name, password_hash, user_created_at
    127 Add: username, email, name, surname, full_name, password_hash, user_created_at
     125user_id → first_name, last_name, email, password, role
     126Add: first_name, last_name, email, password, role
    128127
    129128From FD7:
    130 application_id → app_name, app_email, app_phone, app_city, app_address, submitted_at, app_status, reviewed_at, reviewed_by, denial_reason, clinic_id
    131 Add: app_name, app_email, app_phone, app_city, app_address, submitted_at, app_status, reviewed_at, reviewed_by, denial_reason, clinic_id
    132 
    133 From FD6:
    134 clinic_id → clinic_name, clinic_email, clinic_phone, clinic_address, clinic_location, clinic_city
    135 Add: clinic_name, clinic_email, clinic_phone, clinic_address, clinic_location, clinic_city
    136 
    137 From FD9:
    138 listing_id → listing_status, listing_created_at, price, listing_description, animal_id, admin_id
    139 Add: listing_status, listing_created_at, price, listing_description, animal_id, admin_id
     129ticket_id → admin_id, subject, description, ticket_status, created_at, user_id
     130Add: admin_id, subject, description, ticket_status, created_at
     131(user_id already belongs to K+)
    140132
    141133From FD3:
     
    144136
    145137From FD8:
    146 animal_id → animal_name, located_name, species, animal_type, breed, sex, date_of_birth, photo_url, owner_id
    147 Add: animal_name, located_name, species, animal_type, breed, sex, date_of_birth, photo_url, owner_id
    148 
    149 From FD4:
    150 owner_id → client_id
    151 Add: client_id
     138category_id → category_name, category_description
     139Add: category_name, category_description
     140
     141From FD9:
     142course_id → course_name, course_price, course_status, instructor_id
     143Add: course_name, course_price, course_status, instructor_id
    152144
    153145From FD2:
    154 client_id → user_id, is_blocked, blocked_at, blocked_reason
    155 Add: is_blocked, blocked_at, blocked_reason
     146instructor_id → user_id
    156147user_id already belongs to K+
    157148
     149From FD13:
     150attempt_id → user_id, quiz_id, score, attempt_date
     151Add: quiz_id, score, attempt_date
     152(user_id already belongs to K+)
     153
     154From FD12:
     155quiz_id → lesson_id, total_points, passing_score
     156Add: lesson_id, total_points, passing_score
     157
    158158From FD11:
    159 healthrecord_id → hr_type, hr_description, hr_date, animal_id, appointment_id
    160 Add: hr_type, hr_description, hr_date, appointment_id
    161 animal_id already belongs to K+
     159lesson_id → module_id, lesson_title, material
     160Add: module_id, lesson_title, material
    162161
    163162From FD10:
    164 appointment_id → date_time, appointment_status, notes, animal_id, clinic_id
    165 Add: date_time, appointment_status, notes
    166 animal_id and clinic_id already belong to K+
    167 
    168 From FD12:
    169 review_id → reviewer_id, rating, comment, review_created_at, updated_at, is_deleted
    170 Add: reviewer_id, rating, comment, review_created_at, updated_at, is_deleted
    171 
    172 From FD13:
    173 review_id → target_user_id
    174 Add: target_user_id
     163module_id → module_title, module_description, course_id
     164Add: module_title, module_description
     165(course_id already belongs to K+)
     166
     167From FD15:
     168certificate_id → enrollment_id, issue_date, certificate_code, certificate_status
     169Add: enrollment_id, issue_date, certificate_code, certificate_status
    175170
    176171From FD14:
    177 review_id → target_clinic_id
    178 Add: target_clinic_id
    179 }}}
    180 
    181 Therefore, K+ = R, so K is a superkey.
    182 
    183 K is also minimal, because removing any attribute from K would cause the loss of one independent component of the universal relation
    184 {{{#!comment
    185 * without notification_id, notification attributes cannot be derived
    186 * without application_id, application attributes cannot be derived
    187 * without listing_id, listing attributes cannot be derived
    188 * without healthrecord_id, health record attributes cannot be derived
    189 * without review_id, review attributes cannot be derived
    190 * without saved_user_id or saved_listing_id, the FavoriteListings relationship cannot be identified
    191 }}}
    192 
    193 So K is a candidate key.
     172enrollment_id → user_id, course_id, enroll_date, completion_status, progress_percentage
     173Add: enroll_date, completion_status, progress_percentage
     174(user_id and course_id already belong to K+)
     175}}}
     176
     177Therefore, K+ contains all attributes of the universal relation R, so K is a superkey.
     178
     179K is also minimal, because removing any attribute from K would cause the loss of at least one independent component of the universal relation:
     180- without payment_id, payment/subscription information is lost
     181- without ticket_id, support ticket information is lost
     182- without course_id or category_id, the course-category association is lost
     183- without attempt_id, quiz attempt and course content assessment information is lost
     184- without certificate_id, certificate and enrollment completion information is lost
     185
     186So, K is a candidate key..
    194187
    195188=== Chosen primary key
     
    197190
    198191{{{
    199 {notification_id, application_id, listing_id, healthrecord_id, review_id, saved_user_id, saved_listing_id}
     192K = {payment_id, ticket_id, course_id, category_id, attempt_id, certificate_id}
    200193}}}
    201194