# Views

Define read-only database views with custom SQL for aggregations, joins, and complex queries.

## What are Views?

Database views are virtual tables defined by SQL queries. They provide a way to encapsulate complex queries, aggregate data, and expose a simplified interface for reading data. Views in Prax are read-only and generate type-safe Rust code for querying.

#### Use Cases

- • Aggregate statistics (counts, sums, averages)
- • Pre-joined data for dashboards
- • Filtered subsets of data
- • Denormalized data for APIs
- • Full-text search results

#### Limitations

- • Read-only (no create, update, delete)
- • No relations to other models
- • Query performance depends on base tables
- • Materialized views need manual refresh

## Basic View Definition

Define a view with the `view` keyword, fields that match your SQL output, and a `@@sql()` attribute containing the query.

## Simple Views

Views can be as simple as filtering or joining data. Use `@map()` to map field names to SQL column aliases.

## Materialized Views

For expensive queries that don't need real-time data, use materialized views. They store the query results and can be refreshed periodically. Supported on PostgreSQL.

Note: Materialized views need to be refreshed manually or on a schedule. Use `REFRESH MATERIALIZED VIEW view_name` in PostgreSQL or configure automatic refresh with `@@refreshInterval`.

## Complete Example with Models

Here's a complete example showing models and a view that aggregates their data:

## Querying Views

Views are queried using the same type-safe API as models. All read operations (find_many, find_unique, find_first, count, aggregate) are available.

## Database-Specific Features

Different databases offer unique view capabilities. Prax supports database-specific SQL in your view definitions.

## View Attributes Reference

Attribute | Description | Example
--- | --- | ---
`@@sql("...")` | The SQL query that defines the view | `@@sql("SELECT * FROM users")`
`@@materialized` | Create as materialized view (PostgreSQL) | `@@materialized`
`@@map("name")` | Custom view name in database | `@@map("user_statistics")`
`@@refreshInterval` | Auto-refresh interval for materialized views | `@@refreshInterval("1h")`
`@@parameterized` | View accepts runtime parameters | `@@parameterized`

## Best Practices

#### Index Base Tables

Views inherit the performance characteristics of their underlying queries. Ensure proper indexes exist on columns used in WHERE clauses, JOINs, and GROUP BY.

#### Use Materialized Views for Heavy Aggregations

If a view performs expensive aggregations over large datasets, consider making it materialized and refreshing on a schedule rather than computing on every query.

#### Keep Views Focused

Create multiple focused views rather than one complex view. This improves maintainability, performance, and makes the API clearer.