理解SQL(1,2,3)

1、 SQL 是一种声明式语言

首先要把这个概念记在脑中:“声明”。 SQL 语言是为计算机声明了一个你想从原始数据中获得什么样的结果的一个范例,而不是告诉计算机如何能够得到结果。这是不是很棒?
(译者注:简单地说,SQL 语言声明的是结果集的属性,计算机会根据 SQL 所声明的内容来从数据库中挑选出符合声明的数据,而不是像传统编程思维去指示计算机如何操作。)

SELECT first_name, last_name FROM employees WHERE salary > 100000

上面的例子很容易理解,我们不关心雇员记录从哪来,只关心哪些记录是高薪者的数据(salary > 100000)

我们从哪儿学习到这些?

如果 SQL 语言这么简单,那么是什么让人们“闻 SQL 色变”?主要的原因是:我们潜意识中的是按照命令式编程的思维方式思考问题的。就好像这样:“电脑,先执行这一步,再执行那一步,但是在那之前先检查一下是否满足条件 A 和条件 B ”。例如,用变量传参、使用循环语句、迭代、调用函数等等,都是这种命令式编程的思维惯式。

2、SQL的语法并不按照语法的书写顺序执行

就是;SQL语句的执行顺序跟其语句的语法顺序并不一致。
SQL语句的语法顺序:
• SELECT[DISTINCT]
• FROM
• WHERE
• GROUP BY
• HAVING
• UNION
• ORDER BY
上面并没有把所有的SQL语法结构都列出来,但是已经足以说明SQL语句的语法顺序和其执行顺序完全不一样,上述语句执行顺序:
• FROM
• WHERE
• GROUP BY
• HAVING
• SELECT[DISTINCT]
• UNION
• ORDER BY
执行顺序,有三个值得我们注意的地方:
1、FROM才是SQL语句执行的第一步。数据库在执行SQL语句的第一步是将数据从硬盘加载到数据缓冲区中,以便对这些数据进行操作。(译者注:原文为“The first thing that happens is loading data from the disk into memory, in order to operate on such data.”,但是并非如此,以 Oracle 等常用数据库为例,数据是从硬盘中抽取到数据缓冲区中进行操作。)
2、SELECT是在大部分语句执行了之后才执行的,严格的说是在FROM和GROUP BY之后执行的。这一点非常重要,这就是你不能在WHERE中使用在SELECT中设定别名的字段作为判断条件的原因。

SELECT A.x + A.y AS z
FROM A
WHERE z = 10 -- z 在此处不可用,因为SELECT是最后执行的语句!

如果你想重用别名z,你有两个选择,要么就重新写一遍z所代表的表达式:

SELECT A.x + A.y AS z
FROM A
WHERE (A.x + A.y) = 10

。。。或者求助于衍生表、通用数据表达式或者视图,以避免别名重用。请看下文中的例子。
3、无论在语法上还是执行顺序上,UNION总是排在ORDER BY之前。很多人认为每个UNION段都能使用ORDER BY排序,但根据SQL语言标准以及各个数据库SQL执行差异,并不是的。某些数据库允许SQL语法对子查询(subqueries)或派生表(derived table)进行排序,但这并不能说明这个排序在UNION操作之后仍保持排序后的顺序。
注意:并非所有的数据库对 SQL 语句使用相同的解析方式。如 MySQL、PostgreSQL和 SQLite 中就不会按照上面第二点中所说的方式执行。

我们学到了什么?

我们要永远都记得:SQL语句的语法顺序和其执行顺序并不一致,这样我们就能避免一般性的错误。如果你能记住SQL语句语法顺序和执行顺序的差异,你就能理解一些很常见的SQL问题。
当然,如果一种语言被设计成语法顺序直接反映其语句的执行顺序,那么这种语言对程序员是十分友好的,这种编程语言层面的设计理念已经被微软应用到了LINQ语言中

3、SQL语言的核心是对表的引用(table references)

其实真正的核心在于对表的引用
根据SQL标准,FROM语句被定义为:

<from clause> ::= FROM <table reference> [ { <comma> <table reference> }... ]

FROM语句的“输出”是一张联合表,来自于所有引用的表在某一维度上的联合。我们慢慢来分析:

FROM a, b

上面这句FROM语句的输出是一张联合表,联合了表a和表b。如果表a有3个字段,表b有5个字段,那么这个“输出表”就有8(3+5)个字段。
这个联合表里的数据是:a*b,即a和b的笛卡儿积。也就是表a中的每一条数据都要和表b中的每一条数据配对。如果表a有3条数据,表b有5条数据,那么,联合表就会有15(3*5)条数据。
FROM输出的结果被WHERE语句筛选后要经过GROUP BY语句处理,从而形成新的处理结果。后面还会再讨论这方面。
如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。

我们学到了什么?

思考问题的时候从表的角度来思考问题,这样很容易理解数据如何在SQL的“流水线”上进行了怎样的变动。

Oct 31st, 2016

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章