Can Materialized Views in PostgreSQL inherit? - postgresql

I use PostgreSQL for time series data. There is an Event table and partitioned tables like Event_2016, Event_2017 which inherit from Event with a CONSTRAINT CHECK for the date range. So when querying the Event table, PostgreSQL uses only the child tables that are needed.
To roll up events I use an EventByDay materialized view. Refreshing this requires reading from all Event_* tables.
Can I use Materialized Views the same way as tables above to limit the amount of data in each Materialized View? (EventByDay_2016 inherits from EventByDay).

No, a MVIEW can not participate in table inheritance.
But you can create a (regular) child table and then use insert into .. select ... using the query from the MVIEW. If you want to store the MVIEW's query in the database then create a view that you use for populating the child table.
Something like this:
Initial setup:
create view v_event_by_day_2016
as
-- this is the complete query from your MVIEW
select ...;
create table event_by_day_2016
as
select *
from v_view_one;
alter table event_by_day_2016 inherit event_by_day;
alter table event_by_day_2016 add constraint check (...);
Refresh the table:
truncate table event_by_day_2016;
insert into event_by_day_2016
select *
from v_event_by_day_2016;
Alternatively you can use delete to so that the data in the child table can be refreshed in a transactional manner.

Related

How to create materialized view of an external table

CREATE VIEW materialized_view WITH SCHEMABINDING AS
SELECT ...
FROM ext.external_table
Fails with
The option 'SCHEMABINDING' is not supported with external tables.
If I understand correctly SCHEMABINDING is necessary to make a materialized view.
How can I correct this query?
You cannot create an indexed view based on tables that are in a different database.
I think your options are:
a) create the indexed view in the other database and create a regular view in this database to query that indexed view
b) create a copy of the table in this database and a mechanism to update this table whenever the data is changed in the table which is in the other database; this could be done with triggers, replication, a stored procedure called on a schedule, etc.

SQL Server 2016 - System_Versioned table - Re-create existing table with meaningful SysStartTime and SysEndTime fields

We have two tables, Events and EventsLog. The Events table is shown below
The EventsLog table is used to keep a history of changes made to the Events table via a trigger on UPDATE in the Events table.
Since Temporal tables was added to SQL 2016, we now want to use system_versioning to keep a log of our changes to the Events table.
We have setup a new EventsTemporal table to migrate over the existing data and the EventsTemporal_History table is working nicely, logging historical entries from EventsTemporal
However, we cannot override the SysStartTime and SysEndTime. Currently we can only apply default into these fields when performing an INSERT statement.
The question is, using any method possible, can we override the SysStartTime and SysEndTime fields so we can INSERT meaningful datetime2's into them, to make use of the EventsTemporal_History table?
This is currently how the EventsTemporal table looks. Notice the SysStartTime field, we want to be able to populate these fields with our own 'timestamp' and not use SQLs default.
Ideally we want to be able to populate these fields like the below.
Disable SYSTEM_VERSIONING on EventsTemporal.
ALTER TABLE EventsTemporal SET ( SYSTEM_VERSIONING = OFF );
Update EventsTmeporal as normal table.
UPDATE D
SET D.SysStartDate = S.EventDate
FROM dbo.EventsTemporal AS D
INNER JOIN dbo.Events AS S
ON D.EventId = S.EventId;
Enable SYSTEM_VERSIONING on EventTemporal;
ALTER TABLE dbo.EventsTemporal ADD PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime);
ALTER TABLE dbo.EventsTemporal ALTER COLUMN SysStartTime ADD HIDDEN;
ALTER TABLE dbo.EventsTemporal ALTER COLUMN SysEndTime ADD HIDDEN;
ALTER TABLE dbo.EventsTemporal
SET ( SYSTEM_VERSIONING = ON ( HISTORY_TABLE = dbo.EventsTemporal_History ) );

How to migrate dependent views when deep copying the table

I am adding distkey/sortkey to all my tables in redshift and would like to automate this. I am doing the following:
ALTER TABLE table RENAME TO tmp_table;
CREATE TABLE table
distkey(id)
sortkey(id)
AS
select * from tmp_table;
DROP TABLE tmp_table;
This works great, except the views don't get migrated. When you ALTER TABLE, the existing views would point to the tmp_table. Ideally I want to restore the views to the way before, possibly in the same query transaction or as part of a script.
In your migration procedure:
For each view execute:
select definition from pg_views where viewname = 'my_view';
And store all the results.
Execute for all views:
drop view 'my_view'; // or rename only to have a rollback option
Alter your tables
Execute the create view commands obtained in step 2
Just drop and recreate the views. That could be part of the script.
Views might not form part of a transaction, so some testing might be required.

Convert a view to a table in PostgreSQL

I have a view view_a in my database on which several other views depend (view_b, view_c, etc.)
I need to convert view_a into a table, because I no longer want the information in this relation to be dynamic and I need the capability to edit rows manually.
Can I replace view_a with a table without doing a DROP CASCADE and redefining all views that reference view_a?
Clarification: I want view_b and view_c to continue to reference view_a (now a table). I want to replace a view with a table, not have a table in addition to a view.
I was able to resolve this without tracking down and redefining all objects that depend on view_a, at the expense of adding one level of useless redirection.
-- create a copy of the result of view_a
CREATE TABLE table_a AS SELECT * FROM view_a;
-- redefine view_a to its own result
CREATE OR REPLACE VIEW view_a AS SELECT * FROM table_a;

TOAD-Modify Materialized View Select Query without dropping

Is there any way I can edit the MVIEW query without dropping it in TOAD.I am not sure if we can do it?If not how Can I do it in a way that does not affect the table contents?
Thanks in advance
You can't alter a materialized view query, you have to drop and recreate it.
See: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_2001.htm
Use the ALTER MATERIALIZED VIEW statement to modify an existing
materialized view in one or more of the following ways:
To change its storage characteristics
To change its refresh method, mode, or time
To alter its structure so that it is a different type of materialized
view
To enable or disable query rewrite
As pointed out by Jeffre Kemp, you cannot change the query of an existing Materialized View.
However, if you expect that changes will be necessary in the future, you can choose one of these approaches:
use an intermediate VIEW that does all the heavy lifting; your MATERIALIZED VIEW then does a simple SELECT * FROM myView. This allows you to change the query - however, it does not allow you to add / remove columns to/from the MATERIALIZED VIEW
use a pre-built table for your materialized view; this logically separates the TABLE that holds the content from the query that is used to update the content. Now, you can drop the MATERIALIZED VIEW, add/remove columns from your TABLE as needed, and re-create the MATERIALIZED VIEW afterwards
use a synonym for all code that queries the MATERIALIZED VIEW; if necessary, create a backup table using CTAS, point the synonym to this backup table, drop and re-create your MATERIALIZED VIEW, point the synonym back to the MATERIALIZED VIEW, and drop your backup table (that's how we do it)