Changes between Version 9 and Version 10 of P5


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

--

Legend:

Unmodified
Added
Removed
Modified
  • P5

    v9 v10  
    33== Denormalized Form ==
    44
    5 A single flat relation initially stores all entities and relationships of the Wedding Planner system in one table, without structural separation.
    6 This causes repeating groups, redundancy, update anomalies, insertion anomalies, and deletion anomalies.
     5A single flat table containing all entities and their relationships, with no structural constraints. 
     6Multi-valued attributes and repeating groups are present.
    77
    88=== Initial Denormalized Relation ===
     
    2424The following functional dependencies hold in the Wedding Planner system:
    2525
    26 user_id → first_name, last_name, email, phone_number, gender, birthday
    27 wedding_id → date, budget, notes, user_id
    28 event_id → event_type, date, start_time, end_time, status, wedding_id
    29 guest_id → guest_first_name, guest_last_name, email, wedding_id
    30 response_id → status, response_date, guest_id, event_id
    31 attendance_id → status, table_number, role, guest_id, event_id
    32 venue_booking_id → vb_date, vb_start, vb_end, vb_status, vb_price, venue_id, wedding_id
    33 venue_id → venue_name, location, city, address, capacity, menu, phone_number, price_per_guest, type_id
    34 type_id → type_name
    35 photographer_booking_id → date, start_time, end_time, status, photographer_id, wedding_id
    36 photographer_id → photographer_name, email, phone_number, price_per_hour
    37 band_booking_id → date, start_time, end_time, status, band_id, wedding_id
    38 band_id → band_name, band_genre, equipment, phone_number, price_per_hour
    39 registrar_booking_id → start_time, end_time, price, status, registrar_id, wedding_id
    40 registrar_id → registrar_name, contact, location, working_hours
    41 church_id → church_name, location, contact, wedding_id
    42 priest_id → priest_name, contact, church_id
    43 
    44 === Additional Business Constraints ===
    45 
    46 The 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}
     26* user_id → first_name, last_name, email, phone_number, gender, birthday
     27* wedding_id → date, budget, notes, user_id
     28* event_id → event_type, date, start_time, end_time, status, wedding_id
     29* guest_id → guest_first_name, guest_last_name, email, wedding_id
     30* response_id → status, response_date, guest_id, event_id
     31* attendance_id → status, table_number, role, guest_id, event_id
     32* venue_booking_id → vb_date, vb_start, vb_end, vb_status, vb_price, venue_id, wedding_id
     33* venue_id → venue_name, location, city, address, capacity, menu, phone_number, price_per_guest, type_id
     34* type_id → type_name
     35* photographer_booking_id → date, start_time, end_time, status, photographer_id, wedding_id
     36* photographer_id → photographer_name, email, phone_number, price_per_hour
     37* band_booking_id → date, start_time, end_time, status, band_id, wedding_id
     38* band_id → band_name, band_genre, equipment, phone_number, price_per_hour
     39* registrar_booking_id → start_time, end_time, price, status, registrar_id, wedding_id
     40* registrar_id → registrar_name, contact, location, working_hours
     41* church_id → church_name, location, contact, wedding_id
     42* priest_id → priest_name, contact, church_id
     43
     44=== Additional Functional Dependencies ===
     45
     46The following additional functional dependencies also hold in R due to business constraints:
     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}
    5252
    5353== Candidate Key Determination ==
    5454
    55 To uniquely identify a tuple in the denormalized relation, identifiers from all independent entity branches are required.
     55Attribute set X is a candidate key if:
     56
     57* X⁺ = R
     58* X is minimal
    5659
    5760=== Candidate Key ===
     
    6669}
    6770
    68 Please review the detailed proof here → [[Proof of Candidate Key]]
    69 
    70 === Minimality Verification ===
    71 
    72 Each attribute in K is necessary:
    73 
    74 Removing attendance_id loses the guest/event attendance branch
    75 Removing venue_booking_id loses venue reservation information
    76 Removing photographer_booking_id loses photographer booking information
    77 Removing band_booking_id loses band booking information
    78 Removing registrar_booking_id loses registrar booking information
    79 Removing priest_id loses priest information because church_id is derived through priest_id
    80 
    81 Since removing any attribute prevents determining all attributes of R, the key is minimal.
     71The detailed proof is provided here → [[Proof of Candidate Key]]
     72
     73=== Minimality Check ===
     74
     75* Removing attendance_id loses the guest/event branch
     76* Removing venue_booking_id loses the venue booking branch
     77* Removing photographer_booking_id loses the photographer booking branch
     78* Removing band_booking_id loses the band booking branch
     79* Removing registrar_booking_id loses the registrar booking branch
     80* Removing priest_id loses priest information because a church may contain multiple priests
     81
     82Therefore every attribute is required and the key is minimal.
     83
     84== Sample Denormalized Data ==
     85
     86|| user_id || first_name || wedding_id || date || budget || venue_name || photographer_name || band_name || church_name || guest_fname || rsvp_status ||
     87|| 1 || Ana || 1 || 2026-06-20 || 8500.00 || Lakeside Garden || Luna Studio || Wedding Vibes || St. Clement || Daniel || accepted ||
     88|| 2 || Stefan || 2 || 2026-09-05 || 12000.00 || Royal Hall || Golden Frame || Balkan Groove || St. Panteleimon || none || none ||
    8289
    8390== First Normal Form (1NF) ==
     
    8592=== Definition ===
    8693
    87 A relation is in 1NF if:
    88 
    89 Every attribute contains atomic values
    90 No repeating groups exist
    91 Each tuple is uniquely identifiable
    92 Columns contain consistent data types
     94A relation is in 1NF when:
     95
     96* Row ordering carries no meaning
     97* Every attribute contains atomic values
     98* Data types are consistent
     99* A primary key uniquely identifies each tuple
     100* No repeating groups exist
    93101
    94102=== Transformation to 1NF ===
    95103
    96 The original denormalized relation contains multiple conceptual entities combined into a single table.
    97 Repeating groups are eliminated by separating each entity occurrence into individual tuples.
    98 
    99 All attributes now contain atomic values.
     104The original denormalized relation contains multiple conceptual entities combined into one structure.
     105
     106Examples include:
     107
     108* User information
     109* Wedding information
     110* Guest information
     111* Event information
     112* Venue booking information
     113* Photographer booking information
     114* Band booking information
     115* Registrar booking information
     116* Church and priest information
     117
     118Repeating groups are eliminated by separating repeating occurrences into individual tuples.
     119
     120All attributes become atomic, satisfying the requirements of 1NF.
    100121
    101122=== Superkey Construction ===
    102123
    103 A superkey for the denormalized relation is:
     124To uniquely identify a tuple in the denormalized relation, identifiers from all independent entity groups must be included.
     125
     126A valid superkey is:
    104127
    105128K = {
     
    117140}
    118141
    119 === Minimality Check ===
    120 
    121 Removing any identifier causes loss of at least one independent entity branch.
     142=== Minimality Verification ===
     143
     144Removing any identifier causes at least one branch of the relation to become undetermined.
    122145
    123146Examples:
    124147
    125 Removing venue_booking_id removes venue booking information
    126 Removing photographer_booking_id removes photographer booking information
    127 Removing attendance_id removes attendance information
    128 
    129 Therefore the superkey is necessary for uniqueness in the denormalized structure.
     148* Removing venue_booking_id loses venue booking information
     149* Removing photographer_booking_id loses photographer booking information
     150* Removing attendance_id loses attendance information
     151* Removing church_id loses church information
     152
     153Therefore the superkey is necessary for uniqueness.
     154
     155== Transition to Second Normal Form (2NF) ==
     156
     157To achieve 2NF:
     158
     159* Partial dependencies must be removed
     160* Attributes depending only on part of a composite key must be separated
     161* Each resulting relation must contain attributes fully dependent on its own primary key
     162
     163This results in decomposition into multiple smaller relations.
    130164
    131165== Second Normal Form (2NF) ==
     
    135169A relation is in 2NF if:
    136170
    137 It is already in 1NF
    138 Every non-key attribute is fully functionally dependent on the entire primary key
    139 No partial dependencies exist
     171* It is already in 1NF
     172* Every non-key attribute depends on the entire primary key
     173* No partial dependencies exist
    140174
    141175=== Partial Dependency Violations ===
    142176
    143 The original relation violates 2NF because:
    144 
    145 user_id → user attributes
    146 wedding_id → wedding attributes
    147 venue_id → venue attributes
    148 
    149 These 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 
    172 Each resulting relation contains attributes fully dependent on its primary key.
    173 
    174 === Lossless Join Verification ===
    175 
    176 Every decomposition satisfies the lossless join condition:
    177 
    178 (Ri ∩ Rj) → Ri OR (Ri ∩ Rj) → Rj
    179 
    180 Examples:
    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 
    187 Therefore all decompositions are lossless.
    188 
    189 == Third Normal Form (3NF) ==
    190 
    191 === Definition ===
    192 
    193 A relation is in 3NF if:
    194 
    195 It is already in 2NF
    196 No transitive dependencies exist
    197 Every non-key attribute depends only on the primary key
    198 
    199 === Transitive Dependency Example ===
    200 
    201 venue_id → type_id → type_name
    202 
    203 Here, type_name depends transitively on venue_id through type_id.
    204 
    205 === Resolution ===
    206 
    207 To eliminate the transitive dependency:
    208 
    209 VENUE_TYPE(type_id, type_name) is created
    210 VENUE stores type_id as a foreign key
    211 
    212 This 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 
    237 A relation is in BCNF if for every non-trivial dependency:
    238 
    239 X → Y
    240 
    241 X is a superkey.
    242 
    243 All final relations satisfy this condition because every determinant is a candidate key or superkey.
    244 
    245 == Final Conclusion ==
    246 
    247 The Wedding Planner database schema has been formally normalized to Third Normal Form (3NF) and BCNF.
    248 
    249 The normalization process:
    250 
    251 Eliminates redundancy
    252 Prevents update anomalies
    253 Prevents insertion anomalies
    254 Prevents deletion anomalies
    255 Preserves functional dependencies
    256 Guarantees lossless joins
    257 Ensures entity integrity through verified primary keys
    258 
    259 The final schema consists of 17 fully normalized relations.
     177Examples of partial dependencies in the original relation:
     178
     179* user_id → user attributes
     180* wedding_id → wedding attributes
     181* venue_id → venue attributes
     182
     183Therefore the original relation violates 2NF.
     184
     185== 2NF Decomposition ==
     186
     187=== R1 – USER ===
     188
     189{user_id} → {first_name, last_name, email, phone_number, gender, birthday}
     190
     191=== Candidate Key Verification ===
     192
     193user_id is the surrogate primary key.
     194
     195No partial dependencies exist.
     196
     197=== Sample Data ===
     198
     199|| user_id || first_name || last_name || email || phone_number || gender || birthday ||
     200|| 1 || Ana || Trajkovska || ana.trajkovska@gmail.com || +38970111222 || Female || 2004-07-12 ||
     201|| 2 || Stefan || Petrovski || stefan.petrovski@gmail.com || +38970333444 || Male || 2003-11-20 ||
     202
     203=== Lossless Join Test ===
     204
     205R ∩ R1 = {user_id, first_name, last_name, email, phone_number, gender, birthday}
     206
     207Since:
     208
     209user_id → R1
     210
     211The decomposition is lossless.
     212
     213----
     214
     215=== R2 – WEDDING ===
     216
     217{wedding_id} → {date, budget, notes, user_id}
     218
     219=== Candidate Key Verification ===
     220
     221wedding_id is the surrogate primary key.
     222
     223=== Sample Data ===
     224
     225|| wedding_id || date || budget || notes || user_id ||
     226|| 1 || 2026-06-20 || 8500.00 || Summer wedding || 1 ||
     227|| 2 || 2026-09-05 || 12000.00 || Elegant indoor wedding || 2 ||
     228
     229=== Lossless Join Test ===
     230
     231R1.1 ∩ R2 = {wedding_id, date, budget, notes, user_id}
     232
     233Since:
     234
     235wedding_id → R2
     236
     237The decomposition is lossless.
     238
     239----
     240
     241=== R3 – VENUE_TYPE ===
     242
     243{type_id} → {type_name}
     244
     245=== Candidate Key Verification ===
     246
     247type_id is the surrogate primary key.
     248
     249=== Sample Data ===
     250
     251|| type_id || type_name ||
     252|| 1 || Restaurant ||
     253|| 2 || Wedding Hall ||
     254|| 3 || Outdoor Garden ||
     255
     256=== Lossless Join Test ===
     257
     258R2.1 ∩ R3 = {type_id, type_name}
     259
     260Since:
     261
     262type_id → type_name
     263
     264The decomposition is lossless.
     265
     266----
     267
     268=== R4 – VENUE ===
     269
     270VENUE(
     271venue_id,
     272name,
     273location,
     274city,
     275address,
     276capacity,
     277menu,
     278phone_number,
     279price_per_guest,
     280type_id
     281)
     282
     283=== Candidate Key Verification ===
     284
     285venue_id is the surrogate primary key.
     286
     287=== Sample Data ===
     288
     289|| venue_id || name || location || city || address || capacity || menu || phone_number || price_per_guest || type_id ||
     290|| 1 || Lakeside Garden || Matka || Skopje || Matka 12 || 200 || Garden menu || +38971123456 || 35 || 3 ||
     291|| 2 || Royal Hall || Centar || Skopje || Main St 5 || 350 || Full menu || +38972234567 || 45 || 2 ||
     292
     293=== Lossless Join Test ===
     294
     295R3.1 ∩ R4 = {venue_id, name, location, city, address, capacity, menu, phone_number, price_per_guest, type_id}
     296
     297Since:
     298
     299venue_id → R4
     300
     301The decomposition is lossless.
     302
     303----
     304
     305=== R5 – VENUE_BOOKING ===
     306
     307{booking_id} → {date, start_time, end_time, status, price, venue_id, wedding_id}
     308
     309=== Candidate Key Verification ===
     310
     311booking_id is the surrogate primary key.
     312
     313=== Sample Data ===
     314
     315|| booking_id || date || start_time || end_time || status || price || venue_id || wedding_id ||
     316|| 1 || 2026-06-20 || 16:00 || 23:00 || confirmed || 7000 || 1 || 1 ||
     317|| 2 || 2026-09-05 || 17:00 || 23:30 || confirmed || 9500 || 2 || 2 ||
     318
     319=== Lossless Join Test ===
     320
     321R4.1 ∩ R5 = {venue_booking_id, date, start_time, end_time, status, price, venue_id, wedding_id}
     322
     323Since:
     324
     325venue_booking_id → R5
     326
     327The decomposition is lossless.
     328
     329----
     330
     331=== R6 – PHOTOGRAPHER ===
     332
     333{photographer_id} → {name, email, phone_number, price_per_hour}
     334
     335=== Candidate Key Verification ===
     336
     337photographer_id is the surrogate primary key.
     338
     339=== Sample Data ===
     340
     341|| photographer_id || name || email || phone_number || price_per_hour ||
     342|| 1 || Luna Studio || luna@studio.mk || +38970101010 || 55 ||
     343|| 2 || Golden Frame || golden@frame.mk || +38970202020 || 65 ||
     344
     345=== Lossless Join Test ===
     346
     347R5.1 ∩ R6 = {photographer_id, name, email, phone_number, price_per_hour}
     348
     349Since:
     350
     351photographer_id → R6
     352
     353The decomposition is lossless.
     354
     355----
     356
     357=== R7 – PHOTOGRAPHER_BOOKING ===
     358
     359{booking_id} → {date, start_time, end_time, status, photographer_id, wedding_id}
     360
     361=== Candidate Key Verification ===
     362
     363booking_id is the surrogate primary key.
     364
     365=== Sample Data ===
     366
     367|| booking_id || date || start_time || end_time || status || photographer_id || wedding_id ||
     368|| 1 || 2026-06-20 || 14:00 || 22:00 || confirmed || 1 || 1 ||
     369|| 2 || 2026-09-05 || 12:00 || 21:00 || pending || 2 || 2 ||
     370
     371=== Lossless Join Test ===
     372
     373R6.1 ∩ R7 = {photographer_booking_id, date, start_time, end_time, status, photographer_id, wedding_id}
     374
     375Since:
     376
     377photographer_booking_id → R7
     378
     379The decomposition is lossless.
     380
     381----
     382
     383=== R8 – BAND ===
     384
     385{band_id} → {band_name, genre, equipment, phone_number, price_per_hour}
     386
     387=== Candidate Key Verification ===
     388
     389band_id is the surrogate primary key.
     390
     391=== Sample Data ===
     392
     393|| band_id || band_name || genre || equipment || phone_number || price_per_hour ||
     394|| 1 || Wedding Vibes || Pop || Sound + lights || +38970909090 || 80 ||
     395|| 2 || Balkan Groove || Traditional || Full instruments || +38970707070 || 95 ||
     396
     397=== Lossless Join Test ===
     398
     399R7.1 ∩ R8 = {band_id, band_name, genre, equipment, phone_number, price_per_hour}
     400
     401Since:
     402
     403band_id → R8
     404
     405The decomposition is lossless.
     406
     407----
     408
     409=== R9 – BAND_BOOKING ===
     410
     411{booking_id} → {date, start_time, end_time, status, band_id, wedding_id}
     412
     413=== Candidate Key Verification ===
     414
     415booking_id is the surrogate primary key.
     416
     417=== Sample Data ===
     418
     419|| booking_id || date || start_time || end_time || status || band_id || wedding_id ||
     420|| 1 || 2026-06-20 || 18:00 || 23:00 || confirmed || 1 || 1 ||
     421|| 2 || 2026-09-05 || 19:00 || 23:30 || confirmed || 2 || 2 ||
     422
     423=== Lossless Join Test ===
     424
     425R8.1 ∩ R9 = {band_booking_id, date, start_time, end_time, status, band_id, wedding_id}
     426
     427Since:
     428
     429band_booking_id → R9
     430
     431The decomposition is lossless.
     432
     433----