MySQL视图 vs PHP查询

21

我正在开发一个Web应用程序,其中包括创建各种列表中的餐厅列表,如“Joe的必游之地”。现在,对于每个餐厅和列表,我都需要在网站上显示一些内容来计算:

  • 餐厅的受欢迎程度
  • 列表的受欢迎程度
  • 餐厅出现在多少个列表中

目前,我在PHP中使用MySQL语句来实现这一点,但计划切换到MySQL VIEWS并在PHP中执行简单的选择语句...

我的问题是, 使用VIEWS相比在PHP中编写SQL查询的优势/劣势是什么?

回答:使用MySQL视图(VIEWS)的主要优势是可以重用复杂的SQL查询。视图可以看作是虚拟表格,它们基于SELECT查询构建。当您需要执行同一查询的多个实例时,通过使用视图可以减少代码的重复程度。此外,视图提高了数据安全性,因为可以通过授予对视图的访问权限来限制用户对底层表的访问。
使用视图的劣势是可能会导致一些性能损失。由于视图是动态计算的,因此在涉及大型数据集或复杂查询的情况下,视图可能会比直接查询表格慢。因此,需要谨慎地评估使用视图的优势和劣势,并根据具体的用例做出决策。

1
这个问题在我看来太宽泛了,你想要什么样的优势?代码可维护性?查询速度?还是其他方面的? - Andreas Wong
为什么不发布你的ER模型或架构,这样我们就可以建议优化方式。 - Jon Black
我想要了解更广泛的视角,需要在多个项目中使用它。 - Tarun
3
使用视图,就这样。你的生活会变得更加轻松。视图可以让代码更加简洁,只需在一个单一的点上编辑大部分数据库查询。在 PHP 中,请确保按名称引用列而不是按编号引用以保持视图的可编辑性。我转向了视图,我有一些复杂的查询需要运行好几页。如果我在 PHP 中实现,我可能已经疯了。 - Jason
谢谢Jason,我已经将我的架构从在PHP中使用SQL查询转换为使用视图。 - Tarun
5个回答

16
使用视图可以增加抽象层次:如果您稍后更改表结构,则无需更改显示有关列表信息的代码,因为您仍将查询视图(虽然视图定义可能会更改)。
主要区别在于,在每次插入后更新视图,使数据在您查询视图时处于“准备就绪”状态,而使用自定义查询将导致MySQL每次计算所有内容(当然有一些缓存)。
最重要的是,如果您的列表更新频率低于其查看频率,则使用视图会提高性能。

1
“每次插入后视图都会更新”--您是什么意思?您是否意味着视图是预先计算和缓存的? - jrharshath
如果你使用MySQL,也许可以看一下http://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html。你有两种方式,一种是临时表,另一种是内联模式。在这两种视图中,都会执行SQL语句,在`MERGE`中,它会被“粘贴”到调用SQL中,但是在`TEMPTABLE`中,会创建一个临时表并填充查询数据(因此锁可以释放)。 - PhoneixS

5
原问题是关于优缺点的,但是目前答案中并没有看到太多的缺点。 那么,视图的一个缺点不就是它们可以给你带来虚假的简单查询的安慰吗?例如,SELECT username FROM myview WHERE id='1'。看起来很简单,但是如果“myview”是一个非常复杂的SELECT……甚至是基于其他视图构建的呢?最终会出现一个看起来很简单的查询,在后台却需要比从头开始编写查询时更多的工作量。
我一直在尝试使用视图,尽管有很多好处,但我还没有被完全说服。我想听听其他人对视图的缺点的看法,而不仅仅是为什么视图如此出色的说辞。可能仍然会转换,但希望了解有关性能的更多信息。

4

我的完整答案取决于几个方面(从您的应用程序角度):

  • 您是否计划允许用户创建和共享此类列表?
  • 用户可以创建任何类型的列表,还是只能通过将值插入现有查询模板来创建?

假设您有一些预定义的列表要显示:

使用视图有几个优点:

  • 您的代码将更加简洁
  • 生成视图的查询不需要每次由mysql解析。

我不确定这一点:我不认为mysql像Tomasz建议的那样缓存视图 - 我不认为视图包含“已经准备好的数据”。

一个缺点是创建列表所涉及的逻辑进入数据库而不是存在于您的PHP代码中 - 这是我非常反感的事情。在我的世界里,数据库是用于数据的,代码是用于逻辑的。

干杯


我说过这句话吗?:) 我只是说频繁更改数据库(即插入视图表中的数据)将使视图不断更新,因此性能会受到影响...好吧,如果您所说的“视图缓存”指的是视图查询缓存,那么是的,已编译的查询被存储并在用户尝试从视图获取数据时使用。视图不“包含”数据,我只是指数据库引擎持有准备好的数据以供视图使用,它不是按请求“即时计算”的。 - Tomasz Kowalczyk
嗯,我肯定是误解了。 - jrharshath
1
@TomaszKowalczyk,您可以将我链接到您看到的数据准备用于查看的位置吗?从阅读周围的内容来看,似乎查询像往常一样在后台运行(具有连接、联合等),因此实际上没有任何性能优势。编辑:我想您谈论的是临时表视图。它们没有索引,因此查询大表将非常缓慢。除非您只有少量行,否则我不确定这是否值得。 - timetofly
如果你使用MySQL,也许可以看一下http://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html。你有两种方式,一种是使用临时表,另一种则是使用内联模式。在这两个视图中,SQL都会被执行,但是在“MERGE”模式中,它将被“粘贴”到调用SQL中,而在“TEMPTABLE”模式中,则会创建一个临时表,并填充查询数据(以便释放锁定)。 - PhoneixS

3
如果您试图从中制作视图的表不经常更改,那么您肯定会获得更好的性能,因为您只需从已准备好的数据中进行简单选择。但是请注意,视图不是一次性制作的东西 - 每次更改其中一个表的内容都会使数据库引擎进行“视图刷新”,因此必须调用另一个查询(从中制作视图的查询)以考虑所做的更改。总之:

变化不频繁?提高性能。频繁/持续的更改(社区添加、评论、评分您的餐厅)-最好使用SQL查询。


0
缺点:
  • 个人认为数据库用于数据层,将业务代码放入其中并不适当。这会降低可维护性,违背了分层清晰的原则。同样的,将业务代码和计算逻辑放入网页的JavaScript中也是如此。对于JavaScript来说,情况更为严重,因为这会引发安全威胁。数据库内部代码的源代码控制也是另一个问题。

  • 现在代码已经在数据库内部,安全性和访问复杂性(针对视图和存储过程)也增加了。

  • 将应用程序从一个数据库引擎迁移到另一个数据库引擎将变得更加困难(因为除了简单查询外,存储过程/视图等可能也不同)。如果数据库只涉及数据,则抽象层可以允许更改数据库引擎(至少在某种程度上)。

优点:
  • 略微提高性能(由于数据不需要从数据库中出来进行处理,因此它直接在数据库内部进行处理)。

  • 代码看起来更干净(因为肮脏的部分被隐藏在数据库视图、存储过程等中)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接