【问题标题】:Comparing SQL and Prolog比较 SQL 和 Prolog
【发布时间】:2010-01-22 13:57:35
【问题描述】:

我开始学习 Prolog 并想知道与 SQL 语言的理论差异。

例如:

  • 都是声明性语言
  • 两者都支持事实驱动的知识数据库
  • 两者都支持问题式数据检索
  • 两者都支持函数依赖

还有什么共同点吗?有什么明显的区别吗?

【问题讨论】:

标签: sql prolog


【解决方案1】:

您是对的:Prolog 和 SQL 在理论上是相关的(您专门询问了理论差异)。

我想补充RBarryYoung's answer,给你一些理解连接的提示,让你有一个学习和理解技术的起点。

Prolog 和 SQL 共享一个核心:可以在 Prolog 子集中表达的每个查询都可以在 SQL 子集中表达,反之亦然,即这些子集在逻辑上是等价的。

要了解这是如何实现的,您需要检查 Prolog 和 SQL 的理论基础:

当然,这些子集中的某些内容需要更多的翻译工作。

尽管如此,在考虑 Prolog 到 SQL 的翻译时,我认为这两个子集的表达能力等价的说法不仅仅是对 Turing equivalence4 的吸引力.

注意事项:

1) 不幸的是,SQL 可用于与 RDBMS 理论基础(关系代数-演算)相反;例如,SQL tables are not necessarily relations - 根据 RA - 即它们可以没有(主)键,因此允许重复行。这样的表不是集合,而是 multisets (aka bags) 的元组。在这种情况下,关系是集合的 RA 的所有理论结果都不一定有效。

2) 有关从 SQL 到 TRC 的转换,请参阅A note on the translation of SQL to tuple calculus,另请参阅here (postscript paper)

3) 有关 Datalog 和 Prolog 之间差异的更多信息,请参阅 What You Always Wanted to Know About Datalog (And Never Dared to Ask)(pdf 论文 - 直接链接到第 6 页,标题 H. Datalog 和 Prolog)。

4) 作为记录:RA(以及它们的等价物 safe TRC 和 safe Datalog w/o recursion)故意不是图灵完备的,以避免永无止境查询。

历史记录: Prolog 和 Codd 的关系代数是在大约同一时间(60 年代末 70 年代初)在不同的上下文中构思的 - Colmerauer 构思了用于自然语言处理的 Prolog,而 Codd 将 RA 构思为关系型数据库管理系统的理论基础。因此,Prolog-Datalog-RA-SQL 之间的任何理论联系都必须后验建立,并且隐含在它们都基于一阶谓词演算这一事实(又名first order logic)。

【讨论】:

【解决方案2】:

Prolog 和 SQL 都基于一阶逻辑,但 SQL 表是简单的二元关系,而 Prolog 谓词是 Horn 子句。

这不是一些晦涩的理论观点。 SQL 二元关系是事实陈述,形式为:

f(A, B, C ... N)

其中f 是关系的名称,A...N 是它的变量。 Prolog 二元关系是含义,形式为:

A

其中 A ... N 本身就是 Horn 子句。 SQL 关系是描述数据的一种有效方式。 Prolog 关系描述了数据之间的复杂关系,数据本身存储为数据。

重要的是要了解在 Prolog 中,数据和操作之间没有分离。 Prolog 事实、规则和查询都是 Horn 子句,因此是数据,在大多数大学课程的翻译中都会丢失。 Prolog 与 C 不同,但使用事实而不是变量和规则而不是函数。另一方面,SQL 很像 Prolog,没有规则或查询。

SQL 查询也是逻辑谓词,但 SQL 查询并不存储在数据库本身中。相反,它们用于从事实数据库中提取数据集。您可以将查询作为表行存储在 SQL 数据库中,但不能以该形式执行。

Prolog 查询与任何其他 Prolog 谓词一样存储在数据库中,因为它们与任何其他 Prolog 谓词一样。查询是以下形式的 Horn 子句:

所以有先例但没有先例的含义,因此总是错误的。 Facts 是带先行词但没有先例的 Horn 子句,形式为:

