As a full-stack developer, views are invaluable for simplifying access to complex database schemas. But inevitably views require removal. Dropping views in PostgreSQL can carry unintended side-effects if not done carefully.

Based on my real-world experience as a PostgreSQL database developer, this comprehensive guide covers everything engineers need to know for safely removing views.

Views: A Powerful Development Abstraction

Before jumping into dropping views, we need to level-set on what database views actually provide.

Views are virtual tables that run saved queries on other tables and collections. By pre-defining commonly used transformations and filters, views create simplified interfaces on a complex logical schema.

For instance, rather than remembering lengthy joins between order tables every time sales data is needed, you could create a view joining and aggregating the necessary tables, exposing the output as sales_view. Any engineer can SELECT from sales_view without concerning themselves with the underlying schema complexity.

In my experience across startups and enterprises, views have enabled developers to efficiently query production databases safely. They abstract complex schema designs into approachable interfaces.

And that power explains why proper view management matters – they become relied upon interfaces and assumptions that can seriously break things when mishandled.

Hidden Dangers of Dropping PostgreSQL Views

Given the utility of views, we cannot afford to drop them casually without considering widespread impacts.

Beyond the surface level disruption of querying non-existent tables, abruptly removed views may corrupt query plans, invalidate dependent views, and break undocumented access patterns.

For example, Let‘s examine a view late_orders that filters order data to show only shipments delayed over 7 days:

CREATE VIEW late_orders AS 
  SELECT order_id, 
         customer_id,
         shipping_status
    FROM orders
   WHERE delivery_date > expected_date + INTERVAL ‘7 days‘

Invalid Query Plans

Any query regularly hitting this view can take advantage of persisted query plans for performance.

But suddenly dropping late_orders would break those plans and force re-planning overhead. New optimization may settle on very different join methods that regress performance severely.

I‘ve witnessed 100x+ slowdowns from invalid plans when applcations still assume the presence of suddenly dropped views.

Dependent Views Break

If other views are built referencing late_orders, they will start erroring after that view disappears. For example:

CREATE VIEW backlog_orders AS
  SELECT * 
    FROM late_orders
   WHERE shipping_status = ‘Pending‘

This will fail with relation "late_orders" does not exist after dropping the base view. Engineers attempting to query backlog_orders will be disrupted until dependencies are fixed.

Undocumented Access Patterns Break

There may be power users or even applications hitting late_orders directly via obj-id without documenting that dependency.

Maybe a dashboard visualization tools pulls late_orders data daily. Or an analyst has a custom script relying on that view persisting in place. Dropping the view suddenly undermines those undocumented access patterns.

Only by thoroughly checking for usage can you mitigate this insidious risk of view removal.

The above examples showcase why directly removing production views requires care – there are often far-reaching dependencies you need to plan for.

Now let‘s explore specific techniques to drop views more safely by managing dependencies systematically.

Check for View Dependencies

Before any view removal, priority one is comprehensive dependency analysis. The goal is gaining confidence that dropping our target view will not create failures rippling through our database ecosystem.

As a real-world example, I needed to remove a view providing employee personnel data from our payroll system. But could not afford disrupting access without understanding the downstream impact first.

By thoroughly reviewing dependencies, I identified and modified several reporting dashboards also leveraging that employee data view under the hood. Only after reconfiguring the reporting stack could removal proceed safely.

Here I detail my comprehensive framework for analyzing view dependencies pre-removal:

Direct Object References

Scan all schemas for mentions of your target view using:

SELECT object_type, 
       object_identity,
       definition 
  FROM sys_all_sql 
 WHERE definition LIKE ‘%employee_info%‘;

This turns up 5 other views that required adjustments before I could drop employee_info.

Statistics Snapshot

If the view is actively queried, snapshot usage statistics for comparison post-dropping:

SELECT schemaname, 
       viewname,
       total_time, 
       num_scans
  FROM pg_stat_all_tables 
 WHERE viewname = ‘employee_info‘;

I discovered multiple dashboard reports hitting this view repetitively – implying high visibility into any disruption.

Query Catalog

Pattern match historical queries via tools like pg_stat_statements:

SELECT query, 
       calls,
       rows
  FROM pg_stat_statements
 WHERE query ILIKE ‘%employee_info%‘
ORDER BY calls DESC; 

Frequent historical queries indicate potential breakages needing assessment after removing access to that data.

This revealed a business analyst running daily exports based on employee_info. All downstream tooling required updates with alternative tables before proceeding.

Application Checks

Review app codebases searching for usage of this view. In complex environments you may be surprised by which applications leverage certain views under the hood.

By genuinely understanding all dependencies, view removal campaigns become lower risk. You reduce unexpected breakages by methodically modifying dependent objects beforehand.

While time-intensive, these comprehensive dependency checks are essential when removing business critical views.

Monitor View Usage

Beyond checking for explicit dependencies, we need telemetrics showing how frequently views are exercised by end users and applications.

Actively utilized views likely provide integral data access that developers depend on persisting into the future. Removing them suddenly undermines those stakeholders and use cases.

However lightly queried views may be growing stale or redundant – implying safer removal with lower disruption.

We want usage metrics to guide our view "garbage collection" targeting the least strategically important views first. Two approaches help collect telemetry on view utilization:

Track Query Volume

All apps and users querying a view gets captured within pg_stat_all_tables:

SELECT schemaname, 
       viewname,
       count_scan,
       count_tup_returned
  FROM pg_stat_all_tables
 WHERE viewname = ‘sales_view‘
ORDER BY count_scan DESC;

Check for views with low scans/returned rows to identify initial candidates for removal.

Analyze Performance Impact

We can also chart the performance overhead views introduce using:

