这里的示例显示了我在MySQL中构建的{em>非常简化版本的VIEW
。这里的目标是创建一个视图,我可以从中选择要将一组结果填充到HTML表中。
我使用视图的目的部分是将此数据的计算显示为视图中的列。我可以通过为表达式提供别名来轻松完成此操作,例如:SELECT a, b, a + b AS c
将为我提供一个包含三列的结果集,其中c
列中的值是列{{1}中的值的添加}和a
这就是我目前正在构建一个虚构的“产品库存”表格的视图:
b
能够同时显示库存缺口和更换表中的库存成本对我来说非常重要。您可以看到这没有完全优化,因为再次使用库存短缺计算的一部分来计算成本。
这也意味着,如果计算出股票短缺的计算方式发生变化,则需要对股票短缺成本进行相同的变更,从而增加维护代码的难度。
我可以创建一个这样的SELECT语句,这将允许我使用用户变量引用过去的表达式:
SELECT
description,
unit_cost,
current_stock,
required_stock,
(required_stock - current_stock) AS stock_shortfall,
(required_stock - current_stock) * unit_cost AS stock_shortfall_cost
FROM product_stock
通过在进一步的计算中引用表达式的别名,我也可以通过对派生表使用子查询来实现类似的效果。
不幸,MySQL不允许我在SELECT
description,
unit_cost,
current_stock,
required_stock,
@stock_shortfall := (required_stock - current_stock) AS stock_shortfall,
@stock_shortfall * unit_cost AS stock_shortfall_cost
FROM product_stock
内使用用户变量或派生表子查询。< / p>
另一种解决方案可能是创建一个视图来代替派生表,并为每个重用的表达式创建另一个视图“图层”以从中选择派生值。这有效,但经过这么多层次之后,它也变得无法维护。
我目前正在执行“分层”视图和重复计算的混合,如示例#1中所示。请理解,我希望构建的实际VIEW
是8个表中的VIEW
,其中包含大量计算值,可在整个表达式中重复使用。它不太可管理。
感谢您阅读我的文字墙。以下是我的问题:
是否可以使用与示例#2类似的方式使用派生表达式创建JOIN
?
如果没有,你会如何解决这个问题?
最佳解决方案是什么?我应该使用服务器端脚本来计算值而不是使用数据库吗?是否有其他数据库技术支持此功能?你会做什么?
答案 0 :(得分:3)
最后,我写了SELECT
语句,类似于我在第二个例子(理想的解决方案)中编写的语句,它不能用于构造VIEW
。
然后我写了一个小编译器来从该语句创建一个更复杂的查询,可用于构造VIEW
。
现在维护起来要容易得多。
感谢Rob Van Dam鼓励我编译查询。
答案 1 :(得分:1)
这些查询的客户端是什么?如果您使用的是任何编程语言(而不是瘦Web客户端),那么您可以使用该语言构建查询(perl / php示例):
$stock_shortfall = "(required_stock - current_stock)";
$query = "SELECT
description,
unit_cost,
current_stock,
required_stock,
$stock_shortfall AS stock_shortfall,
$stock_shortfall * unit_cost AS stock_shortfall_cost
FROM product_stock"
如果您可能需要经常重复使用此查询,那么您可以围绕它构建一个类,或者至少有一个生成查询字符串的静态库类。
答案 2 :(得分:0)
我们基本上在做同样的工作 - &gt;除了BLOBS,意味着每个派生/临时表都自动写入磁盘。
这是绝对的性能杀手。
此外,MySQL 5.0(我们正在使用的)不支持索引VIEW,因此每次查询完成时都需要全表扫描才能获取1个结果!
然而,有希望。
我从未使用过这个功能,但PostgreSQL支持物化视图。因此,我的理解是,当你计算所有讨厌的子查询时,它会将计算结果保存在VIEW中,直到其中一个底层字段发生变化(告诉我这里是不是错了,Postgres devs / DBAs)。
此外,我们无法更改为Postgres,因此我们制作了一个cron文件,仅每5分钟构建一次VIEW并存储一个静态计算版本,从而使性能更好。我认为基准测试好10倍。但是,这取决于您是否愿意暂时使用陈旧数据......
答案 3 :(得分:0)
使用FUNCTION可能会利用可维护性......并且希望(在不久的将来)它也可以提升性能。
SELECT
...
stock_shortfall(required_stock, current_stock),
stock_shortfall_cost(required_stock, current_stock, unit_cost)
...
这两个函数应标记为DETERMINISTIC
。在MySql 5.0中,优化器未使用该特性。我不知道以后的版本是否已经使用它(所以“不久的将来”参考)。
当然,简单的单次使用计算很少值得CREATE FUNCTION...
打字开销。