| | 325 | `UserEntity`(user_id, first_name, last_name, email, password, role) |
| | 326 | Users(user_id) |
| | 327 | Administrators(admin_id, user_id) |
| | 328 | Instructors(instructor_id, user_id) |
| | 329 | |
| | 330 | SubscriptionPlan(plan_id, plan_name, price, duration_months, plan_description, access_type) |
| | 331 | UserSubscription(subscription_id, user_id, plan_id, start_date, end_date, subscription_status) |
| | 332 | Payment(payment_id, user_id, subscription_id, amount) |
| | 333 | |
| | 334 | SupportTicket(ticket_id, user_id, admin_id, subject, ticket_description, ticket_status, created_at) |
| | 335 | |
| | 336 | Category(category_id, category_name, category_description) |
| | 337 | Course(course_id, course_name, course_price, course_status, instructor_id) |
| | 338 | CourseCategory(course_id, category_id) |
| | 339 | |
| | 340 | Module(module_id, course_id, module_title, module_description) |
| | 341 | Lesson(lesson_id, module_id, lesson_title, material) |
| | 342 | Quiz(quiz_id, lesson_id, total_points, passing_score) |
| | 343 | QuizAttempt(attempt_id, user_id, quiz_id, score, attempt_date) |
| | 344 | |
| | 345 | Enrollment(enrollment_id, user_id, course_id, enroll_date, completion_status, progress_percentage) |
| | 346 | Certificate(certificate_id, enrollment_id, issue_date, certificate_code, certificate_status) |
| | 347 | |
| | 348 | All resulting relations satisfy 3NF because for every non-trivial functional dependency X → Y inside a relation, X is a key of that relation, or the dependent attributes are stored in a separate relation determined by their own key. |
| | 349 | |
| | 350 | == Check for BCNF |
| | 351 | Each resulting relation is also in BCNF, because in every non-trivial functional dependency within a relation, the determinant is a superkey of that relation. |
| | 352 | * `UserEntity`: user_id is key → BCNF |
| | 353 | * `Users`: user_id is key → BCNF |
| | 354 | * `Administrators`: admin_id is key → BCNF |
| | 355 | * `Instructors`: instructor_id is key → BCNF |
| | 356 | * `SubscriptionPlan`: plan_id is key → BCNF |
| | 357 | * `UserSubscription`: subscription_id is key → BCNF |
| | 358 | * `Payment`: payment_id is key → BCNF |
| | 359 | * `SupportTicket`: ticket_id is key → BCNF |
| | 360 | * `Category`: category_id is key → BCNF |
| | 361 | * `Course`: course_id is key → BCNF |
| | 362 | * `CourseCategory`: (course_id, category_id) is composite key → BCNF |
| | 363 | * `Module`: module_id is key → BCNF |
| | 364 | * `Lesson`: lesson_id is key → BCNF |
| | 365 | * `Quiz`: quiz_id is key → BCNF |
| | 366 | * `QuizAttempt`: attempt_id is key → BCNF |
| | 367 | * `Enrollment`: enrollment_id is key → BCNF |
| | 368 | * `Certificate`: certificate_id is key → BCNF |
| | 369 | {{{Therefore, the resulting schema satisfies BCNF.}}} |
| | 370 | |
| | 371 | == Check for 4NF (multivalued dependencies) |
| | 372 | No additional non-trivial multivalued dependencies are identified in the resulting schema. |
| | 373 | |
| | 374 | The many-to-many relationship between Course and Category is already decomposed into the separate relation: |
| | 375 | |
| | 376 | CourseCategory(course_id, category_id) |
| | 377 | |
| | 378 | This relation contains only the composite key and no additional descriptive attributes, so no further decomposition is required. |
| | 379 | |
| | 380 | All other relations describe a single entity or relationship around one key, and no independent multi-valued facts are stored together in the same relation. |
| | 381 | |
| | 382 | {{{Therefore, the schema satisfies 4NF.}}} |
| | 383 | |
| | 384 | == Final relations |
| | 385 | Final relations |
| | 386 | |
| | 387 | After applying normalization up to 4NF, the final normalized schema consists of the following relations: |
| | 388 | |
| | 389 | {{{ |
| 347 | | |
| 348 | | All resulting relations satisfy 3NF because for every non-trivial functional dependency X → Y inside a relation, X is a key of that relation, or the dependent attributes are stored in a separate relation determined by their own key. |
| 349 | | |
| 350 | | == Check for BCNF |
| 351 | | Each resulting relation is also in BCNF, because in every non-trivial functional dependency within a relation, the determinant is a superkey of that relation. |
| 352 | | * `UserEntity`: user_id is key → BCNF |
| 353 | | * Users: user_id is key → BCNF |
| 354 | | * Administrators: admin_id is key → BCNF |
| 355 | | * Instructors: instructor_id is key → BCNF |
| 356 | | * SubscriptionPlan: plan_id is key → BCNF |
| 357 | | * UserSubscription: subscription_id is key → BCNF |
| 358 | | * Payment: payment_id is key → BCNF |
| 359 | | * SupportTicket: ticket_id is key → BCNF |
| 360 | | * Category: category_id is key → BCNF |
| 361 | | * Course: course_id is key → BCNF |
| 362 | | * CourseCategory: (course_id, category_id) is composite key → BCNF |
| 363 | | * Module: module_id is key → BCNF |
| 364 | | * Lesson: lesson_id is key → BCNF |
| 365 | | * Quiz: quiz_id is key → BCNF |
| 366 | | * QuizAttempt: attempt_id is key → BCNF |
| 367 | | * Enrollment: enrollment_id is key → BCNF |
| 368 | | * Certificate: certificate_id is key → BCNF |
| 369 | | {{{Therefore, the resulting schema satisfies BCNF.}}} |
| 370 | | |
| 371 | | == Check for 4NF (multivalued dependencies) |
| 372 | | No additional non-trivial multivalued dependencies are identified in the resulting schema. |
| 373 | | |
| 374 | | The many-to-many relationship between Course and Category is already decomposed into the separate relation: |
| 375 | | |
| 376 | | CourseCategory(course_id, category_id) |
| 377 | | |
| 378 | | This relation contains only the composite key and no additional descriptive attributes, so no further decomposition is required. |
| 379 | | |
| 380 | | All other relations describe a single entity or relationship around one key, and no independent multi-valued facts are stored together in the same relation. |
| 381 | | |
| 382 | | {{{Therefore, the schema satisfies 4NF.}}} |
| 383 | | |
| 384 | | == Final relations |
| 385 | | Final relations |
| 386 | | |
| 387 | | After applying normalization up to 4NF, the final normalized schema consists of the following relations: |
| 388 | | |
| 389 | | {{{ |
| 390 | | UserEntity(user_id, first_name, last_name, email, password, role) |
| 391 | | Users(user_id) |
| 392 | | Administrators(admin_id, user_id) |
| 393 | | Instructors(instructor_id, user_id) |
| 394 | | |
| 395 | | SubscriptionPlan(plan_id, plan_name, price, duration_months, plan_description, access_type) |
| 396 | | UserSubscription(subscription_id, user_id, plan_id, start_date, end_date, subscription_status) |
| 397 | | Payment(payment_id, user_id, subscription_id, amount) |
| 398 | | |
| 399 | | SupportTicket(ticket_id, user_id, admin_id, subject, ticket_description, ticket_status, created_at) |
| 400 | | |
| 401 | | Category(category_id, category_name, category_description) |
| 402 | | Course(course_id, course_name, course_price, course_status, instructor_id) |
| 403 | | CourseCategory(course_id, category_id) |
| 404 | | |
| 405 | | Module(module_id, course_id, module_title, module_description) |
| 406 | | Lesson(lesson_id, module_id, lesson_title, material) |
| 407 | | Quiz(quiz_id, lesson_id, total_points, passing_score) |
| 408 | | QuizAttempt(attempt_id, user_id, quiz_id, score, attempt_date) |
| 409 | | |
| 410 | | Enrollment(enrollment_id, user_id, course_id, enroll_date, completion_status, progress_percentage) |
| 411 | | Certificate(certificate_id, enrollment_id, issue_date, certificate_code, certificate_status) |