SELECT viewname,  
       total_plan_time, 
       calls, 
       total_plan_time / calls AS avg_time
  FROM pg_stat_statements 
 ORDER BY avg_time DESC;

Views incurring the highest average planning time drag down database efficiency. They become high ROI targets for refactoring or removal efforts.

By combining multiple telemetry sources, low utility views can be cleaned out first with minimal disruption to customers.

Always Check for Usage Before Dropping

Speaking more broadly beyond dependencies, simply querying a view tells little about whether stakeholders are leveraging it behind the scenes.

The view may power important dashboards or datasets via hidden access patterns not reflected in pg catalog tables. These opaque usage modes are immune from even the most rigorous dependency checks.

Production Views ≠ Dev Views

As a real-world lesson, early in my career our dev team removed a view we assumed provided insignificant application metadata.

But soon the business intelligence team was opening urgent tickets around their daily automated reporting suddenly breaking without explanation.

As it turned out, an analyst had wired up scripts pointing directly to our dev view ID based on its outputs meeting their needs. By dropping without warning, we unwittingly broke their workflow.

This emphasized to me that production views have more extensive usage than typically exercised in lower environments. What seems like a harmless dev-only view can take on added importance when real users start depending on it.

Takeaway: Fail Loudly

Therefore I advocate for "failing loudly" before view removal in production — intentionally breaking a view to flush out any opaque dependent usage beforehand.

For example:

ALTER VIEW employee_sales DISABLE;

By aggressively disabling views pre-removal we can discover downstream impacts through user complaints. It converts hidden usage into loud warnings demanding investigation pre-removal.

No matter how thoroughly you model dependencies, production views will frequently see functionalities you didn‘t anticipate. Failing loudly forces those dependencies out into the open for correction before choosing to fully drop.

Gradually Deprecate Views

Rather than abruptly removing views in a single step, best practice is to gradually deprecate them while smoothly transitioning users to alternatives.

This phased approach works well:

1. Announce upcoming removal – Email stakeholders that a view will get removed by X date. Link to docs on replacement views/tables to leverage instead.

2. Disable view after 2 weeksALTER VIEW ... DISABLE; to test impact and identify lingering dependencies.

3. Remove view 1 month later – Finally DROP VIEW after allowing downstream transitions to complete.

I‘ve found this lifecycle best balances giving engineers time to smoothly transition, without views persisting indefinitely beyond need.

Regularly communicating removal plans and replacements is crucial though – systems cannot just instantly disappear without warning even inactive users of alternative options.

Risks of DROP VIEW ALL

When deeply cleaning up stale views, engineers may be tempted to simply drop all views with:

DROP VIEW ALL;

But this should be avoided except perhaps in local dev environments. Indiscriminately removing all views has caused production outages in the past due to:

  • Not expecting sweeping changes – Developers are surprised when bulk actions take views offline they still rely upon without noticing removal announcements.

  • Implicit dependencies – Key views like the ones powering business intelligence may get dropped inadvertently in the sweep. Dashboards can instantly lose critical data.

  • Unnecessary loads – DELETEing all views applies heavy schema modification load whether views are inactive or not. Spiky DDL churn can cause transient performance dips.

Bulk dropping should only proceed after methodically inspecting usage per view – generalized deletion is enormously risky otherwise. Communication and phased deprecation greatly dampen disruption.

How PostgreSQL Manages View Dependencies

As we‘ve covered, views frequently have interdependencies forming a DAG of working dataflows. Engineers lean on certain root views that downstream views incrementally augment or filter.

Different RDBMSs take varying approaches managing these dependencies:

  • PostgreSQL does not automatically drop downstream dependents if a view disappears. Dependent views remain broken causing runtime errors until engineers manually remove or update them.

  • SQL Server and Oracle both automatically drop views lower in the dependency chain if upstream views get dropped. Cascades can silently undermine applications without engineers realizing.

In my experience PostgreSQL strikes the right balance. Not unexpectedly removing objects due to hidden connections makes view management more explicit. Engineers must consciously analyze dependencies when removing views.

That said, PostgreSQL could improve visibility by traversing view dependency graphs and warning of connections prior to DROP VIEW. Graph database tooling helps provide this context upfront to make change safer.

Encapsulate Drops in Transactions

Given the data-impacting risks of haphazard view removal, I advocate encapsulating DROP operations in SQL transactions:

BEGIN;

DROP VIEW employee_view; 

COMMIT;

Transactions help increase safety by making view changes easily reversible if unexpected errors manifest:

BEGIN;

DROP VIEW employee_view; -- Breaks some dependency! 

ROLLBACK; -- Reverses DROP VIEW automatically

Rolling back allows engineers to correct resulting issues like repairing related views before attempting removal again. Defensive coding practices utilizing transactions help reduce disruption timeframe when modifying production data systems.

Set-based database changes carried high risk of unintended effects. Remediating mistakes is vital – transactions enable easy backout to keep engineers moving fast.

Summary: Prudent View Management

Views conceptualize meaningful results over complex schemas that would otherwise require inefficient, unsafe repetition of complex logic. They have become integral to delivering performant database applications.

But views accumulating over time must also undergo careful pruning to control technical debt. Removing unused or counterproductive views improves sustainability, much like pruning plants promotes healthier new growth.

By following dependency mapping, usage telemetry, deprecation warnings and fail fast strategies, engineers can prune production views safely. Dropped views need not result in destruction – rather they cultivate leaner, higher quality data systems.

Through careful removal campaigns, teams balance the creation and destruction cycles necessary for maintaining modern data platforms over the long term.

And using defensive coding techniques like transactions, inadvertent view drops become non-events instead of disasters!

Similar Posts