From a49013fc0cee52fce6aa04d578640d50ac6348ee Mon Sep 17 00:00:00 2001 From: StewKI Date: Sun, 17 May 2026 20:32:58 +0200 Subject: [PATCH] new schemas --- sql/datamart_schema.sql | 133 ++++++++++++++++++++++++++++++++++ sql/schema.sql | 154 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 287 insertions(+) create mode 100644 sql/datamart_schema.sql create mode 100644 sql/schema.sql diff --git a/sql/datamart_schema.sql b/sql/datamart_schema.sql new file mode 100644 index 0000000..a3f0b66 --- /dev/null +++ b/sql/datamart_schema.sql @@ -0,0 +1,133 @@ +-- ============================================================================= +-- HOTEL RESERVATIONS — DATA MART (STAR SCHEMA) +-- Target: Oracle (university lab schema) +-- Based on A.24 Revenue Data Mart — Dimensional Modelling by Example +-- ============================================================================= + +-- ----------------------------------------------------------------------------- +-- DIMENSION TABLES +-- ----------------------------------------------------------------------------- + +-- YYYYMMDD integer key — cheap date range predicates, no JOIN to calendar needed +CREATE TABLE DIM_DATE ( + date_key NUMBER(8,0) NOT NULL, + full_date DATE NOT NULL, + year NUMBER(4,0) NOT NULL, + quarter NUMBER(1,0) NOT NULL, + month NUMBER(2,0) NOT NULL, + month_name VARCHAR2(10) NOT NULL, + week_number NUMBER(2,0) NOT NULL, + day_of_month NUMBER(2,0) NOT NULL, + day_name VARCHAR2(10) NOT NULL, + is_weekend NUMBER(1,0) NOT NULL, + is_business_day NUMBER(1,0) NOT NULL, + season VARCHAR2(10) NOT NULL, -- Peak / High / Low / Off + CONSTRAINT pk_dim_date PRIMARY KEY (date_key), + CONSTRAINT ck_dim_date_wknd CHECK (is_weekend IN (0,1)), + CONSTRAINT ck_dim_date_bday CHECK (is_business_day IN (0,1)) +); + +CREATE TABLE DIM_COUNTRY ( + country_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + country_id NUMBER(10,0) NOT NULL, + code CHAR(2) NOT NULL, + name VARCHAR2(100) NOT NULL, + currency VARCHAR2(10) NOT NULL, + CONSTRAINT pk_dim_country PRIMARY KEY (country_key), + CONSTRAINT uq_dim_cntry_id UNIQUE (country_id) +); + +CREATE TABLE DIM_STAR_RATING ( + star_rating_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + star_rating_id NUMBER(10,0) NOT NULL, + code NUMBER(1,0) NOT NULL, + description VARCHAR2(20) NOT NULL, + CONSTRAINT pk_dim_star PRIMARY KEY (star_rating_key), + CONSTRAINT uq_dim_star_id UNIQUE (star_rating_id) +); + +CREATE TABLE DIM_HOTEL_CHAIN ( + hotel_chain_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + hotel_chain_id NUMBER(10,0) NOT NULL, + code VARCHAR2(10) NOT NULL, + name VARCHAR2(100) NOT NULL, + CONSTRAINT pk_dim_chain PRIMARY KEY (hotel_chain_key), + CONSTRAINT uq_dim_chain_id UNIQUE (hotel_chain_id) +); + +CREATE TABLE DIM_HOTEL ( + hotel_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + hotel_id NUMBER(10,0) NOT NULL, + hotel_chain_key NUMBER(10,0), + country_key NUMBER(10,0) NOT NULL, + star_rating_key NUMBER(10,0) NOT NULL, + code VARCHAR2(20) NOT NULL, + name VARCHAR2(150) NOT NULL, + city VARCHAR2(100) NOT NULL, + CONSTRAINT pk_dim_hotel PRIMARY KEY (hotel_key), + CONSTRAINT uq_dim_hotel_id UNIQUE (hotel_id), + CONSTRAINT fk_dh_chain FOREIGN KEY (hotel_chain_key) REFERENCES DIM_HOTEL_CHAIN (hotel_chain_key), + CONSTRAINT fk_dh_country FOREIGN KEY (country_key) REFERENCES DIM_COUNTRY (country_key), + CONSTRAINT fk_dh_star FOREIGN KEY (star_rating_key) REFERENCES DIM_STAR_RATING (star_rating_key) +); + +CREATE TABLE DIM_ROOM ( + room_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + room_id NUMBER(10,0) NOT NULL, + hotel_key NUMBER(10,0) NOT NULL, + room_number VARCHAR2(10) NOT NULL, + floor NUMBER(3,0) NOT NULL, + room_type_code VARCHAR2(20) NOT NULL, + room_type_desc VARCHAR2(100) NOT NULL, + smoking_yn NUMBER(1,0) NOT NULL, + standard_rate NUMBER(10,2) NOT NULL, + CONSTRAINT pk_dim_room PRIMARY KEY (room_key), + CONSTRAINT uq_dim_room_id UNIQUE (room_id), + CONSTRAINT fk_dr_hotel FOREIGN KEY (hotel_key) REFERENCES DIM_HOTEL (hotel_key), + CONSTRAINT ck_dim_room_smk CHECK (smoking_yn IN (0,1)) +); + +CREATE TABLE DIM_GUEST ( + guest_key NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + guest_id NUMBER(10,0) NOT NULL, + country_key NUMBER(10,0), + name VARCHAR2(150) NOT NULL, + city VARCHAR2(100), + CONSTRAINT pk_dim_guest PRIMARY KEY (guest_key), + CONSTRAINT uq_dim_guest_id UNIQUE (guest_id), + CONSTRAINT fk_dg_country FOREIGN KEY (country_key) REFERENCES DIM_COUNTRY (country_key) +); + +-- ----------------------------------------------------------------------------- +-- FACT TABLE +-- ----------------------------------------------------------------------------- + +-- Grain: one row per room_booking +-- Revenue measures: nightly_rate, total_amount, nights_stayed +CREATE TABLE FACT_ROOM_BOOKING ( + fact_id NUMBER(10,0) GENERATED ALWAYS AS IDENTITY, + -- foreign keys + hotel_key NUMBER(10,0) NOT NULL, + hotel_chain_key NUMBER(10,0), + room_key NUMBER(10,0) NOT NULL, + guest_key NUMBER(10,0) NOT NULL, + country_key NUMBER(10,0), + star_rating_key NUMBER(10,0) NOT NULL, + checkin_date_key NUMBER(8,0) NOT NULL, + checkout_date_key NUMBER(8,0) NOT NULL, + -- degenerate dimensions + booking_status VARCHAR2(20) NOT NULL, + -- measures + nights_stayed NUMBER(4,0) NOT NULL, + nightly_rate NUMBER(10,2) NOT NULL, + total_amount NUMBER(12,2) NOT NULL, + CONSTRAINT pk_fact_rb PRIMARY KEY (fact_id), + CONSTRAINT fk_frb_hotel FOREIGN KEY (hotel_key) REFERENCES DIM_HOTEL (hotel_key), + CONSTRAINT fk_frb_chain FOREIGN KEY (hotel_chain_key) REFERENCES DIM_HOTEL_CHAIN (hotel_chain_key), + CONSTRAINT fk_frb_room FOREIGN KEY (room_key) REFERENCES DIM_ROOM (room_key), + CONSTRAINT fk_frb_guest FOREIGN KEY (guest_key) REFERENCES DIM_GUEST (guest_key), + CONSTRAINT fk_frb_country FOREIGN KEY (country_key) REFERENCES DIM_COUNTRY (country_key), + CONSTRAINT fk_frb_star FOREIGN KEY (star_rating_key) REFERENCES DIM_STAR_RATING (star_rating_key), + CONSTRAINT fk_frb_checkin FOREIGN KEY (checkin_date_key) REFERENCES DIM_DATE (date_key), + CONSTRAINT fk_frb_checkout FOREIGN KEY (checkout_date_key) REFERENCES DIM_DATE (date_key) +); diff --git a/sql/schema.sql b/sql/schema.sql new file mode 100644 index 0000000..2985d3d --- /dev/null +++ b/sql/schema.sql @@ -0,0 +1,154 @@ +CREATE DATABASE IF NOT EXISTS hotel_reservations + CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci; + +USE hotel_reservations; + +-- ───────────────────────────────────────────────────────────────────────────── +-- LOOKUP / REFERENCE TABLES +-- ───────────────────────────────────────────────────────────────────────────── + +CREATE TABLE hotel_chain ( + hotel_chain_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code VARCHAR(10) NOT NULL, + name VARCHAR(100) NOT NULL, + PRIMARY KEY (hotel_chain_id), + UNIQUE KEY uq_chain_code (code) +); + +CREATE TABLE country ( + country_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code CHAR(2) NOT NULL, + name VARCHAR(100) NOT NULL, + currency VARCHAR(10) NOT NULL, + PRIMARY KEY (country_id), + UNIQUE KEY uq_country_code (code) +); + +CREATE TABLE star_rating ( + star_rating_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code TINYINT UNSIGNED NOT NULL, + description VARCHAR(20) NOT NULL, + PRIMARY KEY (star_rating_id), + UNIQUE KEY uq_star_code (code) +); + +CREATE TABLE hotel_characteristic ( + characteristic_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code VARCHAR(20) NOT NULL, + description VARCHAR(100) NOT NULL, + PRIMARY KEY (characteristic_id), + UNIQUE KEY uq_char_code (code) +); + +CREATE TABLE room_type ( + room_type_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code VARCHAR(20) NOT NULL, + description VARCHAR(100) NOT NULL, + standard_rate DECIMAL(10,2) NOT NULL, + smoking_yn BOOLEAN NOT NULL DEFAULT FALSE, + PRIMARY KEY (room_type_id), + UNIQUE KEY uq_room_type_code (code) +); + +CREATE TABLE rate_period ( + rate_period_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + code VARCHAR(20) NOT NULL, + description VARCHAR(50) NOT NULL, + month_from TINYINT UNSIGNED NOT NULL, + month_to TINYINT UNSIGNED NOT NULL, + PRIMARY KEY (rate_period_id), + UNIQUE KEY uq_rate_period_code (code) +); + +-- ───────────────────────────────────────────────────────────────────────────── +-- CORE ENTITIES +-- ───────────────────────────────────────────────────────────────────────────── + +CREATE TABLE hotel ( + hotel_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + hotel_chain_id INT UNSIGNED, + country_id INT UNSIGNED NOT NULL, + star_rating_id INT UNSIGNED NOT NULL, + code VARCHAR(20) NOT NULL, + name VARCHAR(150) NOT NULL, + address VARCHAR(200), + postcode VARCHAR(20), + city VARCHAR(100) NOT NULL, + url VARCHAR(200), + PRIMARY KEY (hotel_id), + UNIQUE KEY uq_hotel_code (code), + CONSTRAINT fk_hotel_chain FOREIGN KEY (hotel_chain_id) REFERENCES hotel_chain (hotel_chain_id), + CONSTRAINT fk_hotel_country FOREIGN KEY (country_id) REFERENCES country (country_id), + CONSTRAINT fk_hotel_star FOREIGN KEY (star_rating_id) REFERENCES star_rating (star_rating_id) +); + +CREATE TABLE hotel_room ( + room_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + hotel_id INT UNSIGNED NOT NULL, + room_type_id INT UNSIGNED NOT NULL, + room_number VARCHAR(10) NOT NULL, + floor TINYINT UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (room_id), + UNIQUE KEY uq_hotel_room (hotel_id, room_number), + CONSTRAINT fk_room_hotel FOREIGN KEY (hotel_id) REFERENCES hotel (hotel_id), + CONSTRAINT fk_room_type FOREIGN KEY (room_type_id) REFERENCES room_type (room_type_id) +); + +CREATE TABLE guest ( + guest_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + country_id INT UNSIGNED, + name VARCHAR(150) NOT NULL, + email VARCHAR(150), + address VARCHAR(200), + city VARCHAR(100), + PRIMARY KEY (guest_id), + CONSTRAINT fk_guest_country FOREIGN KEY (country_id) REFERENCES country (country_id) +); + +CREATE TABLE booking ( + booking_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + guest_id INT UNSIGNED NOT NULL, + hotel_id INT UNSIGNED NOT NULL, + date_from DATE NOT NULL, + date_to DATE NOT NULL, + status ENUM('confirmed', 'cancelled', 'completed', 'no_show') NOT NULL DEFAULT 'confirmed', + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (booking_id), + CONSTRAINT fk_booking_guest FOREIGN KEY (guest_id) REFERENCES guest (guest_id), + CONSTRAINT fk_booking_hotel FOREIGN KEY (hotel_id) REFERENCES hotel (hotel_id) +); + +CREATE TABLE room_booking ( + room_booking_id INT UNSIGNED NOT NULL AUTO_INCREMENT, + booking_id INT UNSIGNED NOT NULL, + room_id INT UNSIGNED NOT NULL, + date_from DATE NOT NULL, + date_to DATE NOT NULL, + nightly_rate DECIMAL(10,2) NOT NULL, + total_amount DECIMAL(10,2) NOT NULL, + PRIMARY KEY (room_booking_id), + CONSTRAINT fk_rb_booking FOREIGN KEY (booking_id) REFERENCES booking (booking_id), + CONSTRAINT fk_rb_room FOREIGN KEY (room_id) REFERENCES hotel_room (room_id) +); + +-- ───────────────────────────────────────────────────────────────────────────── +-- JUNCTION TABLES +-- ───────────────────────────────────────────────────────────────────────────── + +CREATE TABLE hotel_hotel_characteristic ( + hotel_id INT UNSIGNED NOT NULL, + characteristic_id INT UNSIGNED NOT NULL, + PRIMARY KEY (hotel_id, characteristic_id), + CONSTRAINT fk_hhc_hotel FOREIGN KEY (hotel_id) REFERENCES hotel (hotel_id), + CONSTRAINT fk_hhc_char FOREIGN KEY (characteristic_id) REFERENCES hotel_characteristic (characteristic_id) +); + +CREATE TABLE period_room_rate ( + room_type_id INT UNSIGNED NOT NULL, + rate_period_id INT UNSIGNED NOT NULL, + rate DECIMAL(10,2) NOT NULL, + PRIMARY KEY (room_type_id, rate_period_id), + CONSTRAINT fk_prr_type FOREIGN KEY (room_type_id) REFERENCES room_type (room_type_id), + CONSTRAINT fk_prr_period FOREIGN KEY (rate_period_id) REFERENCES rate_period (rate_period_id) +);