diff --git a/README.md b/README.md index 37f5f36..6a6017b 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,8 @@ hierarchies of dependent views. Scenic offers a `replace_view` schema statement, resulting in a `CREATE OR REPLACE VIEW` SQL query which will update the supplied view in place, retaining -all dependencies. Materialized views cannot be replaced in this fashion. +all dependencies. Materialized views cannot be replaced in this fashion, though +the `side_by_side` update strategy may yield similar results (see below). You can generate a migration that uses the `replace_view` schema statement by passing the `--replace` option to the `scenic:view` generator: @@ -137,7 +138,7 @@ end ``` Scenic even provides a `scenic:model` generator that is a superset of -`scenic:view`. It will act identically to the Rails `model` generator except +`scenic:view`. It will act identically to the Rails `model` generator except that it will create a Scenic view migration rather than a table migration. There is no special base class or mixin needed. If desired, any code the model @@ -185,6 +186,44 @@ you would need to refresh view B first, then right after refresh view A. If you would like this cascading refresh of materialized views, set `cascade: true` when you refresh your materialized view. +## Can I update the definition of a materialized view without dropping it? + +No, but Scenic can help you approximate this behavior with its `side_by_side` +update strategy. + +Generally, changing the definition of a materialized view requires dropping it +and recreating it, either without data or with a non-concurrent refresh. The +materialized view will be locked for selects during the refresh process, which +can cause problems in your application if the refresh is not fast. + +The `side_by_side` update strategy prepares the new version of the view under a +temporary name. This includes copying the indexes from the original view and +refreshing the data. Once prepared, the original view is dropped and the new +view is renamed to the original view's name. This process minimizes the time the +view is locked for selects at the cost of additional disk space. + +You can generate a migration that uses the `side_by_side` strategy by passing +the `--side-by-side` option to the `scenic:view` generator: + +```sh +$ rails generate scenic:view search_results --materialized --side-by-side + create db/views/search_results_v02.sql + create db/migrate/[TIMESTAMP]_update_search_results_to_version_2.rb +``` + +The migration will look something like this: + +```ruby +class UpdateSearchResultsToVersion2 < ActiveRecord::Migration + def change + update_view :search_results, + version: 2, + revert_to_version: 1, + materialized: { side_by_side: true } + end +end +``` + ## I don't need this view anymore. Make it go away. Scenic gives you `drop_view` too: @@ -234,7 +273,7 @@ It's our experience that maintaining a library effectively requires regular use of its features. We're not in a good position to support MySQL, SQLite or other database users. -Scenic *does* support configuring different database adapters and should be +Scenic _does_ support configuring different database adapters and should be extendable with adapter libraries. If you implement such an adapter, we're happy to review and link to it. We're also happy to make changes that would better accommodate adapter gems. @@ -242,10 +281,10 @@ accommodate adapter gems. We are aware of the following existing adapter libraries for Scenic which may meet your needs: -* [`scenic_sqlite_adapter`]() -* [`scenic-mysql_adapter`]() -* [`scenic-sqlserver-adapter`]() -* [`scenic-oracle_adapter`]() +- [`scenic_sqlite_adapter`](https://github.com/pdebelak/scenic_sqlite_adapter) +- [`scenic-mysql_adapter`](https://github.com/EmpaticoOrg/scenic-mysql_adapter) +- [`scenic-sqlserver-adapter`](https://github.com/ClickMechanic/scenic_sqlserver_adapter) +- [`scenic-oracle_adapter`](https://github.com/cdinger/scenic-oracle_adapter) Please note that the maintainers of Scenic make no assertions about the quality or security of the above adapters. @@ -255,26 +294,24 @@ quality or security of the above adapters. ### Used By Scenic is used by some popular open source Rails apps: -[Mastodon](), -[Code.org](), and -[Lobste.rs](). +[Mastodon](https://github.com/mastodon/mastodon/), +[Code.org](https://github.com/code-dot-org/code-dot-org), and +[Lobste.rs](https://github.com/lobsters/lobsters/). ### Related projects -- [`fx`]() Versioned database functions and +- [`fx`](https://github.com/teoljungberg/fx) Versioned database functions and triggers for Rails - ### Media Here are a few posts we've seen discussing Scenic: -- [Announcing Scenic - Versioned Database Views for Rails]() by Derek Prior for thoughtbot -- [Effectively Using Materialized Views in Ruby on Rails]() by Leigh Halliday for pganalyze -- [Optimizing String Concatenation in Ruby on Rails]() -- [Materialized Views In Ruby On Rails With Scenic]() by Dawid Karczewski for Ideamotive -- [Using Scenic and SQL views to aggregate data]() by André Perdigão for Redlight Software - +- [Announcing Scenic - Versioned Database Views for Rails](https://thoughtbot.com/blog/announcing-scenic--versioned-database-views-for-rails) by Derek Prior for thoughtbot +- [Effectively Using Materialized Views in Ruby on Rails](https://pganalyze.com/blog/materialized-views-ruby-rails) by Leigh Halliday for pganalyze +- [Optimizing String Concatenation in Ruby on Rails](https://dev.to/pimp_my_ruby/from-slow-to-lightning-fast-optimizing-string-concatenation-in-ruby-on-rails-28nk) +- [Materialized Views In Ruby On Rails With Scenic](https://www.ideamotive.co/blog/materialized-views-ruby-rails-scenic) by Dawid Karczewski for Ideamotive +- [Using Scenic and SQL views to aggregate data](https://dev.to/weareredlight/using-scenic-and-sql-views-to-aggregate-data-226k) by André Perdigão for Redlight Software ### Maintainers