This project designs an analytics warehouse using a star schema centered on FactSales with dimensions DimProduct, DimCustomer, DimDate, and DimLocation. It supports monthly revenue per region, returning vs new customers, daily activity, and most profitable products.
erDiagram
DimDate ||--o{ FactSales : date_key
DimProduct ||--o{ FactSales : product_key
DimCustomer ||--o{ FactSales : customer_key
DimLocation ||--o{ FactSales : location_key
DimDate {
int date_key
date date
string day_name
int week
int month
string month_name
int quarter
int year
int iso_week
bool is_weekend
}
DimProduct {
int product_key
string product_id
string name
string category
string subcategory
string brand
string sku
timestamp effective_from
timestamp effective_to
bool is_current
}
DimCustomer {
int customer_key
string customer_id
string first_name
string last_name
string email_hash
int signup_date_key
string segment
timestamp effective_from
timestamp effective_to
bool is_current
}
DimLocation {
int location_key
string country
string region
string state
string city
string postal_code
}
FactSales {
bigint fact_sales_id
int date_key
int product_key
int customer_key
int location_key
string order_id
string line_item_id
numeric quantity
numeric unit_price
numeric discount_amount
numeric tax_amount
numeric revenue
numeric cost
numeric profit
numeric net_revenue
numeric gross_margin
}
DimDate: one row per calendar date, supports common time attributes.DimProduct: SCD Type 2 dimension tracking changes to product attributes over time.DimCustomer: SCD Type 2 dimension tracking changes to customer attributes and segment.DimLocation: standard geo dimension for country/region/state/city/postal_code.FactSales: line-item grain per order and transaction date with foreign keys to dimensions and sales measures.
FactSales.date_key→DimDate.date_keyFactSales.product_key→DimProduct.product_keyFactSales.customer_key→DimCustomer.customer_keyFactSales.location_key→DimLocation.location_key
- PostgreSQL
- Run
schema/ddl_postgres.sqlagainst your database. - Run
schema/staging_postgres.sqlto create staging tables. - Load sample data: run
data/staging_seed.sql. - Set
DW_PG_DSNand runetl/etl_example.pyafter loading staging tablesstg_orders,stg_order_items,stg_products,stg_customers,stg_locations.
- Run
- BigQuery
- Run
schema/ddl_bigquery.sqlin a dataset of your choice. - Use
etl/etl_bigquery.sqlfor a MERGE-based ETL example that populates dimensions and loadsFactSaleswithtransaction_date. - Ensure staging tables
stg_*exist and are populated.
- Run
- See
queries/olap_examples.sqlfor 10 queries covering ROLLUP, CUBE, GROUPING SETS, window functions, ranking, contribution analysis, basket size, and time deltas.
- Dimensions use surrogate keys;
FactSalesincludes degenerate identifiers for drill-through. - SCD2 managed for product and customer with
effective_from,effective_to,is_current. - Requirements: see
requirements.txt.