| 201 | | R does not satisfy 2NF because it has a composite primary key and many non-key attributes depend only on part of that key rather than on the whole key. |
| 202 | | |
| 203 | | Examples: |
| 204 | | * listing_id → listing_status, listing_created_at, price, listing_description |
| 205 | | * animal_id → animal_name, species, breed, sex, date_of_birth, photo_url, owner_id |
| 206 | | * clinic_id → clinic_name, clinic_email, clinic_phone, clinic_address, clinic_location, clinic_city |
| 207 | | * review_id → reviewer_id, rating, comment, review_created_at, updated_at, is_deleted |
| 208 | | * notification_id → notification_type, notification_message, notification_created_at, is_read, user_id |
| | 202 | R does not satisfy 2NF because it has a composite candidate key and many non-key attributes depend only on part of that key, instead of depending on the whole key. |
| | 203 | |
| | 204 | Examples of partial dependencies are: |
| | 205 | * payment_id → user_id, subscription_id, amount |
| | 206 | * ticket_id → user_id, admin_id, subject, ticket_description, ticket_status, created_at |
| | 207 | * course_id → course_name, course_price, course_status, instructor_id |
| | 208 | * category_id → category_name, category_description |
| | 209 | * attempt_id → user_id, quiz_id, score, attempt_date |
| | 210 | * certificate_id → enrollment_id, issue_date, certificate_code, certificate_status |
| 215 | | * user_id → username, email, name, surname, full_name, password_hash, user_created_at |
| 216 | | * client_id → user_id, is_blocked, blocked_at, blocked_reason |
| 217 | | * admin_id → user_id |
| 218 | | * owner_id → client_id |
| 219 | | * notification_id → notification_type, notification_message, notification_created_at, is_read, user_id |
| 220 | | * clinic_id → clinic_name, clinic_email, clinic_phone, clinic_address, clinic_location, clinic_city |
| 221 | | * application_id → app_name, app_email, app_phone, app_city, app_address, submitted_at, app_status, reviewed_at, reviewed_by, denial_reason, clinic_id |
| 222 | | * animal_id → animal_name, located_name, species, animal_type, breed, sex, date_of_birth, photo_url, owner_id |
| 223 | | * listing_id → listing_status, listing_created_at, price, listing_description, animal_id, admin_id |
| 224 | | * appointment_id → date_time, appointment_status, notes, animal_id, clinic_id |
| 225 | | * healthrecord_id → hr_type, hr_description, hr_date, animal_id, appointment_id |
| 226 | | * review_id → reviewer_id, rating, comment, review_created_at, updated_at, is_deleted |
| 227 | | * review_id → target_user_id / target_clinic_id |
| 228 | | * FavoriteListings has key (saved_user_id, saved_listing_id) only |
| | 217 | To remove partial dependencies, the attributes are grouped according to the determinants from the functional dependencies: |
| | 218 | |
| | 219 | - user_id → first_name, last_name, email, password, role |
| | 220 | - instructor_id → user_id |
| | 221 | - admin_id → user_id |
| | 222 | - plan_id → plan_name, price, duration_months, plan_description, access_type |
| | 223 | - subscription_id → user_id, plan_id, start_date, end_date, subscription_status |
| | 224 | - payment_id → user_id, subscription_id, amount |
| | 225 | - ticket_id → user_id, admin_id, subject, ticket_description, ticket_status, created_at |
| | 226 | - category_id → category_name, category_description |
| | 227 | - course_id → course_name, course_price, course_status, instructor_id |
| | 228 | - module_id → course_id, module_title, module_description |
| | 229 | - lesson_id → module_id, lesson_title, material |
| | 230 | - quiz_id → lesson_id, total_points, passing_score |
| | 231 | - attempt_id → user_id, quiz_id, score, attempt_date |
| | 232 | - enrollment_id → user_id, course_id, enroll_date, completion_status, progress_percentage |
| | 233 | - certificate_id → enrollment_id, issue_date, certificate_code, certificate_status |
| | 234 | The relation CourseCategory has composite key (course_id, category_id) and no additional non-trivial functional dependencies. |
| 231 | | * Users(user_id, username, email, name, surname, full_name, password_hash, user_created_at) |
| 232 | | * Clients(client_id, user_id, is_blocked, blocked_at, blocked_reason) |
| 233 | | * Admins(admin_id, user_id) |
| 234 | | * Owners(owner_id, client_id) |
| 235 | | * Notifications(notification_id, user_id, notification_type, notification_message, notification_created_at, is_read) |
| 236 | | * VetClinics(clinic_id, clinic_name, clinic_email, clinic_phone, clinic_address, clinic_location, clinic_city) |
| 237 | | * VetClinicApplications(application_id, clinic_id, app_name, app_email, app_phone, app_city, app_address, submitted_at, app_status, reviewed_at, reviewed_by, denial_reason) |
| 238 | | * Animals(animal_id, owner_id, animal_name, located_name, species, animal_type, breed, sex, date_of_birth, photo_url) |
| 239 | | * Listings(listing_id, admin_id, animal_id, listing_status, listing_created_at, price, listing_description) |
| 240 | | * Appointments(appointment_id, clinic_id, animal_id, date_time, appointment_status, notes) |
| 241 | | * HealthRecords(healthrecord_id, appointment_id, animal_id, hr_type, hr_description, hr_date) |
| 242 | | * Reviews(review_id, reviewer_id, rating, comment, review_created_at, updated_at, is_deleted) |
| 243 | | * FavoriteListings(saved_user_id, saved_listing_id) |
| | 237 | After removing the partial dependencies, we obtain the following relations: |
| | 238 | |
| | 239 | - UserEntity(user_id, first_name, last_name, email, password, role) |
| | 240 | - Users(user_id) |
| | 241 | - Administrators(admin_id, user_id) |
| | 242 | - Instructors(instructor_id, user_id) |
| | 243 | |
| | 244 | - SubscriptionPlan(plan_id, plan_name, price, duration_months, plan_description, access_type) |
| | 245 | - UserSubscription(subscription_id, user_id, plan_id, start_date, end_date, subscription_status) |
| | 246 | - Payment(payment_id, user_id, subscription_id, amount) |
| | 247 | |
| | 248 | - SupportTicket(ticket_id, user_id, admin_id, subject, ticket_description, ticket_status, created_at) |
| | 249 | |
| | 250 | - Category(category_id, category_name, category_description) |
| | 251 | - Course(course_id, course_name, course_price, course_status, instructor_id) |
| | 252 | - CourseCategory(course_id, category_id) |
| | 253 | |
| | 254 | - Module(module_id, course_id, module_title, module_description) |
| | 255 | - Lesson(lesson_id, module_id, lesson_title, material) |
| | 256 | - Quiz(quiz_id, lesson_id, total_points, passing_score) |
| | 257 | - QuizAttempt(attempt_id, user_id, quiz_id, score, attempt_date) |
| | 258 | |
| | 259 | - Enrollment(enrollment_id, user_id, course_id, enroll_date, completion_status, progress_percentage) |
| | 260 | - Certificate(certificate_id, enrollment_id, issue_date, certificate_code, certificate_status) |