Posted on: March 12, 2025 Posted by: rahulgite Comments: 0

Design a database system for a multi-floor car parking building where:

  1. Users can check the number of available parking slots on each floor in real time.
  2. When a vehicle enters, the system should:
    • Assign the first available slot.
    • Record the vehicle’s registration number, floor, and slot location.
    • Maintain an entry log.
  3. When a vehicle exits, the system should:
    • Free the corresponding slot.
    • Update the available slot count.
    • Log the exit time.
  4. Ensure data consistency during concurrent vehicle entries and exits.
  5. Optimize for fast read and write operations to handle high traffic.

The system should support both a normalized design for maintaining data integrity and a denormalized design for faster access and scalability.

1. Normalized Database Design

In a normalized design, we follow 3NF (Third Normal Form) to minimize data redundancy and ensure data integrity.

Schema (Normalized Design)

  1. Building: Stores building-level information.
CREATE TABLE building (
    building_id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);
  1. Floor: Stores information about each floor.
CREATE TABLE floor (
    floor_id SERIAL PRIMARY KEY,
    building_id INT NOT NULL,
    floor_number INT NOT NULL,
    total_slots INT NOT NULL,
    available_slots INT NOT NULL,
    FOREIGN KEY (building_id) REFERENCES building(building_id)
);
  1. Slot: Stores individual parking slots.
CREATE TABLE slot (
    slot_id SERIAL PRIMARY KEY,
    floor_id INT NOT NULL,
    slot_number INT NOT NULL,
    is_occupied BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (floor_id) REFERENCES floor(floor_id)
);
  1. Vehicle: Stores vehicle details when parked.
CREATE TABLE vehicle (
    vehicle_number VARCHAR(20) PRIMARY KEY,
    slot_id INT UNIQUE,
    owner_name VARCHAR(100),
    entry_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (slot_id) REFERENCES slot(slot_id)
);
  1. Parking Logs: Stores entry and exit logs.
CREATE TABLE parking_logs (
    log_id SERIAL PRIMARY KEY,
    vehicle_number VARCHAR(20),
    floor_id INT,
    slot_id INT,
    action_type VARCHAR(10) CHECK (action_type IN ('ENTRY', 'EXIT')),
    action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Key Queries (Normalized Design)

  1. Find Available Slots on Each Floor
SELECT f.floor_number, COUNT(*) AS available_slots
FROM floor f
JOIN slot s ON f.floor_id = s.floor_id
WHERE s.is_occupied = FALSE
GROUP BY f.floor_number;
  1. Park a Vehicle (Transaction for Consistency)
BEGIN;

-- Find the first available slot
WITH available_slot AS (
    SELECT s.slot_id, f.floor_id
    FROM slot s
    JOIN floor f ON s.floor_id = f.floor_id
    WHERE s.is_occupied = FALSE
    ORDER BY f.floor_number, s.slot_number
    LIMIT 1
    FOR UPDATE SKIP LOCKED
)
-- Mark slot as occupied
UPDATE slot
SET is_occupied = TRUE
WHERE slot_id = (SELECT slot_id FROM available_slot);

-- Insert vehicle record
INSERT INTO vehicle (vehicle_number, slot_id, owner_name)
VALUES ('ABC123', (SELECT slot_id FROM available_slot), 'John Doe');

-- Log entry
INSERT INTO parking_logs (vehicle_number, floor_id, slot_id, action_type)
VALUES ('ABC123', (SELECT floor_id FROM available_slot), (SELECT slot_id FROM available_slot), 'ENTRY');

COMMIT;
  1. Find Vehicle Location
SELECT f.floor_number, s.slot_number
FROM vehicle v
JOIN slot s ON v.slot_id = s.slot_id
JOIN floor f ON s.floor_id = f.floor_id
WHERE v.vehicle_number = 'ABC123';

Trade-offs (Normalized Design)

Pros:

  • Data Integrity: Ensures data consistency via normalization.
  • Reduces Redundancy: Avoids duplicate information.
  • Easier Maintenance: Update and delete operations are simple.

Cons:

  • Performance: Requires JOIN operations across tables.
  • Complex Queries: Requires transactions for atomic updates.
  • Slower Reads: Especially for real-time slot availability checks.

2. Denormalized Database Design

In a denormalized design, we combine related tables to improve read performance by reducing joins.

Schema (Denormalized Design)

  1. Parking Status: Stores all slot and vehicle information in a single table.
CREATE TABLE parking_status (
    id SERIAL PRIMARY KEY,
    building_id INT NOT NULL,
    floor_number INT NOT NULL,
    slot_number INT NOT NULL,
    vehicle_number VARCHAR(20) UNIQUE, -- NULL if empty
    owner_name VARCHAR(100),
    is_occupied BOOLEAN NOT NULL DEFAULT FALSE,
    entry_time TIMESTAMP
);
  1. Parking Logs: Logs vehicle entry and exit.
CREATE TABLE parking_logs (
    log_id SERIAL PRIMARY KEY,
    vehicle_number VARCHAR(20),
    floor_number INT,
    slot_number INT,
    action_type VARCHAR(10) CHECK (action_type IN ('ENTRY', 'EXIT')),
    action_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Key Queries (Denormalized Design)

  1. Find Available Slots on Each Floor
SELECT floor_number, COUNT(*) AS available_slots
FROM parking_status
WHERE is_occupied = FALSE
GROUP BY floor_number;
  1. Park a Vehicle (Fast Atomic Update)
WITH available_slot AS (
    SELECT id FROM parking_status
    WHERE is_occupied = FALSE
    ORDER BY floor_number, slot_number
    LIMIT 1
    FOR UPDATE SKIP LOCKED
)
UPDATE parking_status
SET vehicle_number = 'ABC123', owner_name = 'John Doe', is_occupied = TRUE, entry_time = CURRENT_TIMESTAMP
WHERE id = (SELECT id FROM available_slot)
RETURNING floor_number, slot_number;

-- Log entry
INSERT INTO parking_logs (vehicle_number, floor_number, slot_number, action_type)
VALUES ('ABC123', 1, 101, 'ENTRY');
  1. Find Vehicle Location
SELECT floor_number, slot_number
FROM parking_status
WHERE vehicle_number = 'ABC123';

Trade-offs (Denormalized Design)

Pros:

  • Faster Reads: No complex JOIN operations.
  • Simple Queries: Easier to manage.
  • Efficient Updates: Single-row update is faster.

Cons:

  • Data Redundancy: Duplicate data across rows.
  • Consistency Issues: Must synchronize changes across records.
  • Complex Updates: Requires careful handling during concurrent access.

3. Summary Comparison

FeatureNormalized DesignDenormalized Design
Data IntegrityStrong (via foreign keys)Weaker (requires manual synchronization)
Read PerformanceSlower (due to multiple JOINs)Faster (data in a single table)
Write PerformanceSlower (multi-table updates)Faster (one table update)
Storage EfficiencyMinimal (no data duplication)Higher (redundancy in parking_status)
Query ComplexityComplex (JOINs and transactions)Simple (direct table access)
ScalabilityModerate (index optimizations help)High (suited for high-read workloads)

Leave a Comment