Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL视图是如何工作的?_Sql_Mysql_Sql View - Fatal编程技术网

MySQL视图是如何工作的?

MySQL视图是如何工作的?,sql,mysql,sql-view,Sql,Mysql,Sql View,当我创建一个视图时,我基本上是在创建一个新表,当它所连接的其中一个表中的数据发生变化时,该表将自动进行事务处理;对吗 还有,为什么不能在视图中使用子查询?视图的工作原理类似于表,但它不是表。它从不存在;它只是在引用视图名称时运行的准备好的SQL语句。即: CREATE VIEW foo AS SELECT * FROM bar SELECT * FROM foo …相当于运行: SELECT x.* FROM (SELECT * FROM bar) x MySQLDump永远不会

当我创建一个视图时,我基本上是在创建一个新表,当它所连接的其中一个表中的数据发生变化时,该表将自动进行事务处理;对吗

还有,为什么不能在视图中使用子查询?

视图的工作原理类似于表,但它不是表。它从不存在;它只是在引用视图名称时运行的准备好的SQL语句。即:

CREATE VIEW foo AS
  SELECT * FROM bar

SELECT * FROM foo
…相当于运行:

SELECT x.* 
  FROM (SELECT * FROM bar) x
MySQLDump永远不会包含要插入到视图中的行

还有,为什么我不能在视图中使用子查询

可悲的是,这是出于(尽管值得怀疑)设计。MySQL视图有很多限制,有文档记录:


那么,如果它只是一个虚构的表/准备好的语句,这是否意味着它在理论上具有与普通表/查询相同的性能(甚至更低)?
否。
一个表可以有相关联的索引,这可以使数据检索更快(插入/更新需要付出一定的代价)。一些数据库支持“物化”视图,即可以应用索引的视图-鉴于视图功能有限(仅从v5 IIRC开始,游戏进行得很晚),MySQL不支持也就不足为奇了


因为视图是一个派生表,所以视图的性能仅与它所基于的查询一样好。如果这个查询糟糕透顶,那么性能问题就会越滚越大。。。也就是说,当查询视图时-如果WHERE子句中的视图列引用未包装在函数中(即:
WHERE v.column LIKE…
notWHERE 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中的另一个bug,但上面的例子实际上不起作用!“Foo1”按预期工作,但“Foo2”似乎忽略了分组前的顺序,因此我的最终结果不是预期的结果。如果我将“DESC”改为“ASC”,我甚至会得到同样的结果(令人惊讶)

此外,如果您阅读17.5.1。查看语法部分,它清楚地说明:

视图可以由多种SELECT语句创建。它可以引用基表或其他视图。它可以使用联接、联合和子查询

我要将我的数据库更新到5.6,然后再试一次

区别在于:

对于视图,只能在where-part中有子查询,而不能在from-part中有子查询

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

可以-但同时您可以获得只读视图。。。单个表上的简单视图将允许“通过”视图更新到底层表

不知道MySQL无法执行子查询。。。很高兴知道。@Slokun:MySQL视图不能使用子查询-子查询在典型的SQL语句中很好。因此,如果它只是一个虚构的表/准备好的语句,这是否意味着它在理论上具有与普通表/查询相同的性能(甚至更低)?是的,我说错了。以前在MySQL中做过子查询,但我认为我从来没有必要在其中创建视图。@Slokun:不用担心,我只是学究,因为过去有过误解。结论是,似乎没有MySQL能够修复视图中的分组错误。所以,由于这个原因,什么都不管用,我几乎尝试了我能得到的每一个该死的版本。这是MySQL的悲哀。。。真的期待更多!我也有一个左连接的子查询