当前位置:  开发笔记 > 编程语言 > 正文

为什么使用'*'构建视图不好?

如何解决《为什么使用'*'构建视图不好?》经验,为你挑选了5个好方法。

为什么使用'*'构建视图不好?

假设您有一个复杂的连接,并且可以在某处使用所有字段.

然后你只需要选择所需的字段.

SELECT field1, field2 FROM aview WHERE ...

视图"aview"可能是 SELECT table1.*, table2.* ... FROM table1 INNER JOIN table2 ...

如果table1和table2中的2个字段具有相同的名称,则会出现问题.

这只是为什么在视图中使用'*'不好的原因?

使用'*',您可以在不同的上下文中使用该视图,因为信息就在那里.

我错过了什么?

问候



1> Martin..:

我不认为软件中有太多"只是坏",但有很多东西被滥用的方式很糟糕:-)

你给出的例子是*为什么*可能不会给你你期望的东西,我认为还有其他的原因.例如,如果基础表发生更改,可能会添加或删除列,则使用*的视图将继续有效,但可能会破坏使用它的任何应用程序.如果您的视图已明确命名列,那么在进行架构更改时,有人会发现问题的可能性更大.

另一方面,您实际上可能希望您的视图轻松接受对基础表的所有更改,在这种情况下,*就是您想要的.

更新:我不知道OP是否有一个特定的数据库供应商,但现在很清楚,我的上一句话并不适用于所有类型.我非常感谢user12861和Jonny Leeds指出这一点,对不起,我花了6年时间来编辑我的答案.


最后的注释是完全错误的(至少在sql server中) - 相反的情况 - 对底层表的更改会被忽略.这是@ user12861提到的.在sql server中,任何使用select*的视图都需要删除并重新创建,当底层表更改时,否则它将默默地不显示所有列.这是一种非常糟糕的故障形式,因为它不太可能在您从头开始重建数据库的开发环境中被选中.添加列时,也很容易忘记删除并重建表上的所有视图

2> Anne Porosof..:

虽然这里的许多注释非常好,并且引用了在查询中使用通配符的一个常见问题,例如,如果基础表发生更改会导致错误或不同结果,另一个未涵盖的问题是优化.拉取表的每一列的查询往往不如仅提取实际需要的列的查询效率高.当然,有些时候你需要每一列而且它是一个主要的PIA必须全部引用它们,特别是在一个大表中,但是如果你只需要一个子集,为什么要用比你需要的更多的列来阻止你的查询.



3> Bill Karwin..:

" *"不仅在视图中而且在查询中存在风险的另一个原因是列可以更改名称或更改基础表中的位置.使用通配符意味着您的视图可以轻松容纳此类更改,而无需进行更改.但是,如果应用程序在结果集中按位置引用列,或者如果使用返回按列名称键入的结果集的动态语言,则可能会遇到难以调试的问题.

我总是避免使用通配符.这样,如果列更改名称,我立即在视图或查询中收到错误,并且我知道在哪里修复它.如果列更改基础表中的位置,则指定视图或查询中列的顺序将对此进行补偿.


请阅读我的其他答案,至少在SQL服务器上,并不总是反映基础表中的更改.

4> user12861..:

这些其他答案都有好处,但在SQL服务器上至少它们也有一些错误点.试试这个:

create table temp (i int, j int)
go
create view vtemp as select * from temp
go
insert temp select 1, 1
go
alter table temp add k int
go
insert temp select 1, 1, 1
go
select * from vtemp

添加时,SQL Server不会了解"新"列.根据你的需要,这可能是件好事还是坏事,但无论哪种方式,依赖它都可能并不好.所以避免它只是一个好主意.

对我来说,这种奇怪的行为是避免在视图中选择*的最有说服力的理由.

这些评论告诉我,MySQL有类似的行为而Oracle没有(它将了解对表的更改).这与我的不一致是更多的理由不在视图中使用select*.


Oracle不像这样工作.表更改将使视图无效,并在下一次访问时使用新列重新编译.
MySQL中的相同行为 - 新列不会成为视图的一部分.显然,在创建视图时,通配符将转换为列的列表.同时重命名基表中的列会使视图无法使用.

5> Dave..:

使用'*'进行任何生产都很糟糕.这对于一次性查询非常有用,但在生产代码中,您应始终尽可能明确.

特别是对于视图,如果基础表添加或删除了列,则视图将被错误或中断,直到重新编译为止.

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有