1.2 关于术语的一些说明
在1.1节的关系化问题列表中,你可能意识到我使用了形式化术语“关系”(relation)、“元组”(tuple)及“属性”(attribute)。SQL当然不使用这些术语,取而代之的是更“用户友好的”术语:“表”(table),“行”(row),“列”(column)。只要有助于使知识更易于理解,我通常都会赞同使用更“用户友好的”术语。然而,就当前的情况而言,我(遗憾地)认为它们没有使知识更易于理解,而是曲解了知识并实际上损害了真正理解的形成。真相是,关系并不是表,元组并不是行而属性也并不是列。尽管在某些非正式上下文中对术语的曲解(即关系是表,元组是行而属性是列——译者注)是可被接受的(事实上我自己也经常如此),但是我要说:只有当我们全都理解“用户友好的”术语只是对于真相的近似而不能抓住事实本质时,它才是可接受的。换个说法:如果你确实理解真实情况,那么合理地使用“用户友好的”术语是一个不错的想法,但是如果以学习和领会真实情况为第一要义的话,你需要使用正式的术语。因此,在这本书中,我将会使用正式用语(至少在我讲述与SQL相对的关系模型时会是如此),并在合适的时机为这些正式术语给出精确定义。相反,在SQL上下文中,我会使用SQL的专用术语。
关于术语的另外一点是:尽管我已经说过SQL试图简化一个术语集合,但我必须强调的是,它使另外一个术语集合复杂起来。我指的是SQL对于术语“运算符”(operator)、“函数”(function)、“过程”(procedure)、 “程序”(routine)和“方法”(method)的使用,所有这些本质上代表同一个事物(即使有差别也微乎其微)。在这本书中我会全程使用术语“运算符”;比如,我会明确地将“=”(等值比较)、“:=”(赋值)、“+”(加)、DISTINCT、JOIN、SUM和GROUP BY(等等)都称作运算符。
需要注意的是,说到SQL,请允许我提醒你(如前言所述):除非是在极为有限的几个上下文中,否则本书中的SQL指的都是标准版本的SQL语言。注2
然而:
- 标准所用的术语有时并不适合使用。此时,我一般会使用我自己的术语。比如,我会使用“表表达式”(table expression)代替SQL标准中的术语“查询表达式”(query expression),这是因为:首先,这种表达式表示的值实际是表而不是查询;其次,查询并不是使用这种表达式涉及的唯一上下文(事实上,SQL标准中确实使用了术语“表表达式”,但是用的很不恰当;具体来说, “表表达式”在标准中用来指代SELECT表达式中SELECT子句后面的部分)。
- 紧接着上一点,(不论是从我的观点还是从标准的观点出发)在SQL中并不是所有的“表表达式”在其本应合法的所有上下文中都是合法的。尤其是,尽管一个显式JOIN调用肯定表示一个表,但它不能作为独立的(stand alone)表表达式出现(即,不能独自出现在嵌套查询中的最外层),也不能作为构成子查询的括号内部表表达式出现(参见第12章)注3。请注意,这些说明适用于书中很多单独的讨论,但不断地重复这些说明是很乏味的,我也不会那么做(不过,在第12章的BNF语法部分我会再次提及它们)。
- 我忽略了SQL标准中被认为是晦涩难懂的部分,尤其是那些不是SQL标准所谓的核心SQL部分或是与关系化处理本身无紧密联系的部分。这些内容的具体例子包括:分析或窗口(OLAP)函数,动态SQL,临时表,以及用户自定义类型的细节。
- 出于某些原因,我使用了不同于SQL标准的注释风格。具体来说,我使用由“/”及“/”分隔符包围的斜体字符串来显示注释。
不过要注意,所有的SQL数据库产品都包括SQL标准本身不存在的特性。行编号(row ID)就是一个普遍的例子。一般情况下,我对于此类特性的建议是:只要这些特性不违反关系化原则,那么就尽可能地使用(毕竟,我倡导的是SQL的关系化方法)。比如,行编号尤其容易单独违反或同时违反互换性原理(The Principle of Interchangeability,参见第9章)和信息原理(The Information Principle,参见附录A);如果违反了,那么我就肯定不会使用行编号。不过,不管在哪,最高规则是:只要你知道你正在做什么,那么你怎么做都行。