Flink 能够改写成 FlinkSQL的理论依据:命令式代码 vs 声明式代码

x33g5p2x  于2021-12-30 转载在 Flink  
字(1.1k)|赞(0)|评价(0)|浏览(313)

当关系模型最初被引入时,就包含了查询数据的不同方法:SQL 是一种声明式查询语言,而 IMS 和 CODASYL 则是命令式。这种差别意味着什么呢?

命令式代码 vs 声明式代码

例如,我有一个动物物种的列表,想要查询列表中的鲨鱼:

1、命令式代码:

function getSharks() {
    var sharks = [];
    for (var i = 0; i < animals.length; i++) {
        if (animals[i].family === "Sharks") {
        	sharks.push(animals[i]);
        }
    }
    return sharks;
}

2、声明式代码:

SELECT * FROM animals WHERE family = 'Sharks';

命令式语言 告诉计算机以特定顺序执行某些操作,而对于 声明式的查询语言,则只需要指定所需的数据格式,结果需要满足什么条件,以及如何转换数据(例如,排序、分组和聚合),而不需要指明如何实现这一目标。

命令式代码 由于指定了特定的执行顺序,很难在多核和多台机器上并行化,声明式语言 则对于并行执行更为友好。

例如,对于 Web 浏览器来说,使用声明式 CSS 样式表比用 JavaScript 命令式地操作样式好得多。类似地,在数据库中,像 SQL 这样的声明式查询语言比命令式查询 APIs 要好得多。

MapReduce 查询

MapReduce 是一个相当底层的编程模型,用于在许多机器上批量处理海量数据。

MapReduce 既不是声明式查询语言, 也不是一个完全命令式的查询 API, 而是介于两者之间: 查询的逻辑用代码片段来表示, 这些代码片段可以被处理框架重复地调用。它主要基于许多函数式编程语言中的 map (也称为 collect) 和 reduce (也称为 fold 或inject) 函数。

map 和 reduce 函数对于可执行的操作有所限制。 它们必须是纯函数, 这意味着只能使用传递进去的数据作为输入, 而不能执行额外的数据库查询, 也不能有任何副作用。这些限制 使得数据库能够在任何位置、 以任意顺序来运行函数, 并在失败时重新运行这些函数。 不管怎样, 该功能非常强大, 可以通过它来解析字符串、 调用库函数、 执行计算等。
读者注:这些限制能够让代码在多台机器上并行执行,更贴近 SQL 这样的声明式查询语言。也正是因为这些限制,让 Flink 任务改写为 FlinkSQL 从理论上是可行的。

参考:《数据密集型应用系统设计》,Martin Kleppmann,P53

相关文章