当我创建一个视图时,我基本上创建了一个新表,当它加入的一个表中的数据发生变化时,它将自动被处理;那是对的吗?
为什么我不能在视图中使用子查询?
答案 0 :(得分:51)
视图就像表一样,但它不是表。它永远不存在;它只是在引用视图名称时运行的准备好的SQL语句。 IE:
CREATE VIEW foo AS
SELECT * FROM bar
SELECT * FROM foo
......相当于跑步:
SELECT x.*
FROM (SELECT * FROM bar) x
MySQLDump永远不会包含要插入视图的行...
遗憾的是,这是(尽管有问题的)设计。 MySQL视图有许多限制,记录在案:http://dev.mysql.com/doc/refman/5.0/en/create-view.html为什么我不能在我的视图中使用子查询????
没有。
表可以关联索引,这可以使数据检索更快(插入/更新需要一些成本)。一些数据库支持“物化”视图,这些视图可以应用索引 - 鉴于视图功能有限(仅在v5中开始),MySQL 不支持这不应该是一个惊喜IIRC,比赛很晚)。
因为视图是派生表,所以视图的性能仅与构建它的查询一样好。如果该查询很糟糕,那么性能问题就会滚雪球...也就是说,在查询视图时 - 如果WHERE子句中的视图列引用未包含在函数中(IE:WHERE v.column LIKE ...
,不 WHERE LOWER(t.column) LIKE ...
),优化器可以将标准(称为谓词)推送到原始查询上 - 使其更快。
答案 1 :(得分:2)
我也遇到了同样的问题(令我惊讶的是,因为我的搜索似乎表明Oracle和MS都支持它)。
我通过为我的最终视图创建两个额外的视图来解决这个限制(至少现在,直到证明不可用)。
示例:
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
上面的示例基本上有一个表't',它是一个包含所有修订的时态表。我的'Foo'(视图)基本上只是我对每条记录的最新版本的简单视图。现在似乎工作正常!
更新
我不知道这是否是MySQL 5.1中的另一个错误,但上面的例子实际上并不起作用! 'Foo1'按预期工作,但'Foo2'似乎忽略了分组前的顺序,所以我的最终结果不是预期的。如果我为'ASC'改变'DESC'(令人惊讶的话),我甚至得到相同的结果。
另外,如果您阅读 17.5.1。查看语法部分,它明确指出:
“可以从多种SELECT语句创建视图。它可以引用基表或其他视图。它可以使用连接,UNION和子查询。”
我要将我的数据库更新为5.6并再试一次!
答案 2 :(得分:2)
区别在于:
对于视图,你只能在where - part中有子查询,而不是在from - part中这样一个
CREATE VIEW v AS SELECT * FROM foo WHERE id IN (SELECT id FROM bar)
可以工作 - 但同时你得到一个只读视图......单个表上的简单视图将允许通过视图更新到基础表