Changes between Version 7 and Version 8 of P5


Ignore:
Timestamp:
05/08/26 20:11:25 (3 weeks ago)
Author:
211171
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P5

    v7 v8  
    1 = Database Normalization – Wedding Planner System =
    2 
    3 == Introduction ==
    4 
    5 This section presents a complete, formal, and provable normalization process for the Wedding Planner database.
    6 The normalization is demonstrated step by step, starting from a denormalized relation and ending in Third Normal Form (3NF).
    7 
    8 **Each transformation is justified using:**
    9 
    10 -Functional dependencies
    11 
    12 -Primary key verification
    13 
    14 -Lossless join decomposition proof
    15 
    16 -Functional dependency preservation proof
    17 
    18 All examples are derived directly from the Wedding Planner domain.
    19 
    20 == Initial Denormalized Relation (UNF) ==
    21 
    22 The system initially stores all wedding-related information in a single relation.
    23 
    24 || Relation || Attributes ||
    25 || R || user_id, user_first_name, user_last_name, user_email, wedding_id, wedding_date, wedding_budget, venue_id, venue_name, venue_type, venue_capacity, booking_date, start_time, end_time ||
    26 
    27 This relation violates normalization principles.
    28 
    29 Note: venue_type in the UNF is an attribute that is later normalized into a separate relation.
    30 
    31 === Denormalized Table ===
    32 
    33 || user_id || first_name || last_name || email || wedding_id || wedding_date || wedding_budget || event_id || event_type || event_date || start_time || end_time ||guest_id || guest_first_name || guest_last_name || rsvp_status || attendance_status || venue_name || venue_type || photographer_name || band_name ||
    34 || 1 || Ana || Trajkovska || ana.trajkovska@gmail.com || 1 || 2026-06-20 || 8500 || 1 || Church Ceremony || 2026-06-20 || 12:00 || 13:00 || 1 || Ana || Markovska || accepted || attending || Lakeside Garden Venue || Outdoor Garden || Luna Studio || The Wedding Vibes ||
    35 || 1 || Ana || Trajkovska || ana.trajkovska@gmail.com || 1 || 2026-06-20 || 8500 || 2 || Reception || 2026-06-20 || 16:00 || 23:00 || 2 || Daniel || Stojanov || accepted || attending || Lakeside Garden Venue || Outdoor Garden || Luna Studio || The Wedding Vibes ||
    36 
    37 
    38 == Identified Problems in UNF ==
    39 
    40 || Problem || Explanation ||
    41 || Repetition || Venue data is repeated for every wedding
    42 || Update anomaly || Updating venue name requires multiple updates
    43 || Insertion anomaly || Venue cannot exist without a wedding
    44 || Deletion anomaly || Deleting a wedding removes venue data
    45 || Mixed entities || User, wedding, venue, and booking data stored together ||
    46 
    47 == Functional Dependency Analysis ==
    48 
    49 Based on business rules of the Wedding Planner system, the following functional dependencies hold:
    50 
    51 || ID || Functional Dependency || Justification ||
    52 || FD1 || user_id → user_first_name, user_last_name, user_email || User attributes depend only on user_id
    53 || FD2 || wedding_id → wedding_date, wedding_budget, user_id || A wedding uniquely defines its properties
    54 || FD3 || venue_id → venue_name, venue_type, venue_capacity || Venue attributes depend only on venue_id
    55 || FD4 || booking_id → venue_id, wedding_id, booking_date, start_time, end_time || A booking uniquely defines a venue reservation ||
     1= Wedding Planner Database Normalization =
     2
     3== Denormalized Form ==
     4
     5A single flat relation initially stores all entities and relationships of the Wedding Planner system in one table, without structural separation.
     6This causes repeating groups, redundancy, update anomalies, insertion anomalies, and deletion anomalies.
     7
     8=== Initial Denormalized Relation ===
     9
     10R(
     11user_id, first_name, last_name, email, phone_number, gender, birthday,
     12wedding_id, date, budget, notes,
     13venue_booking_id, vb_date, vb_start, vb_end, vb_status, vb_price,
     14venue_id, venue_name, location, city, capacity, price_per_guest, venue_type,
     15photographer_id, photographer_name, photo_price_per_hour,
     16band_id, band_name, band_genre, band_price_per_hour,
     17registrar_id, registrar_name, registrar_location,
     18church_id, church_name, priest_name,
     19guest_id, guest_first_name, guest_last_name, rsvp_status, attendance_status, table_number, event_type
     20)
     21
     22== Functional Dependencies ==
     23
     24The following functional dependencies hold in the Wedding Planner system:
     25
     26user_id → first_name, last_name, email, phone_number, gender, birthday
     27wedding_id → date, budget, notes, user_id
     28event_id → event_type, date, start_time, end_time, status, wedding_id
     29guest_id → guest_first_name, guest_last_name, email, wedding_id
     30response_id → status, response_date, guest_id, event_id
     31attendance_id → status, table_number, role, guest_id, event_id
     32venue_booking_id → vb_date, vb_start, vb_end, vb_status, vb_price, venue_id, wedding_id
     33venue_id → venue_name, location, city, address, capacity, menu, phone_number, price_per_guest, type_id
     34type_id → type_name
     35photographer_booking_id → date, start_time, end_time, status, photographer_id, wedding_id
     36photographer_id → photographer_name, email, phone_number, price_per_hour
     37band_booking_id → date, start_time, end_time, status, band_id, wedding_id
     38band_id → band_name, band_genre, equipment, phone_number, price_per_hour
     39registrar_booking_id → start_time, end_time, price, status, registrar_id, wedding_id
     40registrar_id → registrar_name, contact, location, working_hours
     41church_id → church_name, location, contact, wedding_id
     42priest_id → priest_name, contact, church_id
     43
     44=== Additional Business Constraints ===
     45
     46The following additional dependencies also hold:
     47
     48{guest_id, event_id} → {response_id, rsvp_status, response_date}
     49{guest_id, event_id} → {attendance_id, attendance_status, table_number}
     50{venue_id, vb_date, vb_start} → {venue_booking_id}
     51{wedding_id} → {venue_booking_id, photographer_booking_id, band_booking_id, registrar_booking_id, church_id}
    5652
    5753== Candidate Key Determination ==
    5854
    59 To uniquely identify a tuple in R, the following composite key is required:
    60 
    61 
    62 Please review the proof explained in more details here -> [[Proof of Candidate Key]]
    63 
    64 || Candidate Key ||
    65 || (user_id, wedding_id, venue_id, booking_date) ||
    66 
    67 This confirms that the initial relation has a composite primary key, which leads to partial dependencies.
    68 This composite key is minimal because removing any attribute (user_id, wedding_id, venue_id, or booking_date) results in ambiguity and loss of uniqueness. No proper subset of this key functionally determines all attributes of R.
     55To uniquely identify a tuple in the denormalized relation, identifiers from all independent entity branches are required.
     56
     57=== Candidate Key ===
     58
     59K = {
     60attendance_id,
     61venue_booking_id,
     62photographer_booking_id,
     63band_booking_id,
     64registrar_booking_id,
     65priest_id
     66}
     67
     68Please review the detailed proof here → [[Proof of Candidate Key]]
     69
     70=== Minimality Verification ===
     71
     72Each attribute in K is necessary:
     73
     74Removing attendance_id loses the guest/event attendance branch
     75Removing venue_booking_id loses venue reservation information
     76Removing photographer_booking_id loses photographer booking information
     77Removing band_booking_id loses band booking information
     78Removing registrar_booking_id loses registrar booking information
     79Removing priest_id loses priest information because church_id is derived through priest_id
     80
     81Since removing any attribute prevents determining all attributes of R, the key is minimal.
    6982
    7083== First Normal Form (1NF) ==
    7184
    7285=== Definition ===
     86
    7387A relation is in 1NF if:
    7488
    75 *All attributes contain atomic values
    76 
    77 *No repeating groups exist
    78 
    79 *The UNF relation contains repeating venue and booking attributes.
     89Every attribute contains atomic values
     90No repeating groups exist
     91Each tuple is uniquely identifiable
     92Columns contain consistent data types
    8093
    8194=== Transformation to 1NF ===
    8295
    83 The relation is decomposed into atomic tuples by separating entity data.
    84 
    85 || Table || Attributes ||
    86 || R1 || user_id, user_first_name, user_last_name, user_email
    87 || R2 || wedding_id, wedding_date, wedding_budget, user_id
    88 || R3 || venue_id, venue_name, venue_type, venue_capacity
    89 || R4 || booking_id, venue_id, wedding_id, booking_date, start_time, end_time ||
    90 
    91 All attributes are now atomic.
    92 
    93 Please review the proof explained in more details here -> [[Proof of 1N form]]
     96The original denormalized relation contains multiple conceptual entities combined into a single table.
     97Repeating groups are eliminated by separating each entity occurrence into individual tuples.
     98
     99All attributes now contain atomic values.
     100
     101=== Superkey Construction ===
     102
     103A superkey for the denormalized relation is:
     104
     105K = {
     106user_id,
     107wedding_id,
     108venue_booking_id,
     109photographer_booking_id,
     110band_booking_id,
     111registrar_booking_id,
     112church_id,
     113event_id,
     114guest_id,
     115response_id,
     116attendance_id
     117}
     118
     119=== Minimality Check ===
     120
     121Removing any identifier causes loss of at least one independent entity branch.
     122
     123Examples:
     124
     125Removing venue_booking_id removes venue booking information
     126Removing photographer_booking_id removes photographer booking information
     127Removing attendance_id removes attendance information
     128
     129Therefore the superkey is necessary for uniqueness in the denormalized structure.
    94130
    95131== Second Normal Form (2NF) ==
    96132
    97133=== Definition ===
     134
    98135A relation is in 2NF if:
    99136
    100 *It is in 1NF
    101 
    102 *No non-key attribute is partially dependent on a composite key
    103 
    104 === Partial Dependency Proof ===
    105 
    106 || Attribute || Depends On || Violation ||
    107 || user_first_name || user_id || Partial dependency
    108 || wedding_date || wedding_id || Partial dependency
    109 || venue_name || venue_id || Partial dependency
    110 
    111 Thus, 2NF is violated in the original relation.
    112 
    113 === Decomposition to 2NF ===
    114 
    115 || Table || Primary Key || Attributes ||
    116 || user || user_id || user_first_name, user_last_name, user_email
    117 || wedding || wedding_id || wedding_date, wedding_budget, user_id
    118 || venue || venue_id || venue_name, venue_type, venue_capacity
    119 || venue_booking || booking_id || venue_id, wedding_id, booking_date, start_time, end_time
    120 
    121 Each non-key attribute now fully depends on the primary key.
    122 
    123 == Explanation of Entity Composition (User Table) ==
    124 
    125 The user table exists because user data represents an independent entity.
    126 
    127 || Reason || Formal Explanation ||
    128 || Functional dependency || user_id → user attributes
    129 || Independence || User may exist without a wedding
    130 || Reusability || One user can manage multiple weddings
    131 || Normalization rule || Prevents transitive dependencies ||
    132 
    133 This decomposition is mandatory for correctness.
    134 
    135 Please review the proof explained in more details here -> [[Proof of 2N]]
     137It is already in 1NF
     138Every non-key attribute is fully functionally dependent on the entire primary key
     139No partial dependencies exist
     140
     141=== Partial Dependency Violations ===
     142
     143The original relation violates 2NF because:
     144
     145user_id → user attributes
     146wedding_id → wedding attributes
     147venue_id → venue attributes
     148
     149These dependencies rely only on part of the composite key.
     150
     151=== Decomposition into 2NF Relations ===
     152
     153|| Relation || Primary Key ||
     154|| USER || user_id ||
     155|| WEDDING || wedding_id ||
     156|| VENUE_TYPE || type_id ||
     157|| VENUE || venue_id ||
     158|| VENUE_BOOKING || booking_id ||
     159|| PHOTOGRAPHER || photographer_id ||
     160|| PHOTOGRAPHER_BOOKING || booking_id ||
     161|| BAND || band_id ||
     162|| BAND_BOOKING || booking_id ||
     163|| REGISTRAR || registrar_id ||
     164|| REGISTRAR_BOOKING || booking_id ||
     165|| CHURCH || church_id ||
     166|| PRIEST || priest_id ||
     167|| EVENT || event_id ||
     168|| GUEST || guest_id ||
     169|| EVENT_RSVP || response_id ||
     170|| ATTENDANCE || attendance_id ||
     171
     172Each resulting relation contains attributes fully dependent on its primary key.
     173
     174=== Lossless Join Verification ===
     175
     176Every decomposition satisfies the lossless join condition:
     177
     178(Ri ∩ Rj) → Ri OR (Ri ∩ Rj) → Rj
     179
     180Examples:
     181
     182|| Join || Common Attribute || Proof ||
     183|| USER ⋈ WEDDING || user_id || user_id is PK in USER ||
     184|| VENUE_BOOKING ⋈ VENUE || venue_id || venue_id is PK in VENUE ||
     185|| EVENT_RSVP ⋈ EVENT || event_id || event_id is PK in EVENT ||
     186
     187Therefore all decompositions are lossless.
    136188
    137189== Third Normal Form (3NF) ==
    138190
    139191=== Definition ===
     192
    140193A relation is in 3NF if:
    141194
    142 It is in 2NF
    143 
     195It is already in 2NF
    144196No transitive dependencies exist
    145 
    146 === Transitive Dependency Analysis ===
    147 
    148 || Dependency Chain || Explanation ||
    149 || wedding_id → user_id → user_email || Transitive dependency
    150 || booking_id → venue_id → venue_name || Transitive dependency
    151 
    152 === Removal of Transitive Dependencies ===
    153 
    154 Each dependency is isolated into its own table, resulting in full 3NF compliance.
    155 
    156 == Primary Key Verification ==
    157 
    158 Each table has a primary key that uniquely identifies records.
    159 
    160 || Table || Primary Key || Uniqueness Proof ||
    161 || user || user_id || One user per ID
    162 || wedding || wedding_id || One wedding per ID
    163 || venue || venue_id || One venue per ID
    164 || venue_booking || booking_id || One booking per ID ||
    165 
    166 This ensures entity integrity and in all resulting relations, no non-key attribute functionally determines another non-key attribute.
    167 
    168 Please review the proof explained in more details here -> [[Proof of 3N]]
    169 
    170 == Lossless Join Decomposition Proof ==
    171 
    172 === Formal Rule ===
    173 
    174 A decomposition of R into R1 and R2 is lossless if:
    175 
    176 || Condition ||
    177 || (R1 ∩ R2) → R1 OR (R1 ∩ R2) → R2 ||
    178 
    179 === Step-by-Step Explanation ===
    180 
    181 || Join || Common Attribute || Proof ||
    182 || wedding ⋈ user || user_id || user_id is PK in user
    183 || venue_booking ⋈ wedding || wedding_id || wedding_id is PK
    184 || venue_booking ⋈ venue || venue_id || venue_id is PK
    185 
    186 Each decomposition satisfies the lossless join condition.
    187 
    188 ❗ Lossless join is proven pairwise, not by joining all tables simultaneously.
    189 
    190 == Functional Dependency Preservation Proof ==
    191 
    192 === Definition ===
    193 A decomposition preserves dependencies if all FDs can be enforced without joins.
    194 
    195 === Verification ===
    196 
    197 || Functional Dependency || Table ||
    198 || user_id → user_first_name, user_last_name, user_email || user
    199 || wedding_id → wedding_date, wedding_budget, user_id || wedding
    200 || venue_id → venue_name, venue_type, venue_capacity || venue
    201 || booking_id → venue_id, wedding_id, booking_date, start_time, end_time || venue_booking ||
    202 
    203 All dependencies are preserved locally.
    204 
    205 == Final Normalized Schema (3NF) ==
    206 
    207 || Table || Primary Key || Foreign Keys ||
    208 || user || user_id
    209 || wedding || wedding_id || user_id → user
    210 || venue || venue_id
    211 || venue_booking || booking_id || venue_id → venue, wedding_id → wedding ||
     197Every non-key attribute depends only on the primary key
     198
     199=== Transitive Dependency Example ===
     200
     201venue_id → type_id → type_name
     202
     203Here, type_name depends transitively on venue_id through type_id.
     204
     205=== Resolution ===
     206
     207To eliminate the transitive dependency:
     208
     209VENUE_TYPE(type_id, type_name) is created
     210VENUE stores type_id as a foreign key
     211
     212This removes the transitive dependency while preserving all functional dependencies.
     213
     214=== Final 3NF Relations ===
     215
     216|| Relation || Primary Key || Foreign Keys ||
     217|| USER || user_id || — ||
     218|| WEDDING || wedding_id || user_id → USER ||
     219|| VENUE_TYPE || type_id || — ||
     220|| VENUE || venue_id || type_id → VENUE_TYPE ||
     221|| VENUE_BOOKING || booking_id || venue_id → VENUE, wedding_id → WEDDING ||
     222|| PHOTOGRAPHER || photographer_id || — ||
     223|| PHOTOGRAPHER_BOOKING || booking_id || photographer_id → PHOTOGRAPHER, wedding_id → WEDDING ||
     224|| BAND || band_id || — ||
     225|| BAND_BOOKING || booking_id || band_id → BAND, wedding_id → WEDDING ||
     226|| REGISTRAR || registrar_id || — ||
     227|| REGISTRAR_BOOKING || booking_id || registrar_id → REGISTRAR, wedding_id → WEDDING ||
     228|| CHURCH || church_id || wedding_id → WEDDING ||
     229|| PRIEST || priest_id || church_id → CHURCH ||
     230|| EVENT || event_id || wedding_id → WEDDING ||
     231|| GUEST || guest_id || wedding_id → WEDDING ||
     232|| EVENT_RSVP || response_id || guest_id → GUEST, event_id → EVENT ||
     233|| ATTENDANCE || attendance_id || guest_id → GUEST, event_id → EVENT ||
     234
     235== BCNF Verification ==
     236
     237A relation is in BCNF if for every non-trivial dependency:
     238
     239X → Y
     240
     241X is a superkey.
     242
     243All final relations satisfy this condition because every determinant is a candidate key or superkey.
    212244
    213245== Final Conclusion ==
    214246
    215 The Wedding Planner database schema is fully normalized to Third Normal Form.
    216 
    217 The normalization:
    218 
    219 -Eliminates redundancy
    220 
    221 -Prevents anomalies
    222 
    223 -Preserves functional dependencies
    224 
    225 -Guarantees lossless joins
    226 
    227 -Uses provable primary keys
     247The Wedding Planner database schema has been formally normalized to Third Normal Form (3NF) and BCNF.
     248
     249The normalization process:
     250
     251Eliminates redundancy
     252Prevents update anomalies
     253Prevents insertion anomalies
     254Prevents deletion anomalies
     255Preserves functional dependencies
     256Guarantees lossless joins
     257Ensures entity integrity through verified primary keys
     258
     259The final schema consists of 17 fully normalized relations.
     260
     261= Proof of Candidate Key =
     262
     263== Definition ==
     264
     265A set of attributes X is a candidate key if:
     266
     267X⁺ = R
     268X is minimal
     269
     270The closure X⁺ is computed by repeatedly applying functional dependencies until no additional attributes can be derived.
     271
     272== Step 1 – Testing Single Attribute Candidate Keys ==
     273
     274=== Attempt 1 ===
     275
     276K = {attendance_id}
     277
     278=== Closure ===
     279
     280(attendance_id)⁺ gives:
     281
     282attendance_status
     283table_number
     284guest_id
     285event_id
     286
     287Using additional dependencies:
     288
     289event_id → event_type, wedding_id
     290guest_id → guest_first_name, guest_last_name, rsvp_status, wedding_id
     291wedding_id → date, budget, notes, user_id
     292user_id → first_name, last_name, email, phone_number, gender, birthday
     293
     294=== Missing Dependencies ===
     295
     296The closure still does NOT determine:
     297
     298venue booking information
     299photographer booking information
     300band booking information
     301registrar booking information
     302priest and church information
     303
     304Therefore:
     305
     306(attendance_id)⁺ ≠ R
     307
     308Conclusion:
     309
     310attendance_id is NOT a candidate key.
     311
     312== Step 2 – Testing Two Attributes ==
     313
     314K = {attendance_id, priest_id}
     315
     316=== Closure ===
     317
     318Additional attributes derived:
     319
     320priest_name
     321priest_contact
     322church_id
     323church_name
     324church_location
     325
     326=== Missing Dependencies ===
     327
     328Still missing:
     329
     330venue booking information
     331photographer booking information
     332band booking information
     333registrar booking information
     334
     335Therefore:
     336
     337(attendance_id, priest_id)⁺ ≠ R
     338
     339Conclusion:
     340
     341K is NOT a candidate key.
     342
     343== Step 3 – Testing Three Attributes ==
     344
     345K = {
     346attendance_id,
     347venue_booking_id,
     348photographer_booking_id
     349}
     350
     351=== Closure ===
     352
     353Additional attributes derived:
     354
     355venue information
     356photographer information
     357wedding information
     358user information
     359
     360=== Missing Dependencies ===
     361
     362Still missing:
     363
     364band booking information
     365registrar booking information
     366priest/church information
     367
     368Therefore:
     369
     370K⁺ ≠ R
     371
     372Conclusion:
     373
     374K is NOT a candidate key.
     375
     376== Step 4 – Testing Larger Attribute Sets ==
     377
     378K = {
     379attendance_id,
     380priest_id,
     381venue_booking_id,
     382band_booking_id
     383}
     384
     385=== Missing Dependencies ===
     386
     387Still missing:
     388
     389photographer booking information
     390registrar booking information
     391
     392Therefore:
     393
     394K⁺ ≠ R
     395
     396Conclusion:
     397
     398K is NOT a candidate key.
     399
     400== Step 5 – Including All Booking Branches ==
     401
     402K = {
     403attendance_id,
     404venue_booking_id,
     405photographer_booking_id,
     406band_booking_id,
     407registrar_booking_id
     408}
     409
     410=== Missing Dependencies ===
     411
     412Still missing:
     413
     414priest information
     415church information
     416
     417Therefore:
     418
     419K⁺ ≠ R
     420
     421Conclusion:
     422
     423K is NOT a candidate key.
     424
     425== Step 6 – Final Candidate Key ==
     426
     427K = {
     428attendance_id,
     429venue_booking_id,
     430photographer_booking_id,
     431band_booking_id,
     432registrar_booking_id,
     433priest_id
     434}
     435
     436=== Closure ===
     437
     438Using all functional dependencies:
     439
     440attendance branch is determined
     441event branch is determined
     442guest branch is determined
     443wedding branch is determined
     444venue booking branch is determined
     445photographer booking branch is determined
     446band booking branch is determined
     447registrar booking branch is determined
     448priest branch is determined
     449church branch is determined
     450
     451No attributes remain undetermined.
     452
     453Therefore:
     454
     455K⁺ = R
     456
     457Conclusion:
     458
     459K is a candidate key.
     460
     461== Minimality Proof ==
     462
     463A candidate key must be minimal.
     464
     465Removing any attribute from K causes loss of at least one independent entity branch:
     466
     467|| Removed Attribute || Lost Information ||
     468|| attendance_id || attendance branch ||
     469|| venue_booking_id || venue booking branch ||
     470|| photographer_booking_id || photographer booking branch ||
     471|| band_booking_id || band booking branch ||
     472|| registrar_booking_id || registrar booking branch ||
     473|| priest_id || priest/church branch ||
     474
     475Therefore every attribute in K is necessary.
     476
     477== Why church_id Is Not Included ==
     478
     479Suppose we define:
     480
     481K = {
     482attendance_id,
     483venue_booking_id,
     484photographer_booking_id,
     485band_booking_id,
     486registrar_booking_id,
     487priest_id,
     488church_id
     489}
     490
     491This violates minimality because:
     492
     493priest_id → church_id
     494
     495church_id is already derivable from priest_id.
     496
     497Therefore church_id is redundant.
     498
     499The resulting set would be a superkey, NOT a candidate key.
     500
     501== Final Candidate Key ==
     502
     503K = {
     504attendance_id,
     505venue_booking_id,
     506photographer_booking_id,
     507band_booking_id,
     508registrar_booking_id,
     509priest_id
     510}
     511
     512This key:
     513
     514Determines all attributes of R
     515Is minimal
     516Satisfies the formal definition of a candidate key