| 234 | | 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. |
| 235 | | |
| 236 | | Examples of partial dependencies are: |
| 237 | | * payment_id → user_id, subscription_id, amount |
| 238 | | * ticket_id → user_id, admin_id, subject, ticket_description, ticket_status, created_at |
| 239 | | * course_id → course_name, course_price, course_status, instructor_id |
| 240 | | * category_id → category_name, category_description |
| 241 | | * attempt_id → user_id, quiz_id, score, attempt_date |
| 242 | | * certificate_id → enrollment_id, issue_date, certificate_code, certificate_status |
| 243 | | |
| 244 | | These are partial dependencies on components of the composite key, so R violates 2NF. |
| | 234 | The universal relation R is not in Second Normal Form (2NF) because it contains a composite primary key and several non-key attributes depend only on a part of that key (partial dependencies), instead of the whole key. |
| | 235 | |
| | 236 | Examples of such partial dependencies: |
| | 237 | |
| | 238 | payment_id → user_id, subscription_id, amount |
| | 239 | ticket_id → user_id, admin_id, subject, ticket_description, ticket_status, created_at |
| | 240 | course_id → course_name, course_price, course_status, instructor_id |
| | 241 | category_id → category_name, category_description |
| | 242 | attempt_id → user_id, quiz_id, score, attempt_date |
| | 243 | certificate_id → enrollment_id, issue_date, certificate_code, certificate_status |
| | 244 | |
| | 245 | Therefore, R violates 2NF. |
| 248 | | === Grouping by determinants (partial dependencies) |
| 249 | | To remove partial dependencies, the attributes are grouped according to the determinants from the functional dependencies: |
| 250 | | |
| 251 | | - user_id → first_name, last_name, email, password, role |
| 252 | | - instructor_id → user_id |
| 253 | | - admin_id → user_id |
| 254 | | - plan_id → plan_name, price, duration_months, plan_description, access_type |
| 255 | | - subscription_id → user_id, plan_id, start_date, end_date, subscription_status |
| 256 | | - payment_id → user_id, subscription_id, amount |
| 257 | | - ticket_id → user_id, admin_id, subject, ticket_description, ticket_status, created_at |
| 258 | | - category_id → category_name, category_description |
| 259 | | - course_id → course_name, course_price, course_status, instructor_id |
| 260 | | - module_id → course_id, module_title, module_description |
| 261 | | - lesson_id → module_id, lesson_title, material |
| 262 | | - quiz_id → lesson_id, total_points, passing_score |
| 263 | | - attempt_id → user_id, quiz_id, score, attempt_date |
| 264 | | - enrollment_id → user_id, course_id, enroll_date, completion_status, progress_percentage |
| 265 | | - certificate_id → enrollment_id, issue_date, certificate_code, certificate_status |
| 266 | | The relation CourseCategory has composite key (course_id, category_id) and no additional non-trivial functional dependencies. |
| 267 | | |
| 268 | | === 2NF relations (first decomposition) |
| 269 | | After removing the partial dependencies, we obtain the following relations: |
| 270 | | |
| 271 | | - `UserEntity (user_id, first_name, last_name, email, password, role)` |
| 272 | | - `Users(user_id)` |
| 273 | | - `Administrators(admin_id, user_id)` |
| 274 | | - `Instructors(instructor_id, user_id)` |
| 275 | | |
| 276 | | - `SubscriptionPlan(plan_id, plan_name, price, duration_months, plan_description, access_type)` |
| 277 | | - `UserSubscription(subscription_id, user_id, plan_id, start_date, end_date, subscription_status)` |
| 278 | | - `Payment(payment_id, user_id, subscription_id, amount)` |
| 279 | | |
| 280 | | - `SupportTicket(ticket_id, user_id, admin_id, subject, ticket_description, ticket_status, created_at)` |
| 281 | | |
| 282 | | - `Category(category_id, category_name, category_description)` |
| 283 | | - `Course(course_id, course_name, course_price, course_status, instructor_id)` |
| 284 | | - `CourseCategory(course_id, category_id)` |
| 285 | | |
| 286 | | - `Module(module_id, course_id, module_title, module_description)` |
| 287 | | - `Lesson(lesson_id, module_id, lesson_title, material)` |
| 288 | | - `Quiz(quiz_id, lesson_id, total_points, passing_score)` |
| 289 | | - `QuizAttempt(attempt_id, user_id, quiz_id, score, attempt_date)` |
| 290 | | |
| 291 | | - `Enrollment(enrollment_id, user_id, course_id, enroll_date, completion_status, progress_percentage)` |
| 292 | | - `Certificate(certificate_id, enrollment_id, issue_date, certificate_code, certificate_status)` |
| 293 | | |
| 294 | | {{{Lossless join:}}} |
| | 249 | === We eliminate partial dependencies by decomposing R into smaller relations such that each determinant becomes a primary key in its own relation. |
| | 250 | |
| | 251 | {{{R1: UserEntity:}}} |
| 296 | | To verify that the decomposition is lossless, we use the formal condition: |
| 297 | | |
| 298 | | For every decomposition of R into relations Ri and Rj, the intersection of their attributes must functionally determine at least one of the relations: |
| 299 | | |
| 300 | | Ri ∩ Rj → Ri OR Ri ∩ Rj → Rj |
| 301 | | |
| 302 | | In this decomposition, each relation is formed based on a determinant (such as user_id, plan_id, course_id, etc.), which becomes the primary key of that relation. |
| 303 | | |
| 304 | | The shared attributes between relations (e.g. user_id, course_id, subscription_id) are keys in at least one of the involved relations. |
| 305 | | |
| 306 | | Therefore, the condition for lossless join is satisfied, and the decomposition is lossless with respect to the original universal relation R. |
| | 253 | - UserEntity(user_id, first_name, last_name, email, password, role) |
| | 254 | - PK: user_id |
| | 255 | |
| | 256 | - Derived from: |
| | 257 | - FD1: user_id → first_name, last_name, email, password, role |
| | 258 | |
| | 259 | - Lossless Join Check: |
| | 260 | |
| | 261 | R ∩ UserEntity = {user_id} |
| | 262 | user_id → UserEntity |
| | 263 | |
| | 264 | ⇒ The decomposition is lossless |
| | 265 | |
| | 266 | - Dependency Preservation: |
| | 267 | |
| | 268 | FD1 is fully contained in UserEntity |
| | 269 | |
| | 270 | ⇒ PRESERVED |