我只是想大致了解 RDBMS 中使用的视图。也就是说,我知道什么是视图以及如何制作视图。我也知道我过去用它们做什么。
但我想确保我对视图的用途和视图不应该用于的用途有透彻的了解。进一步来说:
- 视图有什么用?
- 有没有在你不应该使用视图的情况下使用视图很诱人?
- 为什么要使用视图来代替表值函数之类的东西,反之亦然?
- 是否存在乍一看并不明显的视图可能有用的任何情况?
(为了记录,其中一些问题是故意幼稚的。这部分是概念检查。)
我只是想大致了解 RDBMS 中使用的视图。也就是说,我知道什么是视图以及如何制作视图。我也知道我过去用它们做什么。
但我想确保我对视图的用途和视图不应该用于的用途有透彻的了解。进一步来说:
(为了记录,其中一些问题是故意幼稚的。这部分是概念检查。)
在某种程度上,视图就像一个界面。您可以随心所欲地更改基础表结构,但视图提供了一种不必更改代码的方法。
视图是为报告作者提供简单内容的好方法。如果您的业务用户想要从诸如 Crystal Reports 之类的东西访问数据,您可以在他们的帐户中为他们提供一些简化数据的视图——甚至可以为他们进行非规范化。
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 asCREATE VIEW AS
SELECT * FROM tblData
1I 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 ;)
视图可用于提供安全性(即:用户可以访问仅访问表中某些列的视图),视图可以为更新、插入等提供额外的安全性。视图还提供了一种为列名取别名的方法(如sp's) 但视图更像是与实际表的隔离。
从某种意义上说,视图是非规范化的。有时需要非规范化以更有意义的方式提供数据。无论如何,这就是许多应用程序通过在其对象中进行域建模所做的事情。它们有助于以更符合企业观点的方式呈现数据。
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.
视图可以集中或整合数据。在我所在的地方,我们在几个不同的链接服务器上有许多不同的数据库。每个数据库都保存不同应用程序的数据。其中一些数据库包含与许多不同应用程序相关的信息。在这种情况下,我们要做的是在该应用程序的数据库中创建一个视图,该视图只是从真正存储数据的数据库中提取数据,这样我们编写的查询看起来就不会跨越不同的数据库。
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:
VIEW for TABLE A:
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.