简体   繁体   中英

PostgreSQL 9.6 View Performance & Side Effects

Our project makes use of different schemas to keep things organized and secure. We GRANT access to entire schemas rather then selecting individual components which may result in an inadvertent leak of data. Additionally, it would make our lives easier if we could write our queries from a single schema as it would help with maintainability and error reduction.

For example, schema_foo and schema_bar contain raw normalized data (not accessible to the end user) and schema_baz contains functions (accessible to the end user) that return data from schema_foo and schema_bar . This makes sense when data in schema_foo and schema_bar need processing prior to delivery to the end user; however, in some cases no additional processing is required.

In this case, would it make sense to make a view in schema_baz simply calling the table in schema_foo or schema_bar and if so, what is the performance difference / side effects between

SELECT * FROM schema_foo.table_bin;

and

CREATE VIEW schema_baz.view_bin AS SELECT * FROM schema_foo.table_bin;
SELECT * schema_baz.view_bin;

If this is acceptable, is it better (for any reason) to identify each column by name rather then * ?

Note: The resulting view would also be used in other queries. I know the query planner is great; however, I'm concerned there could be unintended consequences of (ab)using views for the sole purpose of making a table accessible from another schema.

My experience leans towards "If in doubt, be explicit". Using select * in a production system is usually just asking for trouble down the road.

Also, adding columns to the base table(s) in Postgres won't change the columns in the view-- they won't magically appear. As an example:

(postgres@lh:5432) # create table foo (col1 integer, col2 text);
CREATE TABLE

(postgres@lh:5432) # create view bar as select * from foo;
CREATE VIEW

(postgres@lh:5432) # alter table foo add col3 date;
ALTER TABLE

(postgres@lh:5432) # insert into foo values (1, 'One', current_date);
INSERT 0 1

(postgres@lh:5432) [~] # select * from foo;
 col1 | col2 |    col3    
------+------+------------
    1 | One  | 2017-08-17
(1 row)

(postgres@lh:5432) # select * from bar;
 col1 | col2 
------+------
    1 | One
(1 row)

This was with version 9.5 but I would be surprised if other versions worked any differently.

Yes, tables can and do change, often. If you simply write *, then what if a column gets added or deleted in the base table? Your view changes without your knowledge.

It is best practise to always list out column names when writing views of any kind.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM