What are views good for? - sql

I'm just trying to get a general idea of what views are used for in RDBMSes. That is to say, I know what a view is and how to make one. I also know what I've used them for in the past.
But I want to make sure I have a thorough understanding of what a view is useful for and what a view shouldn't be useful for. More specifically:
What is a view useful for?
Are there any situations in which it is tempting to use a view when you shouldn't use one?
Why would you use a view in lieu of something like a table-valued function or vice versa?
Are there any circumstances that a view might be useful that aren't apparent at first glance?
(And for the record, some of these questions are intentionally naive. This is partly a concept check.)

In a way, a view is like an interface. You can change the underlying table structure all you want, but the view gives a way for the code to not have to change.
Views are a nice way of providing something simple to report writers. If your business users want to access the data from something like Crystal Reports, you can give them some views in their account that simplify the data -- maybe even denormalize it for them.

1) What is a view useful for?
IOPO In One Place Only•Whether you consider the data itself or the queries that reference the joined tables, utilizing a view avoids unnecessary redundancy. •Views also provide an abstracting layer preventing direct access to the tables (and the resulting handcuffing referencing physical dependencies). In fact, I think it's good practice1 to offer only abstracted access to your underlying data (using views & table-valued functions), including views such as CREATE VIEW AS SELECT * FROM tblData1I hafta admit there's a good deal of "Do as I say; not as I do" in that advice ;)
2) Are there any situations in which it is tempting to use a view when you shouldn't use one?
Performance in view joins used to be a concern (e.g. SQL 2000). I'm no expert, but I haven't worried about it in a while. (Nor can I think of where I'm presently using view joins.)Another situation where a view might be overkill is when the view is only referenced from one calling location and a derived table could be used instead. Just like an anonymous type is preferable to a class in .NET if the anonymous type is only used/referenced once. • See the derived table description in http://msdn.microsoft.com/en-us/library/ms177634.aspx
3) Why would you use a view in lieu of something like a table-valued function or vice versa?
(Aside from performance reasons) A table-valued function is functionally equivalent to a parameterized view. In fact, a common simple table-valued function use case is simply to add a WHERE clause filter to an already existing view in a single object.
4) Are there any circumstances that a view might be useful that aren't apparent at first glance?
I can't think of any non-apparent uses of the top of my head. (I suppose if I could, that would make them apparent ;)

