As semantic layers evolve into the foundation of modern analytics architectures, Cube Views are becoming the primary interface between raw semantic models and downstream consumers such as dashboards, embedded analytics, and AI agents.
Although cubes define joins, measures, and business logic, exposing raw cubes directly to end users often creates confusion:
· too many fields,
· ambiguous joins,
· inconsistent business definitions,
· and difficult self-service analytics experiences.
Cube Views solve this problem by acting as curated analytics datasets that reshape the underlying cube graph into focused, business-oriented interfaces.
Using a realistic food delivery platform schema, this guide explores how to design effective Cube Views for:
· operational analytics,
· revenue reporting,
· customer analytics,
· delivery monitoring,
· and AI-powered data exploration.
1. Introduction to Cube Views
Modern analytics systems are rarely simple.
Even a moderately sized business database can contain dozens or hundreds of tables connected through complex relationships. In a real-world food delivery platform like the one we are using in this guide, data is spread across many entities:
· customers
· orders
· restaurants
· drivers
· payments
· refunds
· delivery events
· promotions
· order items
· cities
· cuisines
Although this structure is excellent for storing operational data efficiently, it is not ideal for business users trying to answer questions like:
· What is our total revenue this month?
· Which restaurants have the highest cancellation rates?
· Which city generates the most orders?
· How effective are promotions?
· Which drivers consistently deliver late?
· Which customers are premium users with high lifetime value?
Business users should not need to understand SQL joins, warehouse schemas, fanout risks, or semantic modeling internals just to answer these questions.
This is exactly where Cube Views become important.
1.1 What Are Views?
Views in Cube are curated, business-friendly datasets built on top of cubes.
They provide a simplified and organized interface for downstream consumers such as:
· business analysts
· dashboard users
· embedded analytics customers
· AI agents
· LLM-powered analytics assistants
· self-service reporting tools
A view does not store data itself.
Instead, it sits on top of existing cubes and selectively exposes:
· measures
· dimensions
· segments
· join paths
in a way that is easier for users to understand and explore.
Think of a view as a carefully designed presentation layer for your semantic model.
Instead of exposing the full complexity of your warehouse structure, a view presents a clean and focused business dataset.
For example, your underlying semantic model may contain:
· orders cube
· customers cube
· restaurants cube
· payments cube
· refunds cube
· delivery_events cube
But an analyst may only need a simplified dataset like ‘sales_overview’ containing:
· total revenue
· order count
· customer city
· restaurant name
· average delivery time
The analyst interacts with this curated dataset without needing to understand the complex joins underneath.
1.2 Why Cube Introduced Views?
As semantic models grow, exposing raw cubes directly to users creates several problems.
Problem 1: Too Much Complexity
Large semantic models often contain:
· hundreds of dimensions
· many measures
· deeply connected joins
· technical fields
· intermediate cubes
Exposing all of this directly overwhelms users. For example:
· Should users query orders.final_amount or payments.payment_amount?
· Should city come from customers or restaurants?
· Which delivery timestamp is correct?
· Which revenue measure includes refunds?
Without curation, analytics becomes confusing. Views solve this by exposing only the fields relevant to a specific business use case.
Problem 2: Ambiguous Join Paths
In large data graphs, the same cube may be reachable through multiple paths. Using the food delivery schema:
· orders → customers → cities
· orders → restaurants → cities
Now imagine a user asking "Show total revenue by city". Which city should Cube use?
· customer city?
· restaurant city?
Views remove this ambiguity by explicitly defining join paths. This guarantees consistent analytics behavior.
Problem 3: Self-Service Analytics Is Difficult
Business users usually think in business concepts:
· revenue
· customers
· restaurants
· delivery performance
They do not think in:
· foreign keys
· bridge tables
· SQL joins
· warehouse schemas
Views bridge this gap by reshaping technical models into business-friendly datasets.
Problem 4: AI Agents Need Curated Context
Modern analytics is increasingly AI-driven. LLMs and AI agents perform much better when:
· datasets are smaller
· naming is consistent
· relationships are curated
· irrelevant fields are hidden
A giant semantic graph with hundreds of members creates noisy context for AI systems. Views help create focused, AI-friendly semantic interfaces.
This is one of the biggest reasons views are becoming foundational in modern semantic layers.
1.3 Difference Between Cubes and Views
Although cubes and views are closely related, they serve very different purposes.
|
Cubes |
Views |
|
Define business logic |
Curate business datasets |
|
Define measures and dimensions |
Expose selected members |
|
Define joins |
Define join paths |
|
Handle SQL generation |
Handle presentation and organization |
|
Technical modeling layer |
Business-facing layer |
|
Built for engineers/modelers |
Built for analysts and consumers |
|
Can become large and complex |
Should remain focused and simple |
Cubes Are the Foundation
Cubes define:
· SQL tables
· joins
· measures
· dimensions
· segments
· calculations
· pre-aggregations
They are the semantic engine of the system. Example:
· orders cube
· customers cube
· payments cube
These cubes understand how the warehouse works.
Views Are the Curated Interface
Views sit on top of cubes and decide:
· which fields users can see
· how fields are named
· which join paths are allowed
· how datasets are organized
· what business context is exposed
Views simplify the consumer experience. They are intentionally designed for:
· usability
· discoverability
· governance
· AI friendliness
2. Your First Cube View
Now that we understand what Cube Views are and why they exist, let’s build our very first view using the food delivery platform schema. In this section, we will create a beginner friendly analytics dataset focused on sales analysis.
We will use three core business entities:
· orders
· customers
· restaurants
From these cubes, we want business users to easily analyze:
· total revenue
· total orders
· customer city
· restaurant name
The goal is to demonstrate how views simplify analytics by hiding the complexity of the underlying semantic model.
Orders Cube
- name: orders sql_table: orders joins: - name: customers relationship: many_to_one sql: "{CUBE}.customer_id = {customers.customer_id}" - name: restaurants relationship: many_to_one sql: "{CUBE}.restaurant_id = {restaurants.restaurant_id}" measures: - name: total_revenue sql: final_amount type: sum - name: order_count type: count dimensions: - name: order_id sql: order_id type: number primary_key: true - name: order_status sql: order_status type: string - name: ordered_at sql: ordered_at type: time
Customers Cube
- name: customers sql_table: customers dimensions: - name: customer_id sql: customer_id type: number primary_key: true - name: customer_name sql: full_name type: string - name: city_id sql: city_id type: number
Restaurants Cube
- name: restaurants sql_table: restaurants dimensions: - name: restaurant_id sql: restaurant_id type: number primary_key: true - name: restaurant_name sql: restaurant_name type: string - name: average_rating sql: average_rating type: number
Primary keys are extremely important to specify, because they define:
· row uniqueness
· cube grain
· aggregation safety
Without proper primary keys:
· joins may duplicate rows
· measures may overcount
· fanout issues become harder to detect
Our First View
views: - name: sales_overview description: > Simplified sales analytics dataset for business users. Includes revenue, order metrics, customer geography, and restaurant information. cubes: - join_path: orders includes: - total_revenue - order_count - order_id - order_status - ordered_at - join_path: orders.customers prefix: true includes: - customer_id - customer_name - city_id - join_path: orders.restaurants includes: - name: restaurant_name alias: restaurant - restaurant_id - average_rating
- join_path: orders
This establishes:
· orders as the starting point
· the primary business entity
· the main fact table
The view now inherits measures and dimensions from the orders cube.
- join_path: orders.customers
This explicitly tells Cube to use the customers cube through the orders → customers relationship. This eliminates ambiguity. Cube now knows exactly how customer information should be joined.
prefix: true
This automatically prefixes customer fields. For example: customers_city_id
Restaurant Alias
- name: restaurant_name
alias: restaurant
Instead of exposing restaurant_name, business users see restaurant.
This creates cleaner and more natural analytics datasets. Views allow us to reshape technical field names into business-friendly terminology.
2.1 Examples
Example 1: Total Revenue
What is the total revenue generated by the platform?
Query Spec
measures: - sales_overview.total_revenue
Generated Query
SELECT sum("orders".final_amount) "sales_overview__total_revenue" FROM orders AS "orders"
Example 2: Total Orders
How many orders were placed?
Query Spec
measures: - sales_overview.order_count
Generated Query
SELECT count("orders".order_id) "sales_overview__order_count" FROM orders AS "orders"
Example 3: Revenue by Restaurant
Which restaurants generate the highest revenue?
Query Spec
measures: - sales_overview.total_revenue dimensions: - sales_overview.restaurant order: sales_overview.total_revenue: desc
Generated Query
SELECT "restaurants".restaurant_name "sales_overview__restaurant", sum("orders".final_amount) "sales_overview__total_revenue" FROM orders AS "orders" LEFT JOIN restaurants AS "restaurants" ON "orders".restaurant_id = "restaurants".restaurant_id GROUP BY 1 ORDER BY 2 DESC
Example 4: Orders by Customer City
Which customer cities place the most orders?
Query Spec
measures: - sales_overview.order_count dimensions: - sales_overview.customers_city_id order: sales_overview.order_count: desc
Generated Query
SELECT "customers".city_id "sales_overview__customers_city_id", count("orders".order_id) "sales_overview__order_count" FROM orders AS "orders" LEFT JOIN customers AS "customers" ON "orders".customer_id = "customers".customer_id GROUP BY 1 ORDER BY 2 DESC
Example 5: Revenue Trend by Day
How is revenue trending daily?
Query Spec
measures: - sales_overview.total_revenue timeDimensions: - dimension: sales_overview.ordered_at granularity: day
Generated Query
SELECT date_trunc('day', ("orders".ordered_at::timestamptz AT TIME ZONE 'UTC')) "sales_overview__ordered_at_day", sum("orders".final_amount) "sales_overview__total_revenue" FROM orders AS "orders" GROUP BY 1 ORDER BY 1 ASC
Example 6: Delivered Orders Revenue
What is the revenue generated from delivered orders only?
Query Spec
measures: - sales_overview.total_revenue filters: - member: sales_overview.order_status operator: equals values: - DELIVERED
Generated Query
SELECT sum("orders".final_amount) "sales_overview__total_revenue" FROM orders AS "orders" WHERE ("orders".order_status = 'DELIVERED')
Example 7: Restaurant Revenue by Day
Show daily revenue for each restaurant.
Query Spec
measures: - sales_overview.total_revenue dimensions: - sales_overview.restaurant timeDimensions: - dimension: sales_overview.ordered_at granularity: day
Generated Query
SELECT "restaurants".restaurant_name "sales_overview__restaurant", date_trunc('day', ("orders".ordered_at::timestamptz AT TIME ZONE 'UTC')) "sales_overview__ordered_at_day", sum("orders".final_amount) "sales_overview__total_revenue" FROM orders AS "orders" LEFT JOIN restaurants AS "restaurants" ON "orders".restaurant_id = "restaurants".restaurant_id GROUP BY 1, 2 ORDER BY 2 ASC
Example 8: Top Restaurants in a Customer City
Which restaurants are most popular among customers from a specific city?
Query Spec
measures: - sales_overview.order_count dimensions: - sales_overview.restaurant filters: - member: sales_overview.customers_city_id operator: equals values: - '5' order: sales_overview.order_count: desc
Generated Query
SELECT "restaurants".restaurant_name "sales_overview__restaurant", count("orders".order_id) "sales_overview__order_count" FROM orders AS "orders" LEFT JOIN restaurants AS "restaurants" ON "orders".restaurant_id = "restaurants".restaurant_id LEFT JOIN customers AS "customers" ON "orders".customer_id = "customers".customer_id WHERE ("customers".city_id = '5') GROUP BY 1 ORDER BY 2 DESC
Example 9: Multi-Metric Dashboard Query
Build a sales dashboard showing revenue and order count by restaurant.
Query Spec
measures: - sales_overview.total_revenue - sales_overview.order_count dimensions: - sales_overview.restaurant
Generated Query
SELECT "restaurants".restaurant_name "sales_overview__restaurant", sum("orders".final_amount) "sales_overview__total_revenue", count("orders".order_id) "sales_overview__order_count" FROM orders AS "orders" LEFT JOIN restaurants AS "restaurants" ON "orders".restaurant_id = "restaurants".restaurant_id GROUP BY 1 ORDER BY 2 DESC
Final Thoughts
As semantic layers become central to modern analytics architectures, Cube Views are emerging as one of the most important building blocks for delivering scalable, user-friendly, and AI-ready analytics experiences.
Throughout this guide, we explored how cubes and views work together using a realistic food delivery platform schema containing orders, customers, restaurants, payments, delivery events, refunds, and operational analytics data.
One of the most important ideas to remember is this, Cubes model business logic and Views model business experience.
Cubes are responsible for:
· defining measures
· modeling joins
· encapsulating SQL logic
· handling aggregations
· managing semantic correctness
They represent the technical and governed foundation of the semantic layer.
Views, on the other hand, are the presentation layer of the semantic layer. They reshape the underlying cube graph into:
· focused business datasets
· simplified analytics interfaces
· curated field collections
· AI-friendly semantic contexts
· self-service analytics experiences
Instead of exposing raw warehouse complexity, views allow organizations to present clean, understandable, and governed datasets tailored to how business users actually think about data. This becomes increasingly important as systems scale.
In real enterprise environments:
· semantic graphs become massive
· joins become deeply interconnected
· multiple teams consume shared metrics
· embedded analytics platforms require tenant isolation
· AI agents generate queries dynamically
· governance and consistency become critical
Without views, analytics systems quickly become difficult to navigate and harder to trust. Views solve this by acting as a controlled interface between the semantic model and downstream consumers. Understanding how to design effective Cube Views is therefore an essential skill for anyone building modern semantic layers, embedded analytics platforms, or AI-driven data applications.
Previous Next Home
No comments:
Post a Comment