当我创建一个视图时,我基本上是在创建一个新表,当它连接的其中一个表中的数据发生变化时,它将自动进行事务处理;那是对的吗?
另外为什么我不能在我的视图中使用子查询?
视图像表格一样工作,但它不是表格。它永远不存在;它只是在您引用视图名称时运行的准备好的 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 IIRC 中开始,游戏非常晚,MySQL不支持这一点并不奇怪) )。
因为视图是派生表,所以视图的性能仅与构建它的查询一样好。如果该查询很糟糕,性能问题只会滚雪球......也就是说,在查询视图时 - 如果 WHERE 子句中的视图列引用未包装在函数中(IE: WHERE v.column LIKE ...
,not WHERE LOWER(t.column) LIKE ...
),优化器可能会推送标准(称为谓词)到原始查询 - 使其更快。
我也遇到了同样的问题(令我惊讶的是,因为我的搜索似乎表明 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”更改为“ASC”,我什至会得到相同的结果(令人惊讶)。
另外,如果您阅读17.5.1. 查看语法部分,它明确指出:
“可以从多种 SELECT 语句创建视图。它可以引用基表或其他视图。它可以使用连接、UNION 和子查询。”
我要把我的数据库更新到 5.6,然后再试一次!
区别在于:
对于视图,您只能在 where - 部分有子查询,而不是在 from - 部分所以
CREATE VIEW v AS SELECT * FROM foo WHERE id IN (SELECT id FROM bar)
会工作 - 但同时你会得到一个只读视图......单个表上的简单视图将允许“通过”视图更新到基础表