SQL 像英语是个善意的错误

news2024/11/6 2:41:58

我们知道,SQL 很像英语,简单的 SQL 语句直接可以作为英语读。除了 SQL 外,其它主要程序设计语言都没有这样,语法中就算有英语单词也仅仅是作为某些概念或操作的助记符而已,写出来的是形式化的程序语句 (statement) 而不是英语句子(sentence)。而 SQL 不同,它会把整个句子写成符合英语习惯的形式,还会补充很多不必要的介词,比如 FROM 作为语句的运算主体却被写到后面,GROUP 后面要写一个多余的 BY。
为什么会这样?很容易想到的理由是希望非程序设计人员也能使用。用户只要会读写英语,就可以写出 SQL 来查询数据。这显然是个善意的初衷,但结果却不尽如人意。绝大多数业务人员只会用 SQL 写非常简单的查询,而对于这类查询,现在有强大的 BI 软件能提供更为便捷直观的可视化界面来协助,并不需要直接手写语句,这个设计初衷就失去意义。反过来, 经常使用 SQL 做运算的仍然是程序员,SQL 还是一种编程语言,像不像英语对于程序员理解并没有多大差别,反而会带来不小的困难。
事实上,SQL 是一种语法非常严格的语言,语句中任何一点不合规的地方就会被数据库拒绝,使用者必须认真学习并遵守其语法规则,这和其它程序设计语言并没什么两样。而自然语言真正的优势在于具有模糊性,可以一定程度接受不严格的语法,但 SQL 并没有支持这一点,在发明 SQL 那个年代也实现不了这个特性。

像英语的好处体现不了,反而有不少坏处,将语法设计得像自然语言,看起来容易掌握,其实恰恰相反。
贴近自然语言带来的主要坏处是非过程性。程序逻辑一般是分步执行的,用变量记录中间结果,供后面的步骤使用。但自然语言不是这样,两句话之间的引用关系靠少量几个固定的代词维系,不精确也不方便。所以会把针对同一个主语的动作尽量拼到一句话中,这样就不必借助代词了。在 SQL 中的对应表现就是在一条语句中配有多个动作,SELECT、WHERE、GROUP 这些本来是无关的动作,在其它程序语言中通常会设计成多个函数,但在 SQL 中都会设计成语句的子句。还有,像 WHERE 和 HAVING 根本是一个意思,只对针对的对象不同,在拼到一个句子中就要采用两个词以示区别,让人费解(很多初学者会对 HAVING 很晕)。
实在一句话无法描述的复杂情况,在自然语言中就会使用从句了。这在 SQL 中的表现就是子查询,还可能出现多层嵌套的子查询,这种现象在其它程序设计语言中是不常见的。而且,子查询也要像自然语言,每次都要有个 SELECT…FROM,就会让人觉得非常啰嗦,代码变得长。

分步是降低理解和执行难度的有效办法。本来挺简单分几步能做到的事情,如果不分步就会很绕。可以想象,如果老师要求小学生做应用题时只能列一个算式完成,小朋友们会多么苦恼(当然,不乏一些聪明孩子搞得定)。
比如我们要找出销售额超过平均值两倍的客户,自然思维方式就是先计算出销售额的平均值,再找出销售额超这个值两倍的客户,两个语句完成。而 SQL 的写法就需要用子查询写成更长的一句。这个例子还算好懂,只有两层,一般自然语言的从句用来描述两层关系的理解难度还可以接受,但实际复杂的查询涉及到三五层的比比皆是,严重增加理解难度。
不提倡分步,就会导致单句 SQL 很长。程序员面临的复杂 SQL 语句,很少以行计,经常是以 K 计。而同样的 100 行代码,分成 100 个语句还是只有 1 个语句,其复杂度完全不是一个级别的。这种代码理解起来非常困难,好不容易写出来,过两个月后自己都读不懂,而且太长不分步的单句非常难以调试,开发周期也更长。

关于过程性,业界有个说法,SQL 是声明式语言,用户只要关心要什么,而不必关心怎么做,数据库会自动找解决方案,这档的语言不需要支持过程性。我们在前面已经批判过这个说法。
数据库厂商应该是也发现了 SQL 缺乏过程性的问题,所以后来增加了 CTE 语法来弥补,相当于提供了可以命名的中间变量。存储过程也相当于可以分步执行 SQL,有了分支循环甚至子程序。结果还是要回到过程式语言的老路,那还不如直接就设计成这样。
对于程序语言来说,好的分步计算机制带来的易用性要远远超过长得像自然语言。

更多问题前往乾学院探讨交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2233997.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

google adsense广告费中国收款结算被银行拒解决办法

多年前搞了几个网站,挂了谷歌google adsense广告,不知道不觉到了100美金最低结算,谷歌给我打款,之前是绑定交银银行的。被银行镜内登陆谷歌不合法不合规给拒绝入账,把美金退回了,怎么办? googl…

蓝桥杯 区间移位--二分、枚举

题目 代码 #include <stdio.h> #include <string.h> #include <vector> #include <algorithm> #include <iostream> using namespace std; struct node{ int a,b; }; vector<node> q; bool cmp(node x,node y){ return x.b <…

