Sql >

Sql >,sql,Sql,如果您必须执行一些操作来挑选与某些复杂条件匹配的记录,并对它们执行一些操作,那么最好将其作为存储过程实现。对于一些可能需要检查相当大的数据库的重要部分的东西,基于存储过程的方法可能是完成这类事情的唯一合理的方法 在这种情况下,SQL很可能是实现这一点的合适方法,尽管传统的3GLs(特别是COBOL)是专门为这种类型的处理而设计的。在真正的高容量环境(尤其是大型机)中,使用数据库外的平面文件或VSAM文件进行此类处理可能是最快的方法。此外,某些作业可能天生就面向记录和程序,或者如果以这种方式实施,

如果您必须执行一些操作来挑选与某些复杂条件匹配的记录,并对它们执行一些操作,那么最好将其作为存储过程实现。对于一些可能需要检查相当大的数据库的重要部分的东西,基于存储过程的方法可能是完成这类事情的唯一合理的方法

在这种情况下,SQL很可能是实现这一点的合适方法,尽管传统的3GLs(特别是COBOL)是专门为这种类型的处理而设计的。在真正的高容量环境(尤其是大型机)中,使用数据库外的平面文件或VSAM文件进行此类处理可能是最快的方法。此外,某些作业可能天生就面向记录和程序,或者如果以这种方式实施,则可能更加透明和可维护

“您可以用任何语言编写COBOL”——尽管您可能不想这样做。如果您想将其保存在数据库中,可以使用SQL,但这肯定不是唯一的游戏

报告

报告工具的性质往往决定了对业务逻辑进行编码的方法。大多数设计用于基于SQL的数据源,因此该工具的性质迫使您做出选择

其他域

一些应用程序(如ETL处理)可能非常适合SQL。如果转换变得太复杂,ETL工具开始变得不明智,因此您可能希望采用基于存储过程的体系结构。跨提取、ETL处理和基于存储过程的处理混合查询和转换可能导致转换过程难以测试和排除故障


如果存储过程中有很大一部分逻辑,那么最好将所有逻辑都放在存储过程中,因为它提供了一个相对同质和模块化的代码库。事实上,我有相当好的权威性,银行和保险行业中大约一半的数据仓库项目都是以这种方式作为明确的设计决策来完成的——正是出于这个原因。

答案取决于您的专业知识和对所涉及技术的熟悉程度。此外,如果您是一名技术经理,这取决于您对团队成员技能的分析,以及您打算雇佣/留住哪些员工来支持、扩展和维护未来的应用程序。
如果您不识字,也不精通数据库,那么请坚持使用代码。如果你精通数据库编码(这是你应该具备的),那么在数据库中进行编码并没有什么错(而且很多是对的)


可能影响您的决策的另外两个考虑因素是,逻辑是否具有如此复杂的性质,以至于在数据库代码中执行逻辑比在代码中执行逻辑要复杂得多或更抽象;第二,如果所涉及的过程需要来自数据库外的数据(来自其他来源)在这两种情况下,我都会考虑将逻辑移动到代码模块。 将逻辑推送到数据库的最有说服力的原因之一是将流量降至最低。在给出的示例中,没有什么好处,因为无论逻辑是在查询中还是在应用程序中,您都会获取相同数量的数据


如果您只想获取名为
Michael
的用户,那么在服务器上实现该逻辑更有意义。实际上,在这个简单的示例中,这没有多大区别,因为您可以指定姓为
Baldwin
的用户。但是考虑一个更有趣的问题,你给每个用户一个“流行”的分数,根据他们的名字和姓氏的共同点,你想获取10个最受欢迎的用户。计算应用程序中的“受欢迎度”意味着,在本地对每个用户进行排名、排序和选择之前,你必须获取每个用户。在服务器上计算它意味着您只需跨线路获取10行。

事实上,您可以更轻松地在IDE中单步执行代码,这是您的后处理解决方案的唯一优势。在数据库服务器中执行逻辑可以减少结果集的大小,这通常会大大减少网络流量。它还允许查询优化器更好地了解您真正想要做的事情,通常也允许更好的性能


因此,我几乎总是推荐SQL逻辑。如果你把一个数据库仅仅当作一个愚蠢的存储,它会表现出愚蠢的行为来报答你的好感,这取决于具体情况,这绝对会扼杀你的性能——如果不是今天,可能是明年事情发展起来的时候……

我强烈主张将尽可能多的逻辑直接放入数据库中。这意味着将其合并到视图和存储过程中。我相信大多数都遵循干燥原则

例如,考虑使用FieldNeX和LaSTNEX列的表,以及经常使用FulnNeX字段的应用程序。你有三个选择:

  • 查询名字和姓氏,并计算应用程序代码中的全名

  • 每当查询表时,在应用程序的SQL中查询first、last和(first | | last)

  • 定义包含第一列和最后一列以及计算全名列的视图CustomerText,然后针对该视图而不是customer表进行查询

  • 我认为选择3显然是正确的。考虑将一个中间初始字段添加到表和全名计算中。使用选项3,您只需替换视图,整个公司的每个应用程序都会立即使用新的全名格式。对于那些需要进行一些特殊格式设置的实例,视图仍然可以使用基列,但对于标准实例,所有操作都是“自动”进行的

    这是一个简单的情况,但对于更复杂的情况,原则是相同的。每
    SELECT
        P.LastName, IF(P.LastName='Baldwin','Michael','Bruce') AS FirstName
    FROM
        University.PhilosophyProfessors P
    // This is like a ternary operator; if the condition is true, it returns 
    // the first value; else the second value. So if a professor's last name 
    // is 'Baldwin', we will get their first name as "Michael"; otherwise, "Bruce"**
    
    SELECT P.LastName, 'Michael' AS FirstName
        FROM University.PhilosophyProfessors P
        WHERE P.LastName = 'Baldwin'
    UNION ALL SELECT P.LastName, 'Bruce' AS FirstName
        FROM University.PhilosophyProfessors P
        WHERE P.LastName <> 'Baldwin'