一个

总是如此。 Prolog 通过反驳来证明一个查询:如果它找不到证明它的事实(或规则),它将声明目标为真,因为查询总是错误的。在此过程中,绑定了一些变量,因此可以构造结果集,就像 SQL 对 SELECT 查询所做的那样。

现代 SQL DBMS 具有存储过程和流控制语言等功能,因此 SQL 可用于推理(不是您想要在 SQL 中进行推理)。 Prolog 配备了一个针对其 Horn 子句数据库调整的推理引擎,因为这是对表示为二进制关系的事实数据库进行推理的一种有效方法(不,不仅仅是因为它很漂亮)。

Prolog 的同义性(数据就是操作就是数据)意味着必须将新的新数据添加到数据库中,因此必须添加到程序中,因为数据库就是程序。因此,每次将新事实添加到其数据库(通常使用 assert/1)时,都必须反编译整个程序。这是一个巨大的 PITA,使 Prolog 在存储大型数据集时效率低下,尽管没有理由说明它在数据检索方面效率低下检索,并且 Prolog 系统将为此目的使用与 SQL 系统相同的算法.另一方面,SQL 非常适合存储和检索。

最后,Prolog 有一些 SQL 所没有的特性,即它的超级模式匹配(称为统一)、否定作为失败以及有助于列表处理和语法声明的语法元素(定句语法表示法)。这些只是一个快乐的意外,并且大部分被添加到语言中,因为它们在它最初创建的时候很流行(感谢 LISP)。 SQL 相对最近才获得递归查询,所以 Prolog 不能再吹嘘了。

当然,这两种语言在 I/O 和数学方面都很薄弱,尽管至少您可以在 Prolog 中进行一些算术运算,而不必一路费尽心思。

所以,实际上,Prolog 和 SQL 与 C 和 Haskell 非常相似。它们都基于相同的根抽象,一阶逻辑(如 C 和 Haskell 都基于代数),但在那之后事情很快就变得非常不同。此外,从语言设计的角度来看,SQL 往往是支离破碎的,具有许多不同的语言特性(词条、查询、数据操作语言......)。 Prolog 的设计极其一致,以至于整个语言真的只是谓词和几个标点符号。

对我来说,最重要的区别是:我不喜欢 SQL,但我必须使用它。我喜欢 Prolog,但我不能在工作中使用它。生活是不公平的:)

【讨论】:

  • 该死的解释!! :)
  • f(A, B, C ... N) binaryN-ary 怎么样?
  • f/n 的参数列表是一个元组。您可以将参数视为嵌套树:(A(B(C...)N))。所以在 f(A, B,C,... N) 中,第一个参数通过关系 f 与后续参数的元组相关。所以 f 是两件事之间的关系,即使第二件事中有不止一件事:)
【解决方案3】:

这里的大多数(较早的)答案都反映了这样一个事实,即大多数人不知道 SQL 是什么(它是关系演算的实现)或它的含义(它是谓词逻辑的一种形式)。以下陈述对 Prolog 和 SQL 都适用:

  • 它们都是逻辑驱动的
  • 它们可以存储、表达和使用关系(Prolog 中的逻辑关系)
  • 它们可以存储和表达复杂的逻辑条件
  • 它们都有事实(SQL 中的数据)并且可以从这些事实中得出结论
  • 他们都有查询,实际上意思相同
  • 它们都有数据(Prolog 中的事实)并以类似方式使用它们
  • 它们都是编程语言
  • 它们都是图灵完备的(尽管在它们中都很难访问)
  • 等等等等。

一般来说,人们并不知道它们之间的这些等价关系:

  1. “事实”和“数据”是一回事。这直接来自 Codd 的原始论文。
  2. 关系理论中的“关系”与 SQL 中的“表”相同,与谓词逻辑中的关系或关系函数相同,与集合论中的元组集相同李>
  3. SQL 中的别名表表达式(即视图等)与 Prolog 中的规则相同。

