【问题标题】:Is it safe to use select * in views?在视图中使用 select * 是否安全?
【发布时间】:2013-06-27 09:08:40
【问题描述】:

我越来越喜欢CREATE VIEW 的用处。例如,它允许我通过COALESCE(post.publish, profile.publish) 获得全局值和特定值,这样如果publishNULL,则取而代之的是全局值。

从性能和逻辑的角度来看,我有点好奇的部分是,我应该如何将它与现有表一起使用。假设我有一张桌子:

CREATE TABLE post (
    id INT,
    profile_id INT,
    name VARCHAR,
    publish ENUM('TRUE', 'FALSE') NULL
)

CREATE VIEW 最好像这样运行:

CREATE VIEW post_info AS
SELECT post.*, COALESCE(post.publish, profile.publish) AS publish
FROM post
INNER JOIN profile
ON post.profile_id = profile.id

并且仅在 SELECT 情况下使用 post_info,或者:

CREATE VIEW post_info AS
SELECT post.id, COALESCE(post.publish, profile.publish) AS publish
FROM post
INNER JOIN profile
ON post.profile_id = profile.id

当需要额外的值时,JOIN post_infopostSELECT 中?

请分享您对此的见解和想法。我想听听您对每种解决方案的优缺点的意见。也可以是我没有提到的。

【问题讨论】:

  • SELECT * 永远不会好。
  • 我知道我通常喜欢避开*。但是我觉得这是一个特殊情况,您可以用更多列来完成表格。
  • publish ENUM('TRUE', 'FALSE') NULL?!哎呀!为什么不publish BOOLEAN NULL
  • 我发现更好地了解我的表格比在更多列中包含大量整数更容易。也许不是最好的理由,但只是习惯了。

标签: mysql database-design


【解决方案1】:

这实际上取决于您将如何使用视图。值得一提的是,MySQL 可以处理引用视图的查询有两种方法,使用的方法取决于视图声明的ALGORITHM 子句。

由于缺乏更好的措辞,我将复制the manual

对于[ALGORITHM =] MERGE,引用视图的语句文本和 视图定义被合并,使得部分视图定义 替换语句的相应部分。

对于TEMPTABLE,视图的结果被检索到一个 临时表,然后用于执行语句。

对于UNDEFINED,MySQL 选择使用哪种算法。

MERGE 算法通常允许更快地处理最终查询,但是在许多情况下 MySQL 无法使用它(有关详细信息,请参阅链接的手册页)。

所以答案是:如果您的视图没有使用ALGORITHM = TEMPTABLE 定义 如果包装查询不阻止使用MERGE 算法,则使用SELECT * 的版本,以及没有额外的JOIN,更好。

否则,如果不使用MERGE,则第二种方案可能会更好。

作为旁注,为了解决您提到的用例,更好的选择是让您的应用程序层在插入时用profile.publish 中的值填充post.publish,并去掉JOIN以及视图。或者,可以通过在桌子上放置一个合适的触发器来实现相同的效果。

【讨论】:

  • 如果我希望全局值即使在帖子创建后也能影响它,那么填写该值对我来说并不理想。我需要在我认为的ALGORITHMs 上变得更聪明。
  • 如果你添加一个类似“isDefaultValue BOOLEAN”的列,你会得到更好的结果。然后你可以UPDATE post SET publish = whatever_id WHERE isDefaultValue。它使更新时间更长,但检索更快,我想全球value 的 changedread 少。此外,这是应用程序层(业务规则)的一个问题,而不是数据库应该担心的问题。但我不再是现在迂腐了:)
猜你喜欢
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 2012-10-09
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多