.materialize() on a view asks Bijection to store its
output and maintain it instead:
bijection/schema.ts
Virtual and materialized
A materialized view is never stale. There’s no refresh to schedule and no lag
to monitor: a read always returns the same result the virtual view would
return at the same snapshot, including the pending writes of the current
mutation.
How materialized views stay current
When a mutation writes to a table that a materialized view reads, Bijection recomputes the affected view rows as part of that mutation’s transaction. The change to the table and the change to the view commit together, or not at all. Forcustomer_summaries, inserting an order recomputes that one customer’s
row. Moving an order from one customer to another recomputes both customers,
using indexes to find them. A small change doesn’t rescan every customer.
That work is bounded by the view’s work limits.
If a write would require more maintenance than the limits allow, the mutation
fails. Bijection doesn’t fall back to a stale result or to finishing the work
later.
Index requirements
A materialized view needs indexes that let Bijection find affected rows in both directions:- Joins need the index on the right side, as for any view, and also an
index on the left table that begins with the
leftfields. When a joined row changes, that index finds the view rows that referenced it. A join on the left table’s_iduses the built-inby_idindex. - Grouped inputs need an index that begins with the grouping fields, as for any view.
customer._id, and orders has an index
on customer_id for orderTotals, so no extra index is needed. Bijection
refuses to maintain a materialized join whose left fields have no such index,
with an error naming the table and fields.
Views over views can be materialized too. A materialized view can read a virtual
view, and the other way around.
Choosing between them
Start with a virtual view. It has no storage and no write-time cost, and it’s a good fit when:- Reads are narrow, such as
db.geton one key or an index range over fields the view passes through from its source table. - The view is small enough to evaluate within its limits on every read.
- You order or filter by a computed or joined field, such as a total, across many rows. The stored output can be read by index instead of evaluated and sorted.
- Many clients read the view much more often than its inputs change.
Materializing a view stores its output as a derived copy of its inputs. It
doesn’t create a new source of truth: the tables it reads remain the only
place its data is written, and access to the view is still checked on every
read. See Access rules.