即使只是语法糖,模块化SQL

时间:2013-02-04 18:20:03

标签: sql abstraction

有没有办法模块化SQL代码,以便更具可读性和可测试性?

我的SQL代码经常变成一系列复杂的嵌套连接,内部连接等,难以编写且难以调试。相比之下,在诸如Javascript或Java之类的过程语言中,人们会将离散元素作为单独的函数来捏合,这些函数将按名称调用。

是的,可以将每个查询写成完全独立的查询,存储在数据库中或作为存储过程,但通常我不想更改/混乱数据库,只是查询它很好,特别是如果DBA没有'我希望向所有用户授予写入权限。

例如,从概念上讲,复杂查询可能很容易用伪代码描述:

(getCustomerProfile) 
left join 
(getSummarizedCustomerTransactionHistory) 
using (customerId) 
left join
(getGeographicalSummaries) 
using (region, vendor)
...

我意识到从理论上看有很多主题(下面的几个链接),但我只是想找到一种方法来使代码更容易正确编写,并且一旦编写就更容易阅读。也许只是语法糖来从视觉中抽象出复杂性,如果不是从执行中,那么在我试图不看的文字SQL中编译。通过类比......

  • 手写笔:CSS ::
  • CoffeeScript :Javascript ::
  • SAS宏语言:SAS语言::
  • :SQL

如果特定的SQL风格很重要,我的大部分工作都在PostgresQL中。

http://lambda-the-ultimate.org/node/2440

Code reuse and modularity in SQL

Are Databases and Functional Programming at odds?

2 个答案:

答案 0 :(得分:5)

在大多数数据库中,您可以使用CTE(公用表表达式)执行您想要的操作:

with CustomerProfile as (
      getCustomerProfile
     ),
     SummarizedCustomerTransactionHistory as (
      getSummarizedCustomerTransactionHistory
     ),
     GeographicalSummaries as (
      getGeographicalSummaries
     )
select <whatever>

这适用于单个查询。它的优点是您可以定义一次CTE,但多次使用它。另外,我经常定义一个名为const的CTE,它具有常量值。

下一步是采用这些结构并从中创建视图。在多个模块之间共享代码时,这尤其有用,以确保定义不变。在某些数据库中,您可以在视图上放置索引以“实例化”它们,从而进一步优化处理。

最后,我建议在存储过程中包装插入/更新/删除。这使您可以拥有一致的框架。

但还有两条评论。首先,SQL通常用于事务或报告系统。通常,一旦您为此目的获得了正确格式的数据,数据就会说明问题。您的示例可能只是要求一个数据集市,其中有三个表专门用于这三个主题区域,每周填充一次或每天填充一次。

并且,SQL不是抽象的思想语言。通过良好实践,命名约定和缩进样式,您可以使其有用。我非常想念“真正的”语言中的某些东西,例如宏,错误处理(为什么数据错误很难识别和处理超出我的范围),常见功能的一致方法(有人可以说组字符串连接),以及其他一些特征。也就是说,因为它以数据为中心且易于并行化,所以对我来说比大多数其他语言更有用。

答案 1 :(得分:1)

这里的问题是你需要以关系的方式思考数据。我不相信这种类型的抽象正确地适合关系模型。在使SQL模块化方面,这就是存储过程和/或函数的用途。请注意它们与Java中的方法具有相同的特征。你可以这样抽象出来。另一种方法是将您关心的数据抽象为物化视图。通过这样做,您可以在这些物化视图的顶部放置一个常规视图(请参阅虚函数),这样您就可以在不触及“原始”表的情况下测试数据结构。