-- OBMP analytics materialized views -- -- Applied to the live database and version-controlled here for reproducibility. -- Safe to run against an empty database at init time: the view is created empty -- and the pg_cron job below populates/refreshes it hourly. -- AS adjacency: every undirected pair of consecutive ASes in an observed AS_PATH, -- with an occurrence count. Backs the AS Relationship Map dashboard so its panels -- read a 17k-row view instead of exploding ~4.4M base_attrs rows live. CREATE MATERIALIZED VIEW IF NOT EXISTS mv_as_adjacency AS SELECT LEAST(a.asn, b.asn) AS asn_a, GREATEST(a.asn, b.asn) AS asn_b, COUNT(*) AS occ FROM base_attrs ba CROSS JOIN LATERAL unnest(ba.as_path) WITH ORDINALITY a(asn, ord) JOIN LATERAL unnest(ba.as_path) WITH ORDINALITY b(asn, ord) ON b.ord = a.ord + 1 WHERE ba.as_path_count >= 2 AND a.asn <> b.asn GROUP BY 1, 2; -- Unique index required for REFRESH ... CONCURRENTLY (no read lock during refresh). CREATE UNIQUE INDEX IF NOT EXISTS mv_as_adjacency_pair_idx ON mv_as_adjacency (asn_a, asn_b); CREATE INDEX IF NOT EXISTS mv_as_adjacency_occ_idx ON mv_as_adjacency (occ DESC); -- Refresh hourly at minute 23. SELECT cron.schedule('refresh-mv-as-adjacency', '23 * * * *', 'REFRESH MATERIALIZED VIEW CONCURRENTLY mv_as_adjacency');