那么它们的区别是什么?尽管它们在相同的概念领域中运作,但它们的关注点却完全不同。在 Prolog 术语中,SQL 主要是事实和关系(集合)引擎,而 Prolog 主要是规则和推理引擎。每个人都可以在有限的范围内做其他事情,但随着复杂性的小幅增加,它变得越来越困难。例如,您可以在 SQL 中进行推理,但它几乎完全是手动的,根本不像 Prolog 的自动前向推理。是的,您可以在 Prolog 中存储数据(事实),但它根本不是为 SQL 所设计的“存储、检索、投影和减少数以千计的同时用户的数万亿行”。

另外,SQL 主要是一种服务器语言范例,而 Prolog 主要是一种客户端语言范例。

【讨论】:

  • @MaD70: 怎么样,既然我可以用C++(或者我在学校做的C)实现Prolog,那么所有这些点也可以说是关于C++;但是,出于比较语言的目的,以及当您使用其中一种或另一种时,它们的主要功能是什么,它是没有用的。 @RBarryYoung 甚至说“每个人都可以在有限的范围内做另一个,但它变得越来越困难......”这清楚地表明语言在根本上是不同的,并且是为不同的任务而设计的。寻找技术上的相似之处没有用,也无助于 OP 和质疑。
  • @MaD70(续):这个答案基本上是数学上的帽子戏法。虽然聪明又聪明,但它并没有从设计的角度解释这两种语言的不同之处。
  • Hogan:是的,我的最后(完整)段落基本上是我对问题的回答,前面的点列表(和编号点)实际上是对这里其他陈述的回应:也就是说,这些项目不是区分两者的有用方法。最后,我基本上同意你的答案和你的 cmets,尽管我可能在我们答案的具体性、范围和措辞方面有所不同。
  • ALL:一般来说,我认为对于“这两种语言之间有什么区别”之类的问题,对于不熟悉这两种语言的人来说,给出一个有用的答案实际上是非常困难的,而且大多数回答往往会犯以下错误: 1) 对语言的假设和描述过于狭隘和僵化,实际上是“类型转换”,或者 2) 不切实际的模糊和模糊,或者 3) 在“形式语言理论”的意义上过于技术性,这很少见给刚接触一门语言的人使用(只是尝试在某个时候获得对“功能语言”的良好描述)。
  • 只是想关注这个话题给我带来了新的逻辑挑战
【解决方案4】:

当您开始使用它们时,我认为有许多差异会变得清晰。请记住,由于术语的变化,过去被称为相同事物的事物现在意味着非常不同的事物。

非常广泛的差异概述。

SQL 语句针对关系数据库并从该数据库查询(请求)数据,对该数据的更改和结果准确地用语言表达,而在 Prolog 中您定义事实,逻辑引擎根据以下内容生成新事实现有的事实。通过评估创建新数据(事实)。

它们都使用一种叫做查询的东西(但它们的工作方式完全不同)并且它们都有数据(但使用方式不同。)

SQL 和 Prolog 的用例也完全不同。在 Prolog 中存储地址列表永远不会有意义,而这正是 SQL 的设计目的。

简单地说,SQL 用于访问数据存储,Prolog 是一个表达式求值器。

