Changes between Version 3 and Version 4 of P7


Ignore:
Timestamp:
01/18/26 01:06:40 (3 days ago)
Author:
193284
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P7

    v3 v4  
    11= Phase P7: Advanced Database Development (SQL DDL) =
    2 This phase introduces advanced database mechanisms that help enforce business rules directly at database level.
    3 In our Wedding Planner database (PostgreSQL via DBeaver), we use indexes, constraints, triggers and views to improve performance, prevent invalid data and automate important logic.
    42
    53== Overview ==
    6 In this phase we implement:
    7  * Indexes – faster searching/filtering in large tables
    8  * Constraints – enforce validity and prevent inconsistent records
    9  * Triggers – automate rules (price calculation, venue capacity control)
    10  * Views – simplify reporting queries and provide reusable reports
    11 
    12 == What we cover in this phase ==
    13  * Indexes for frequent query patterns (events, bookings, RSVP)
    14  * Constraints for data validation + preventing overlapping bookings
    15  * Triggers to automate derived values (venue price) and enforce capacity
    16  * Views for simplified summaries (RSVP counts, confirmed bookings, guest counts)
    17 
    18 ----
    19 
    20 == Indexes (Performance Improvement) ==
    21 
    22 === Index: Event Date and Time Search Optimization ===
    23 This improves performance when searching or filtering events by date and time interval.
    24 
    25 *Tables affected:* `event` 
    26 *Index type:* B-tree composite indexes
     4This phase focuses on implementing advanced database mechanisms that enforce business logic directly at the database level.
     5Instead of relying only on application code, the database itself ensures correctness, prevents invalid states, and improves performance.
     6In the Wedding Planner project, this is especially important because the system handles bookings, RSVPs and guest management where mistakes (double booking, invalid status values, capacity overflow) must be impossible.
     7
     8In this phase we implemented:
     9 * Indexes – to speed up searches and filtering
     10 * Constraints – to prevent inconsistent or invalid data (including overlap prevention)
     11 * Triggers – automation of derived fields and enforcing business rules
     12 * Views – simplified reporting and aggregated queries
     13
     14== Indexes ==
     15Indexes significantly improve performance for common queries such as scheduling, availability checks and RSVP filtering.
     16
     17=== Index 1: Event date & time optimization ===
     18This index improves performance when searching or filtering events by date and start/end time (e.g., event timeline and schedule overview).
     19
     20*Table:* ''event'' 
     21*Type:* Composite B-tree index
    2722
    2823{{{
     
    3126}}}
    3227
    33 *Explanation:* 
    34 The indexes store pre-sorted combinations of (`date`, `start_time`) and (`date`, `end_time`), which allows fast retrieval of events for a specific day/time window without scanning the entire table.
    35 
    36 ---
    37 
    38 === Index: Booking Status Filtering ===
    39 These indexes optimize availability checks and booking filtering by date and status.
    40 
    41 *Tables affected:* `venue_booking`, `photographer_booking`, `band_booking` 
    42 *Index type:* B-tree composite indexes
     28*Why this matters:* 
     29Without indexes, PostgreSQL must scan the entire ''event'' table (Seq Scan) to find matching records.
     30With indexes, it can quickly retrieve only the relevant events for a given wedding date and time range.
     31
     32=== Index 2: Booking status filtering (availability checks) ===
     33These indexes optimize filtering bookings by date and status for venues, photographers and bands (used in availability endpoints and admin dashboards).
     34
     35*Tables:* ''venue_booking'', ''photographer_booking'', ''band_booking'' 
     36*Type:* Composite B-tree index
    4337
    4438{{{
     
    4842}}}
    4943
    50 *Explanation:* 
    51 Booking records are organized by (`date`, `status`), allowing fast retrieval of rows such as: “confirmed bookings on a given date”.
    52 
    53 ---
    54 
    55 === Index: RSVP Status Filtering ===
    56 This index speeds up reports of RSVP responses per event.
    57 
    58 *Table affected:* `event_rsvp` 
    59 *Index type:* Composite B-tree index
     44*Why this matters:* 
     45Availability checks would otherwise require full scans across booking tables. With indexes the system stays scalable as data grows.
     46
     47=== Index 3: RSVP filtering per event ===
     48This index improves performance when retrieving RSVP responses for an event grouped by status.
     49
     50*Table:* ''event_rsvp'' 
     51*Type:* Composite B-tree index
    6052
    6153{{{
     
    6355}}}
    6456
    65 *Explanation:* 
    66 RSVP rows are grouped by event and status, so queries like “all accepted guests for event X” are executed efficiently.
    67 
    68 ----
    69 
    70 == Constraints (Data Integrity) ==
    71 
    72 === Constraint: Prevent Overlapping Bookings ===
    73 This prevents double-booking of the same venue/photographer/band at overlapping time intervals.
    74 
    75 To support this constraint, we use:
    76  * `btree_gist` extension
    77  * generated timestamp columns (`start_ts`, `end_ts`)
    78  * GiST exclusion constraints
     57*Why this matters:* 
     58Queries such as “all accepted guests for event_id X” are much faster with this index.
     59
     60== Constraints ==
     61Constraints enforce correctness of the data and prevent invalid or inconsistent states.
     62
     63=== Constraint 1: Prevent overlapping bookings (no double booking) ===
     64One of the most important business rules in Wedding Planner is that a resource cannot be booked twice in overlapping time intervals.
     65This is enforced with EXCLUDE constraints using GiST indexes.
     66
     67First, we enable required extension:
    7968
    8069{{{
     
    8271}}}
    8372
    84 *Generated timestamps (date + time):*
     73Then we add generated timestamp columns which combine date + start_time/end_time:
     74
    8575{{{
    8676ALTER TABLE venue_booking
     
    9787}}}
    9888
    99 *Exclude overlap constraints:*
     89Finally, we enforce overlap prevention:
     90
    10091{{{
    10192ALTER TABLE venue_booking
    102 ADD CONSTRAINT exclude_overlap_vb EXCLUDE USING gist (
     93ADD CONSTRAINT exclude_overlap
     94EXCLUDE USING gist (
    10395    venue_id WITH =,
    10496    tsrange(start_ts, end_ts) WITH &&
     
    10698
    10799ALTER TABLE photographer_booking
    108 ADD CONSTRAINT exclude_overlap_pb EXCLUDE USING gist (
     100ADD CONSTRAINT exclude_overlap_pb
     101EXCLUDE USING gist (
    109102    photographer_id WITH =,
    110103    tsrange(start_ts, end_ts) WITH &&
     
    112105
    113106ALTER TABLE band_booking
    114 ADD CONSTRAINT exclude_overlap_bb EXCLUDE USING gist (
     107ADD CONSTRAINT excl_bb_no_overlap
     108EXCLUDE USING gist (
    115109    band_id WITH =,
    116110    tsrange(start_ts, end_ts) WITH &&
     
    118112}}}
    119113
    120 *Explanation:* 
    121 The database rejects inserting a booking if the interval overlaps with another booking for the same resource (venue/band/photographer).
    122 
    123 ---
    124 
    125 === Constraint: Status and Value Validation ===
    126 We prevent invalid values for status/role/budget using CHECK constraints.
     114*Why this matters:* 
     115This guarantees that a venue/band/photographer cannot be double booked for overlapping time ranges, even if the application sends incorrect input.
     116
     117=== Constraint 2: CHECK constraints for valid values ===
     118To prevent invalid statuses and roles, we added CHECK constraints.
    127119
    128120{{{
     
    160152}}}
    161153
    162 *Explanation:* 
    163 If an invalid value is inserted or updated, PostgreSQL rejects the operation and keeps the database consistent.
    164 
    165 == Triggers (Automation of Business Logic) ==
    166 
    167 === Trigger: Automatic Venue Price Calculation ===
    168 This trigger calculates the total venue booking price based on:
    169  * venue price per guest
    170  * current number of guests for that wedding
    171 
    172 *Tables involved:* `venue_booking`, `venue`, `guest` 
    173 *Trigger type:* BEFORE INSERT on `venue_booking`
     154*Why this matters:* 
     155The database rejects invalid values automatically, ensuring consistent and predictable data for the application.
     156
     157== Triggers ==
     158Triggers automate important derived logic and enforce real-world constraints.
     159
     160=== Trigger 1: Automatic venue price calculation ===
     161This trigger automatically calculates venue booking price if it is not provided, based on:
     162 * venue.price_per_guest
     163 * number of guests for the wedding
    174164
    175165{{{
     
    194184}}}
    195185
    196 *Reason for use:* 
    197 This ensures price is always correct and prevents manual calculation errors inside the application.
    198 
    199 ---
    200 
    201 === Trigger: Venue Capacity Enforcement ===
    202 This trigger prevents adding guests if the confirmed venue capacity will be exceeded.
    203 
    204 *Tables involved:* `guest`, `venue_booking`, `venue` 
    205 *Trigger type:* BEFORE INSERT OR UPDATE on `guest`
     186*Why this matters:* 
     187Price is a derived field. This ensures it is always correct and not dependent only on application-level calculations.
     188
     189=== Trigger 2: Venue capacity enforcement ===
     190This trigger prevents inserting/updating guests when the number of guests exceeds the confirmed venue capacity.
    206191
    207192{{{
     
    229214
    230215    IF guest_count + 1 > venue_cap THEN
    231         RAISE EXCEPTION 'Cannot add guest: venue capacity (%) exceeded', venue_cap;
     216        RAISE EXCEPTION
     217        'Cannot add guest: venue capacity (%) exceeded',
     218        venue_cap;
    232219    END IF;
    233220
     
    242229}}}
    243230
    244 *Reason for use:* 
    245 This enforces a real-world rule: guest count cannot exceed venue capacity.
    246 
    247 ----
    248 
    249 == Views (Simplified Reports) ==
    250 
    251 === View: RSVP summary per event ===
    252 Shows RSVP counts per status for each event.
     231*Why this matters:* 
     232This enforces a critical business rule: a wedding cannot have more guests than venue capacity.
     233
     234== Views ==
     235Views simplify reporting and provide useful aggregated results.
     236
     237=== View 1: RSVP summary per event ===
     238This view returns counts of accepted/declined/pending RSVP answers for each event.
    253239
    254240{{{
     
    258244    SUM(CASE WHEN status = 'accepted' THEN 1 ELSE 0 END) AS yes_count,
    259245    SUM(CASE WHEN status = 'declined' THEN 1 ELSE 0 END) AS no_count,
    260     SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS maybe_count
     246    SUM(CASE WHEN status = 'pending'  THEN 1 ELSE 0 END) AS maybe_count
    261247FROM event_rsvp
    262248GROUP BY event_id;
    263249}}}
    264250
    265 ---
    266 
    267 === View: Confirmed bookings by date (all types) ===
    268 A unified report for all confirmed bookings in one result.
     251=== View 2: Confirmed bookings by date (all service providers) ===
     252This view unifies confirmed bookings (venue, photographer, band) into one report.
    269253
    270254{{{
     
    302286}}}
    303287
    304 ---
    305 
    306 === View: Guest count per wedding ===
    307 A reusable summary of how many guests exist for each wedding.
     288=== View 3: Guest count per wedding ===
     289This view counts guests grouped by wedding_id.
    308290
    309291{{{
     
    316298}}}
    317299
    318 ----
     300== Proof / Screenshots ==
     301To confirm that Phase P7 is implemented in PostgreSQL (DBeaver), we provide screenshots of successful execution and created objects:
     302
     303 * Indexes list created in schema: [[Image(P7_indexes_list.png)]]
     304 * EXCLUDE constraint for overlap prevention: [[Image(P7_exclude_overlap_band_booking.png)]]
     305 * Trigger function execution in DBeaver: [[Image(P7_trigger_function_capacity.png)]]
     306 * Created view in schema and executed script: [[Image(P7_view_wedding_guest_count.png)]]
    319307
    320308== Conclusion ==
    321 In this phase we implemented advanced database mechanisms that improve scalability and correctness of our Wedding Planner system.
    322 Indexes help queries run faster as the number of bookings/events grows.
    323 Constraints enforce strict data rules and prevent invalid states, such as double-booking.
    324 Triggers automate derived values and business rules like venue capacity control.
    325 Finally, views provide reusable reports and simplify querying for common summaries.
     309Phase P7 implements advanced database-level mechanisms for the Wedding Planner system. Indexes improve scalability and query performance, constraints prevent invalid states (especially double booking), triggers automate key business logic (price calculation and capacity enforcement), and views provide simplified reporting.
     310With these mechanisms, the database becomes robust, consistent, and production-ready.