Views can be used to provide security (ie: users can have access to views that only access certain columns in a table), views can provide additional security for updates, inserts, etc. Views also provide a way to alias column names (as do sp's) but views are more of an isolation from the actual table.

In a sense views denormalize. Denormalization is sometimes necessary to provide data in a more meaningful manner. This is what a lot of applications do anyway by way of domain modeling in their objects. They help present the data in a way that more closely matches a business' perspective.

In addition to what the others have stated, views can also be useful for removing more complecated SQL queries from the application.
As an example, instead of in an application doing:
sql = "select a, b from table1 union
select a, b from table2";
You could abstract that to a view:
create view union_table1_table2_v as
select a,b from table1
union
select a,b from table2
and in the app code, simply have:
sql = "select a, b from union_table1_table2_v";
Also if the data structures ever change, you won't have to change the app code, recompile, and redeploy. you would just change the view in the db.

Views hide the database complexity. They are great for a lot of reasons and are useful in a lot of situations, but if you have users that are allowed to write their own queries and reports, you can use them as a safeguard to make sure they don't submit badly designed queries with nasty cartesian joins that take down your database server.

The OP asked if there were situations where it might be tempting to use a view, but it's not appropriate.
What you don't want to use a view for is a substitute for complex joins. That is, don't let your procedural programming habit of breaking a problem down into smaller pieces lead you toward using several views joined together instead of one larger join. Doing so will kill the database engine's efficiency since it's essentially doing several separate queries rather than one larger one.
For example, let's say you have to join tables A, B, C, and D together. You may be tempted to make a view out of tables A & B and a view out of C & D, then join the two views together. It's much better to just join A, B, C, and D in one query.

Views can centralize or consolidate data. Where I'm at we have a number of different databases on a couple different linked servers. Each database holds data for a different application. A couple of those databases hold information that are relavent to a number of different applications. What we'll do in those circumstances is create a view in that application's database that just pulls data from the database where the data is really stored, so that the queries we write don't look like they're going across different databases.

The responses so far are correct -- views are good for providing security, denormalization (although there is much pain down that road if done wrong), data model abstraction, etc.
In addition, views are commonly used to implement business logic (a lapsed user is a user who has not logged in in the last 40 days, that sort of thing).

Views save a lot of repeated complex JOIN statements in your SQL scripts. You can just encapsulate some complex JOIN in some view and call it in your SELECT statement whenever needed. This would sometimes be handy, straight forward and easier than writing out the join statements in every query.

A view is simply a stored, named SELECT statement. Think of views like library functions.

I wanted to highlight the use of views for reporting. Often, there is a conflict between normalizing the database tables to speed up performance, especially for editing and inserting data (OLTP uses), and denormalizing to reduce the number of table joins for queries for reporting and analysis (OLAP uses). Of necessity, OLTP usually wins, because data entry must have optimal performance. Creating views, then, for optimal reporting performance, can help to satisfy both classes of users (data entry and report viewers).

I remember a very long SELECT which involved several UNIONs. Each UNION included a join to a price table which was created on the fly by a SELECT that was itself fairly long and hard to understand. I think it would have been a good idea to have a view that to create the price table. It would have shortened the overall SELECT by about half.
I don't know if the DB would evaluate the view once, or once each time in was invoked. Anyone know? If the former, using a view would improved performance.

Anytime you need [my_interface] != [user_interface].
Example:
TABLE A:
id
info
VIEW for TABLE A:
Customer Information
this is a way you might hide the id from the customer and rename the info to a more verbose name both at once.
The view will use underlying index for primary key id, so you won't see a performance loss, just better abstraction of the select query.

Related

Refactoring big database views

I am an intern (which means I have no decision power, I know sql and pl/sql) and got the Task to refactor some huge database views
Basically the problem is that all views relay on big view which is querying all data and the other views filter further (thoes views all query data for letters and emails) these views are Not documented so I need to find out what they do and rebuild them so that there won't be a query that acquires all that from the database.
My problem is that those views (btw each about 600 lines) are written very wiredly (as far as I know written by a non programmer) and I have no idea where to start, what is the first thing todo? What would you suggest?
This is one of those "stick your finger in the air" kind of questions; it's almost impossible to say what you should do, as it depends entirely on the sql used to create the views, the data in the tables, the structure of the tables etc, etc.
My suggestion would be to start with the base view and see what basic things you can do to aid peformance - for example, can you make use of sub-query factoring? can you change things to filter early? Can things be replaced by an analytic query?
Break things down, too. If you have a subquery in the original view that you think can be optimised, well, it's easy to compare the results of two different sql statements - if they match, it's generally a good indication that you've rewritten the statement correctly (not always, though, so be careful! Test thoroughly!)
Breaking a complex query down to its constituent parts should also allow you to work out what it's trying to do a lot easier!

Is there a reason not to use views in Oracle?

I have recently noticed that nobody uses views in my company (and it's a big company).
I want to create a few views largely because they make my queries simpler to the eye, and these views are on somewhat big tables that don't get very frequent updates (once a day).
My alternative is to create a type table of type record an populate it each time a SP is called. Is this better than using a view? (my guess is no)
PS: database is oracle 10g and
EDIT:
- yes i have asked around but no one could give me a reason.
- both the views and the queries that will be using them are heavy on joins.
Aesthetics doesn't have a place in SQL, or coding in general, when there's performance implications.
If the optimizer determines that predicate pushing can occur, a view will be as good as directly querying the table(s) the view represents. And as Justin mentions, because a view is a macro that expands into the underlying query the view represents -- a soft parse (re-use of the query from cache) is very likely because the cache check needs to match queries exactly.
But be aware of the following:
layering views (one view based on another) is a bad practice -- errors won't be encountered until the view is run
joining views to other tables and or views is highly suspect -- the optimizer might not see things as well if the underlying query is in place of the view reference. I've had such experiences, because the views joined to were doing more than what the query needed -- sometimes, the queries from all the views used were condensed into a single query that ran much better.
I recommend creating your views, and comparing the EXPLAIN plans to make sure that you are at least getting identical performance. I'd need to see your code for populating a TYPE before commenting on the approach, but it sounds like a derived table in essence...
It's possible you would benefit from using materialized views, but they are notorious restricted in what they support.
It certainly sounds like creating some views would be helpful in this case.
Have you asked around to see why no one uses views? That seems quite odd and would certainly tend to indicate that you're not reusing your SQL very efficiently. Without views, you'd tend to put the same logic in many different SQL statements rather than in a single view which would make maintenance a pain.
One reason not to use views which may or may not be valid... is that they have the potential to create complexity where there isn't any
For example I could write
CREATE VIEW foo as <SOME COMPLEX QUERY>
then later I could write
CREATE Procedure UseFoo as
BEGIN
SELECT
somefields
FROM
x
INNER JOIN foo
.....
So now I'm creating to objects that need to be deployed, maintained, version controlled etc...
Or I could write either
CREATE Procedure UseFoo as
BEGIN
WITH foo as (<SOME COMPLEX QUERY>)
SELECT
somefields
FROM
x
INNER JOIN foo
.....
or
CREATE Procedure UseFoo as
BEGIN
SELECT
somefields
FROM
x
INNER JOIN <SOME COMPLEX QUERY> foo
.....
And now I only need to deploy, maintain, and version control a single object.
If <SOME COMPLEX QUERY> only exists in one context maintaining two separate objects creates an unnecessary burden. Also after deployment any changes to requires evaluating things that rely on UseFoo. When two object you need to visit anything that evaluating on UseFoo and Foo
Of course on the other hand if Foo represents some shared logic the evaluation is required anyway but you only have to find and change a single object.
It has been my experience that when you have a large/complex database and some complex queries and no views, it is just because the users just don't know what views are, or how to use them. Once I explained the benifits of using a view, most people used them with out any problems.
From your description, I would just make a view, not a new table.
Views are great for hiding complexity -- if your users can just run the views you create as-is (as opposed to writing a query against the view), this is good.
But views also come with performance issues -- if your users know how to write sql, and they understand the tables they're using, it might be better to let them keep doing that.
Consider also that stored procedures are less prone to (the same) performance issues that views are.
here is a link to and a snippet from a nice article that describes views as well as how to tune them for better peformance.
Uses of Views
Views are useful for providing a horizontal or vertical subset of data
from a table (possibly for security reasons) ; for hiding the
complexity of a query; for ensuring that exactly the same SQL is used
throughout your application; and in n-tier applications to retrieve
supplementary information about an item from a related table......
http://www.smart-soft.co.uk/Oracle/oracle-tuning-part4-vw-use.htm

SQL Views vs. Database Abstraction (in code)

I just learned about SQL views, which seem nice, but if I abstract table joining to a data access class, wouldn't this accomplish the same thing? What are your thoughts on this? I've never used views before so this is all pretty new to me.
Remember that not all applications that hit your your database may be using the same data access classes. Nor are they used in exports or reporting. The views are a better place to abstract some complex things (such as how to get certain kinds of financial information) if you want consistentcy. However, don't go overboard with abstracting things to views either. Views should not call views (at least in Sql Server but I suspect in other dbs as well) because you have to materialize all the underlying views to get the data in the top layer. This means to get to the three records you want, you might end up materializing millions of records first. With large tables this can create a performance problem of nightmare proportions. Further views that call views that call views become a truly difficult maintenance problem when something needs to be fixed.
The main purpose of a view is to abstract the complexity of creating a specific result set. In large relational databases, you often need to join many tables together to get useful data. By creating views, any client can access it without needing access to your database access layer.
Additionally, almost all RDMSs will optimize a view by caching the parsed execution plan. If you query is complicated enough, you may hit a substantial query planning hit when executing the query. However, with a view, the query plan is created and saved when the view is created or when it is used for the first time.
Views can also be great for maintaining backward compatibility. Say you have a table that needs to change, but it would be difficult to update all the clients at once to use the new table schema. You could create a view with the old table name that provides the backwards compatibility. You can then create a new table with the new schema.
I'd say one of the main purposes of views are to simplify the interface betwen a complex database (whether it be star schema/OLTP) and another layer (user / OLAP cube / reporting interface).
I guess broadly I'd say that if there can be multiple ways that you can access your database (MS Excel/.net app) then you would want to use SQL views as then they are available to all, otherwise if you create a data access class in c# (e.g.), then it wont be usable by the MS Excel people.
Views simply put, reduce the complex look of all the joins put together in a sql query.
So instead of executing a join on 30 tables, a view does the 30 table join but then can be reused in another view / sproc to simply say:
SELECT * FROM myView
Rather then:
SELECT...
FROM
...
INNER JOIN
...
INNER JOIN
...
INNER JOIN
...
It basically hides all these details. This article should be a great reference: http://www.craigsmullins.com/cnr_0299b.htm
The point is views are not physical structures, they are simply a relational model or "view" of one or many tables in a database system.
Abstracting joins to a data access class might give you the same data, but it might not give you the same performance.
Also, for most businesses the database is a shared resource. It's sensible to assume that there are applications already hitting the database that cannot or will not go through your data access class. It's also sensible to assume that some future applications cannot or will not go through your data access class. As a trivial example, the command-line interface and the graphical interface to any dbms you use won't be using your data access class.
Views are also the way SQL databases implement logical data independence. Think of them as part of the public interface.
Views can be shared by interactive SQL users, report writers, OLAP tools, and applications written in different languages or by multiple programming teams that don't share classes with eahc other.
As such, it's a good way for database designers to share standardized queries across the whole community of users of the data.

When to use a View instead of a Table?

When should a View actually be used over an actual Table? What gains should I expect this to produce?
Overall, what are the advantages of using a view over a table? Shouldn't I design the table in the way the view should look like in the first place?
Oh there are many differences you will need to consider
Views for selection:
Views provide abstraction over tables. You can add/remove fields easily in a view without modifying your underlying schema
Views can model complex joins easily.
Views can hide database-specific stuff from you. E.g. if you need to do some checks using Oracles SYS_CONTEXT function or many other things
You can easily manage your GRANTS directly on views, rather than the actual tables. It's easier to manage if you know a certain user may only access a view.
Views can help you with backwards compatibility. You can change the underlying schema, but the views can hide those facts from a certain client.
Views for insertion/updates:
You can handle security issues with views by using such functionality as Oracle's "WITH CHECK OPTION" clause directly in the view
Drawbacks
You lose information about relations (primary keys, foreign keys)
It's not obvious whether you will be able to insert/update a view, because the view hides its underlying joins from you
Views can:
Simplify a complex table structure
Simplify your security model by allowing you to filter sensitive data and assign permissions in a simpler fashion
Allow you to change the logic and behavior without changing the output structure (the output remains the same but the underlying SELECT could change significantly)
Increase performance (Sql Server Indexed Views)
Offer specific query optimization with the view that might be difficult to glean otherwise
And you should not design tables to match views. Your base model should concern itself with efficient storage and retrieval of the data. Views are partly a tool that mitigates the complexities that arise from an efficient, normalized model by allowing you to abstract that complexity.
Also, asking "what are the advantages of using a view over a table? " is not a great comparison. You can't go without tables, but you can do without views. They each exist for a very different reason. Tables are the concrete model and Views are an abstracted, well, View.
Views are acceptable when you need to ensure that complex logic is followed every time. For instance, we have a view that creates the raw data needed for all financial reporting. By having all reports use this view, everyone is working from the same data set, rather than one report using one set of joins and another forgetting to use one which gives different results.
Views are acceptable when you want to restrict users to a particular subset of data. For instance, if you do not delete records but only mark the current one as active and the older versions as inactive, you want a view to use to select only the active records. This prevents people from forgetting to put the where clause in the query and getting bad results.
Views can be used to ensure that users only have access to a set of records - for instance, a view of the tables for a particular client and no security rights on the tables can mean that the users for that client can only ever see the data for that client.
Views are very helpful when refactoring databases.
Views are not acceptable when you use views to call views which can result in horrible performance (at least in SQL Server). We almost lost a multimillion dollar client because someone chose to abstract the database that way and performance was horrendous and timeouts frequent. We had to pay for the fix too, not the client, as the performance issue was completely our fault. When views call views, they have to completely generate the underlying view. I have seen this where the view called a view which called a view and so many millions of records were generated in order to see the three the user ultimately needed. I remember one of these views took 8 minutes to do a simple count(*) of the records. Views calling views are an extremely poor idea.
Views are often a bad idea to use to update records as usually you can only update fields from the same table (again this is SQL Server, other databases may vary). If that's the case, it makes more sense to directly update the tables anyway so that you know which fields are available.
According to Wikipedia,
Views can provide many advantages over tables:
Views can represent a subset of the data contained in a table.
Views can limit the degree of exposure of the underlying tables to the outer world: a given user may have permission to query the view, while denied access to the rest of the base table.
Views can join and simplify multiple tables into a single virtual table.
Views can act as aggregated tables, where the database engine aggregates data (sum, average, etc.) and presents the calculated results as part of the data.
Views can hide the complexity of data. For example, a view could appear as Sales2000 or Sales2001, transparently partitioning the actual underlying table.
Views take very little space to store; the database contains only the definition of a view, not a copy of all the data that it presents.
Views can provide extra security, depending on the SQL engine used.
A common practice is to hide joins in a view to present the user a more denormalized data model. Other uses involve security (for example by hiding certain columns and/or rows) or performance (in case of materialized views)
Views are handy when you need to select from several tables, or just to get a subset of a table.
You should design your tables in such a way that your database is well normalized (minimum duplication). This can make querying somewhat difficult.
Views are a bit of separation, allowing you to view the data in the tables differently than they are stored.
You should design your table WITHOUT considering the views.
Apart from saving joins and conditions, Views do have a performance advantage: SQL Server may calculate and save its execution plan in the view, and therefore make it faster than "on the fly" SQL statements.
View may also ease your work regarding user access at field level.
First of all as the name suggests a view is immutable. thats because a view is nothing other than a virtual table created from a stored query in the DB.
Because of this you have some characteristics of views:
you can show only a subset of the data
you can join multiple tables into a single view
you can aggregate data in a view (select count)
view dont actually hold data, they dont need any tablespace since they are virtual aggregations of underlying tables
so there are a gazillion of use cases for which views are better fitted than tables, just think about only displaying active users on a website. a view would be better because you operate only on a subset of the data which actually is in your DB (active and inactive users)
check out this article
hope this helped..

Is it okay to have a lot of database views?

I infrequently (monthly/quarterly) generate hundreds of Crystal Reports reports using Microsoft SQL Server 2005 database views. Are those views wasting CPU cycles and RAM during all the time that I am not reading from them? Should I instead use stored procedures, temporary tables, or short-lived normal tables since I rarely read from my views?
I'm not a DBA so I don't know what's going on behind the scenes inside the database server.
Is it possible to have too many database views? What's considered best practice?
For the most part, it doesn't matter. Yes, SQL Server will have more choices when it parses SELECT * FROM table (it'll have to look in the system catalogs for 'table') but it's highly optimized for that, and provided you have sufficient RAM (most servers nowadays do), you won't notice a difference between 0 and 1,000 views.
However, from a people-perspective, trying to manage and figure out what "hundreds" of views are doing is probably impossible, so you likely have a lot of duplicated code in there. What happens if some business rules change that are embedded in these redundant views?
The main point of views is to encapsulate business logic into a pseudo table (so you may have a person table, but then a view called "active_persons" which does some magic). Creating a view for each report is kind of silly unless each report is so isolated and unique that there is no ability to re-use.
A view is a query that you run often with preset parameters. If you know you will be looking at the same data all the time you can create a view for ease of use and for data binding.
That being said, when you select from a view the view defining query is run along with the query you are running.
For example, if vwCustomersWhoHavePaid is:
Select * from customers where paid = 1
and the query you are running returns the customers who have paid after August first is formatted like this:
Select * from vwCustomersWhoHavePaid where datepaid > '08/01/08'
The query you are actually running is:
Select * from (Select * from customers where paid = 1) where datepaid > '08/01/08'
This is something you should keep in mind when creating views, they are a way of storing data that you look at often. It's just a way of organizing data so it's easier to access.
The views are only going to take up cpu/memory resources when they are called.
Anyhow, best practice would be to consolidate what can be consolidated, remove what can be removed, and if it's literally only used by your reports, choose a consistent naming standard for the views so they can easily be grouped together when looking for a particular view.
Also, unless you really need transactional isolation, consider using the NOLOCK table hint in your queries.
-- Kevin Fairchild
You ask: What's going on behind the scenes?
A view is a bunch of SQL text. When a query uses a view, SQL Server places that SQL text into the query. This happens BEFORE optimization. The result is the optimizer can consider the combined code instead of two separate pieces of code for the best execution plan.
You should look at the execution plans of your queries! There is so much to learn there.
SQL Server also has a concept of a clustered view. A clustered view is a system maintained result set (each insert/update/delete on the underlying tables can cause insert/update/deletes on the clustered view's data). It is a common mistake to think that views operate in the way that clustered views operate.