书生第四期实训营基础岛——L1G1000书生大模型全链路开源体系

书生浦语大模型开源开放体系 书生浦语开源一周年历史 2023.7.6&#xff1a;InternLM-7B开源率先免费商用发布全链条开源工具体系2023.9.20&#xff1a;InternLM-20B开源&#xff0c;开源工具链全线升级2024.1.17&#xff1a;InternLM2开源&#xff0c;性能超最新同量级开源模…

单元测试(Junit)

系统—模块—子模块&#xff0c;子模块中不可分割的程序单元的测试&#xff0c;单元的粒度根据实际情况可能是 类或方法等。 面向对象编程中&#xff0c;最小单元就是方法。 单元测试目的是在集成测试和功能测试之前对系统可测试单元进行逐一检查和验证。 单元测试基本原则 …

MySQL表的增删改查(CRUD3约束)

这次我们开始先不复习嗷&#xff0c;等到把数据表的删除说完咱们统一&#xff0c;总结书写 1.数据表的删除&#xff1a; 语法&#xff1a; 1. 使用 DROP TABLE 语句删除单个表 基本语法&#xff1a;DROP TABLE [IF EXISTS] table_name; table_name是要删除的表的名称。IF EXIS…

go中Println和Printf的区别

Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 go中Println和Printf的区别 package mainimport ( "fmt" )//TIP To run your code, right-click the c…

【系统面试篇】进程和线程类(1)(笔记)——区别、通讯方式、同步、互斥、锁分类

目录 一、问题综述 1. 进程和线程的区别&#xff1f; 2. 进程的状态有哪些&#xff1f; 3. 进程之间的通信方式? &#xff08;1&#xff09;管道 &#xff08;2&#xff09;消息队列 &#xff08;3&#xff09;共享内存 &#xff08;4&#xff09;信号量 &#xff08…

编译安装并刷写高通智能机器人SDK

The Qualcomm Intelligent Robotics Product SDK (QIRP SDK) 高通智能机器SDK基于ROS2进行开发&#xff0c;此SDK适用于高通linux发行版本&#xff0c;QIRPSDK中提供以下内容&#xff1a; ROS 包中用于支持机器人应用程序开发的参考代码 用于评估机器人平台的端到端场景示例集…

网页版五子棋—— WebSocket 协议

目录 前言 一、背景介绍 二、原理解析 1.连接过程&#xff08;握手&#xff09; 2.报文格式 三、代码示例 1.服务端代码 &#xff08;1&#xff09;TestAPI 类 &#xff08;2&#xff09;WebSocketConfig 类 2.客户端代码 3.代码演示 结尾 前言 从本篇文章开始&am…

鸿蒙应用开发:下载功能

鸿蒙系统不断发展&#xff0c;有与安卓、iOS 形成三足鼎立之势&#xff0c;且其在智能手机、智能穿戴、车载、家居等行业领域的应用越来越广泛。作为开发者&#xff0c;如何抓住鸿蒙生态崛起的机遇&#xff0c;解决开发挑战&#xff0c;创造更好的应用体验&#xff1f;欢迎您和…

小白直接冲!BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测

小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 小白直接冲&#xff01;BiTCN-BiLSTM-Attention双向时间卷积双向长短期记忆神经网络融合注意力机制多变量回归预测效果一览基本介绍程序设计参考资料 效果一…

如何绘制产业链图谱?

绘制产业链图谱是一个系统性的工作&#xff0c;涉及到对产业的深入理解和分析。对于一般产业绘制产业图谱的步骤&#xff0c;我们可以参照以下流程&#xff1a; 1.明确目标产业链&#xff1a;确定要分析的产业链&#xff0c;比如新材料、新能源、智能制造等&#xff0c;这通常…

Pycharm,2024最新专业版下载安装配置详细教程!

先来一段官方介绍&#xff0c;PyCharm是一种PythonIDE&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外&#xff0c;该IDE提供了一些高级功能…

鸿蒙开发——进程模型与进程通信

1、进程模型 ❓ 什么是进程&#xff1f; 进程是一个正在执行的程序的实例。当我们启动一个程序时&#xff0c;操作系统会创建一个进程&#xff0c;分配给它所需的资源&#xff0c;如内存和CPU时间。每个进程至少有一个线程&#xff0c;即执行线程&#xff0c;负责执行程序的指…

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…

[大模型]Diffusion扩散式生成模型

一、概述 扩散式生成模型相较于GAN网络的对抗式生成模型&#xff0c;有更高的精度&#xff0c;也更符合人类的视觉和审美罗技&#xff0c;且风格化能力更强。现行的所有Diffusion模型都是基于2020年的论文DDPM来实现的。 GAN网络通过使生成器(Generator)生成的模型尽可能的逼近…

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…

keil5的Debug调试时,卡在 LDR R0, =SystemInit,无法往后进行

解决办法&#xff1a;使用STM32Cube生成的工程文件时&#xff0c;勾选Use MicroLIB即可

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…