【发布时间】:2009-07-20 12:52:05
【问题描述】:
为什么是或为什么不?
【问题讨论】:
标签: sql functional-programming
为什么是或为什么不?
【问题讨论】:
标签: sql functional-programming
不,SQL 不是函数式语言。范式有些不同。请注意,除了函数式编程语言之外,还有其他类型的声明式编程语言——典型的例子是逻辑编程和 PROLOG。
从技术上讲,关系代数(SQL 的理论基础)实际上并不完整。尽管现代 SQL 方言添加了足够的过程特性,因此可以实现存储过程并在此级别图灵完备,但单个 SQL 查询并不是图灵完备的计算。关系代数具有哥德尔完备性。哥德尔完备性意味着表达任何可以用一阶谓词演算定义的计算的能力——基本上就是你所知道的普通逻辑表达式。
【讨论】:
函数是 SQL 中的一等对象吗?几乎不。所以我会说不。
【讨论】:
Select(columns/expressions);
对于什么是函数式语言(或者就此而言,什么是过程式或面向对象的语言)没有一个真正的定义。
但我真的想不出太多指向 SQL 功能的东西。 它没有函数,没有递归,没有闭包,没有嵌套函数,没有作为一等类型的函数。
一个更常见的问题是 SQL 到底是不是一种编程语言。它不是图灵完备的。
【讨论】:
SQL 被设计为一种声明性语言,从某种意义上说,您告诉what 您想要获取,而SQL 引擎决定how。
但是,SQL 对集合进行操作,函数的结果可以是Oracle、SQL Server 和PostgreSQL 中的第一类集合。
可以说SQL 是函数式语言,只要一个函数将一个集合作为其输入并产生一个集合作为其输出。
也就是说,你可以这样写:
SELECT *
FROM mytable t
JOIN myfunction(x) f
ON f.col1 = t.col2
,甚至这个:
SELECT *
FROM mytable t
CROSS APPLY
myfunction(t.col2) f
(在SQL Server)
或者这个:
SELECT t.*, myfunction(t.col2)
FROM mytable t
(在PostgreSQL)
不过,这不是 SQL 标准的一部分。
就像C++ 编译器试图找到将两个 floats 相乘的最佳方法(就普通代数而言),SQL 优化器试图找到将两个集合相乘的最佳方法(就关系而言代数)。
在C++ 中,您只需编写a * b 并依靠编译器为此生成最佳程序集。
在SQL 中,您编写SELECT * FROM a NATURAL JOIN b 并依赖优化器。
然而,由于所有SQL 声明的声明性(没有双关语),大多数真正的优化器只能进行非常基本的查询重写。
比如说,我所知道的任何优化器都无法对这个查询使用同样有效的计划:
SELECT t1.id, t1.value, SUM(t2.value)
FROM mytable t1
JOIN mytable t2
ON t2.id <= t1.id
GROUP BY
t1.id, t1.value
对于这个:
SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
FROM mytable
,更不用说更复杂的查询了。
这就是为什么您仍然需要制定查询,以便它们使用有效的计划(同时仍然产生相同的结果),从而使 SQL 少一点声明性语言。
我最近在我的博客上发了帖子:
【讨论】:
functionA(x) CROSS APPLY functionB(functionA.col1)?
一般来说,如果没有语法扩展(例如 PL/SQL、T-SQL),就不能编写函数。
但它肯定是非常面向表达式的,这是它与函数式语言的共同特点。
【讨论】:
声明性和功能性?那将是一个电子表格。
【讨论】:
我认为 SQL 和函数式语言彼此非常不同。在函数式语言中,计算是通过评估函数来完成的。函数不会改变状态。他们所做的只是根据他们的论点计算一个值。换句话说,函数不会引起副作用。函数式语言是通用的。
SQL 是一种设计用于处理关系数据库管理系统的语言。它可以被视为一种特定领域的语言。它旨在处理“数据集”。它可以通过使用诸如 UPDATE 之类的命令来改变全局状态(即数据库)。没有函数被评估为一个值的概念。据我了解,SQL 甚至都不是图灵完备的。
【讨论】:
既然函数式语言的意义在于您使用函数进行编程,我会说不。 SQL 正在使用关系进行编程(如果您甚至可以将 SQL 称为编程语言 - 在它的基本形式中,SQL 不是图灵完备的)。
【讨论】:
从某种意义上说:是的,SQL 是功能性的。 看看
SELECT 为 map(),WHERE 为filter(),ORDER BY 为sort(),DISTINCT 为 set()
等等
【讨论】: