问题描述
嘿伙计们,
我有一个关于在SELECT语句中使用通配符的干净SQL代码/不良做法的问题。
在提供的示例中,我有一个基本查询,其中包含选择的大量列和两个 (或更多) 源,我需要通过UNION ALL合并。
因为我是一个懒惰的开发人员,也尝试遵循干原则 (不要重复自己),我认为这将是一个好主意,以封装我需要的信息在一个与子句的选择,并通过通配符引用它。在我看来,这也大大增强了SELECT语句的可读性。我什至认为提供3次列的具体列表会增加错误的可能性。
问题1: 你会认为这种方法是糟糕的做法,还是实际的可靠的方法,以实现更易读和干净的SQL语句?
我现在想将我的查询保存为视图,以便易于访问 (并且可重用)。当我这样做时,我注意到Oracle会将我的通配符查询转换为编译时的静态列表,这导致我突然在我的脚本文件 (版本控制) 和我的实际数据库之间存在差异的情况。在进行代码覆盖或其他分析/比较时,这可能会导致问题。
问题2: Oracle在内部更改视图的原始实现的原因是什么?
问题3: 当我们可以在交换中实现更具可读性和更容易出错的代码时,您会认为不同的sourcefiles/数据库源是次要问题吗?你对一般话题有什么看法?
期待您的意见!
干杯,
山姆
我有一个关于在SELECT语句中使用通配符的干净SQL代码/不良做法的问题。
在提供的示例中,我有一个基本查询,其中包含选择的大量列和两个 (或更多) 源,我需要通过UNION ALL合并。
因为我是一个懒惰的开发人员,也尝试遵循干原则 (不要重复自己),我认为这将是一个好主意,以封装我需要的信息在一个与子句的选择,并通过通配符引用它。在我看来,这也大大增强了SELECT语句的可读性。我什至认为提供3次列的具体列表会增加错误的可能性。
问题1: 你会认为这种方法是糟糕的做法,还是实际的可靠的方法,以实现更易读和干净的SQL语句?
我现在想将我的查询保存为视图,以便易于访问 (并且可重用)。当我这样做时,我注意到Oracle会将我的通配符查询转换为编译时的静态列表,这导致我突然在我的脚本文件 (版本控制) 和我的实际数据库之间存在差异的情况。在进行代码覆盖或其他分析/比较时,这可能会导致问题。
问题2: Oracle在内部更改视图的原始实现的原因是什么?
问题3: 当我们可以在交换中实现更具可读性和更容易出错的代码时,您会认为不同的sourcefiles/数据库源是次要问题吗?你对一般话题有什么看法?
期待您的意见!
干杯,
山姆
专家解答
在回答您的问题之前,让我们回顾一下:
为什么select * 不好?
-您 (可能) 选择的列比您需要的更多。这意味着通过网络传输更多的数据,并且使用仅索引扫描或其他次优执行计划的可能性较小。
-如果您的代码使用select * 将数据返回到固定的变量列表中,则添加或删除任何列都会导致此中断。因此,每次更改表的列时,都需要更新这些语句。如果您不需要以所有列开头或添加新列,这将增加您的工作,而不会带来任何好处。
现在在您的查询中:
Presumably,您已经从person_description中选择了您想要的内容。而且,当您更改此选项时,无论如何都在编辑查询,因此可以查看是否仍然需要select *。所以是的,你可以争辩说,在这种情况下,没关系。确保您清楚执行此操作的原因!
A1. 每个人都有自己的宠物偏好,以使SQL “更具可读性”。所以我要说的是:
保持一致。
确保您在整个应用程序中坚持使用格式样式。
A2.创建视图时,数据库需要更新数据字典以存储有关它的信息。这包括列、它们的数据类型等。
如果您将视图保留为select *,那么当您运行许多alter table命令时,您也必须重建视图。如果这是一个广泛使用的核心视图,这可能会触发重建大量数据字典!通过使列明确,您可以限制直接受影响的内容。
A3. 源代码和数据库代码之间的任何差异都成为您需要检查的东西。请记住,是的,在这种情况下,它们不匹配的事实是可以接受的。你创建的这些例外越多,你就越需要彻底地记录你的决定。发现真正的差异就越困难。这也使新开发人员加入该项目变得更加困难。
而且,如果由于某种原因,dev/test/prod数据库中的表具有不同的列,则使用select *,您的视图将可以正常编译。但是,如果缺少命名列,您将立即收到异常。如果这打破了一个版本,它使根本原因分析更容易!
因此,在我看来,您需要在视图中使用select * 而不是命名列有很大的好处。就我个人而言,我认为这里的好处充其量是很小的。但见a1;)
为什么select * 不好?
-您 (可能) 选择的列比您需要的更多。这意味着通过网络传输更多的数据,并且使用仅索引扫描或其他次优执行计划的可能性较小。
-如果您的代码使用select * 将数据返回到固定的变量列表中,则添加或删除任何列都会导致此中断。因此,每次更改表的列时,都需要更新这些语句。如果您不需要以所有列开头或添加新列,这将增加您的工作,而不会带来任何好处。
现在在您的查询中:
with info as (
select id description_id,
prename,
name,
some,
other,
information
from person_description
)
select j.id, j.title, i.*
from jedi j
inner join info i
on j.fk_description = i.description_id
union all
select s.id, s.title, i.*
from sith s
inner join info i
on s.fk_description = i.description_id;Presumably,您已经从person_description中选择了您想要的内容。而且,当您更改此选项时,无论如何都在编辑查询,因此可以查看是否仍然需要select *。所以是的,你可以争辩说,在这种情况下,没关系。确保您清楚执行此操作的原因!
A1. 每个人都有自己的宠物偏好,以使SQL “更具可读性”。所以我要说的是:
保持一致。
确保您在整个应用程序中坚持使用格式样式。
A2.创建视图时,数据库需要更新数据字典以存储有关它的信息。这包括列、它们的数据类型等。
如果您将视图保留为select *,那么当您运行许多alter table命令时,您也必须重建视图。如果这是一个广泛使用的核心视图,这可能会触发重建大量数据字典!通过使列明确,您可以限制直接受影响的内容。
A3. 源代码和数据库代码之间的任何差异都成为您需要检查的东西。请记住,是的,在这种情况下,它们不匹配的事实是可以接受的。你创建的这些例外越多,你就越需要彻底地记录你的决定。发现真正的差异就越困难。这也使新开发人员加入该项目变得更加困难。
而且,如果由于某种原因,dev/test/prod数据库中的表具有不同的列,则使用select *,您的视图将可以正常编译。但是,如果缺少命名列,您将立即收到异常。如果这打破了一个版本,它使根本原因分析更容易!
因此,在我看来,您需要在视图中使用select * 而不是命名列有很大的好处。就我个人而言,我认为这里的好处充其量是很小的。但见a1;)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




