Question

When I create a view I am basically making a new table that will automatically be transacted upon when data in one of the tables it joins changes; is that correct?

Also why can't I use subqueries in my view?

Was it helpful?

Solution

A view works like a table, but it is not a table. It never exists; it is only a prepared SQL statement that is run when you reference the view name. IE:

CREATE VIEW foo AS
  SELECT * FROM bar

SELECT * FROM foo

...is equivalent to running:

SELECT x.* 
  FROM (SELECT * FROM bar) x

A MySQLDump will never contain rows to be inserted into a view...

Also why can't I use subqueries in my view????

That, sadly, is by (albeit questionable) design. There's numerous limitations for MySQL views, which are documented: http://dev.mysql.com/doc/refman/5.0/en/create-view.html

So if it's just an imaginary table/prepared statement does that mean it theoretically has the same performance (or even less) as a normal table/query?


No.
A table can have indexes associated, which can make data retrieval faster (at some cost for insert/update). Some databases support "materialized" views, which are views that can have indexes applied to them - which shouldn't be a surprise that MySQL doesn't support given the limited view functionality (which only began in v5 IIRC, very late to the game).

Because a view is a derived table, the performance of the view is only as good as the query it is built on. If that query sucks, the performance issue will just snowball... That said, when querying a view - if a view column reference in the WHERE clause is not wrapped in a function (IE: WHERE v.column LIKE ..., not WHERE LOWER(t.column) LIKE ...), the optimizer may push the criteria (called a predicate) onto the original query - making it faster.

OTHER TIPS

I ran into the same problem also (to my surprise, because my search seems to indicate that Oracle and MS do support it).

I get around this limitation (at least for now, until proven non-usable) by creating two additional views for my final view.

Example:

CREATE VIEW Foo1 AS
    SELECT * FROM t ORDER BY ID, InsertDate DESC

CREATE VIEW Foo2 AS
    SELECT * FROM Foo1 GROUP BY ID

CREATE VIEW Foo AS
    SELECT * FROM Foo2 ORDER BY ID

The example above basically has a table 't' which is a temporal table containing all the revisions. My 'Foo' (view) basically is a simple view of only my most current revisions of each record. Seems to work alright for now!

Update:

I don't know if this is another bug in MySQL 5.1, but the above example doesn't in fact work! The 'Foo1' works as expected, but the 'Foo2' seems to ignore the order prior to grouping so my end result is not what is intended. I even get the same result if I change the 'DESC' for 'ASC' (surprisingly).

Also, if you read the 17.5.1. View Syntax section, it clearly states:

"A view can be created from many kinds of SELECT statements. It can refer to base tables or other views. It can use joins, UNION, and subqueries."

I'm going to update my database to 5.6 and try it again!

The difference is :

for view you can only have subqueries in the where - part, not in the from - part so a

CREATE VIEW v AS SELECT * FROM foo WHERE id IN (SELECT id FROM bar) 

would work - but at the same time you get a read-only view ... A simple view on a single table would allow to update "through" the view to the underlying table

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top