【讨论】:

    【解决方案5】:

    我认为主要区别在于 Prolog 是一种查询语言,用于将复杂模式与简单事实的数据库进行匹配。另一方面,SQL 仅限于关系数据库。

    【讨论】:

    • 你是说 SQL 比 Prolog 更受限制——我不确定这种比较是否有意义。
    • 不,我不是在做比较,我是说SQL只用于查询关系逻辑。
    【解决方案6】:

    只是一些想法:

    1. SQL 是一种用于(可能是任意复杂的)访问(关系)数据的查询语言,它不是一种编程语言。
    2. 即使将 SQL 视为编程语言 - 它也不是图灵完备的。我很难想象 sql 查询返回 1 到 100 的总和(例如)。
    3. SQL 是用于访问/操作 (DML) 到 数据 库的语言,其中 Prolog 是一种用于处理 知识 库的语言(当然还有规则解析引擎) .实际上,Prolog 不再是简单的统一回溯
    4. 这并不是说 SQL 和 Prolog 的应用领域,它们的原因完全不同 - 高效(常规)数据存储和 AI/符号计算/解析/专家系统/约束求解器/.../更多。

    【讨论】:

    • SQL 一种编程语言,它只是不是 GP(通用)编程语言。从 ANSI SQL 9x 开始,它图灵完备的,尽管这在很大程度上无关紧要。
    • 仅供参考,这是完全正确的 SQL:SELECT SUM(value) FROM Integers WHERE Value BETWEEN 1 AND 100
    • 好吧,我想到了一个你不使用任何表(附加数据)的情况。就像序言中的以下内容: sum1(From, From, S, S) :-!。 sum1(From, To, S0, S) :- S1 是 S0 + From, From1 是 From + 1, sum1(From1, To, S1, S)。 ?- sum1(1, 101, 0, R)。 R = 5050。我敢打赌这用 SQL 是不可能的。否则考虑找到 N 的斐波那契数的情况。一张桌子对你有帮助吗?顺便说一句,请提供一个 url,说明 ANSI SQL 是图灵完备的。我曾经知道关系演算不是图灵设计的完整,尽管有些实现可以......
    • 表是 SQL 等基于表的范例所固有的。是的,我可以在 SQL 中使用 Peano 的推理技巧,但关键是您不必这样做。而且你对 SQL 中的斐波那契数列也是错误的。就在最粗略的层面上:ANSI/ISO SQL 从 ISO 9x 开始就有递归,这意味着它是完全图灵完备的(因为递归和迭代在编程理论中是相同的),这意味着它可以计算任何其他语言可以计算的任何东西.而且 SQL 是关系微积分的超集,因此您无法实现这种逻辑飞跃。
    • 你说的是存储过程/函数吗?如果是,那么我同意这一点,但对我来说这是另一回事。原因,将 Prolog 与存储过程语言(无论是 pgplsql/sql 服务器方言/其他语言)进行比较与将 Prolog 与 PHP 或 Java 进行比较并不遥远。因为,从技术上讲,存储过程对于 SQL 来说并不是必不可少的,它只是一个优化(使应用程序逻辑更接近数据)。
    【解决方案7】:

    xonix,你需要更多的开发经验才能说是否可以在 sql 中完成某些事情。

    以下是您的 fibo 系列的至少 2 个解决方案。一个使用Stored Procedure,另一个使用CTE。任君挑选。

    方法一

    declare @a int, @b int, @c int, @i int, @N int = 10
    select @a=0, @b=1, @i=0, @c=0
    print @a
    print @b
    while @i < @N 
    Begin
    set @c=@a+@b
    print @c
    set @i=@i+1
    set @a=@b
    set @b=@c
    end
    

    方法 2

    WITH FibonacciNumbers (RecursionLevel, FibonacciNumber, NextNumber) 
    AS (
    -- Anchor member definition
    SELECT  
    0  AS RecursionLevel,
    0  AS FibonacciNumber,
    1  AS NextNumber
    UNION ALL
    -- Recursive member definition
    SELECT  a.RecursionLevel + 1             AS RecursionLevel,
    a.NextNumber                     AS FibonacciNumber,
    a.FibonacciNumber + a.NextNumber AS NextNumber
    FROM FibonacciNumbers a
    WHERE a.RecursionLevel < 10
    )
    -- Statement that executes the CTE
    SELECT 
    'F' + CAST( fn.RecursionLevel AS VARCHAR) AS FibonacciOrdinal, 
    fn.FibonacciNumber,
    fn.NextNumber
    FROM FibonacciNumbers fn; 
    GO
    

    【讨论】:

      【解决方案8】:

      在我看来,主要区别在于 SQL 从表中检索行,即从与某些过滤条件相对应的有限实例化对象集中。另一方面,Prolog 理论上为您提供了满足条件的所有可实例化对象。在 Prolog 中,您还可以从有限集中检索实体,但在 SQL 中,您无法从理论上无限集中获取所有值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多