知识卡片

关系的五条性质与SQL表为何不是关系

结构图卡

内容

每个关系都由标题(heading,一组”属性名-类型名”配对,不允许重复属性名)和主体 (body,一组符合该标题的元组构成的集合)两部分组成;严格来说是关系”包含”了一个 主体、主体又”包含”元组,但日常习惯上直接说关系”包含”元组。度(degree/元数)指 标题里属性的个数(元组也有度),基数(cardinality)指主体里元组的个数。由这个 定义可以严格推出五条性质,其中三条直接决定了SQL的表并不是真正意义上的关系: 主体是数学意义上的集合,所以不允许重复元组——SQL的表通常允许重复行,这是SQL表 不是关系的第一个原因(SELECT DISTINCT CITY FROM S 才是真正的关系运算结果, 不加DISTINCT的结果没有主键、不是关系);主体是集合,元组因此上下无序,ORDER BY 只是为了显示方便,并不是关系运算符,加了ORDER BY的查询结果不是关系;标题也是 集合,属性因此左右无序——SQL的表恰好有明确的列顺序,这是SQL表不是关系的第二个 原因(SELECT SNO,CITYSELECT CITY,SNO 代表同一个关系但却是不同的SQL表)。 另外两条性质是:每个关系永远满足第一范式(每个行列交叉点只有一个恰当类型的值); 关系与它的图示之间是逻辑上完全不同的两个东西(用Magritte的名画”这不是一支烟斗” 类比,图示只是对关系的一种描绘,不是关系本身)。

结构图

flowchart TD
    A[关系 relation] --> B[标题 heading<br/>属性名+类型名配对/无重名]
    A --> C[主体 body<br/>符合标题的元组集合]
    C --> D[性质1: 无重复元组<br/>SQL表允许重复行→不是关系]
    C --> E[性质2: 元组上下无序<br/>ORDER BY非关系运算符]
    B --> F[性质3: 属性左右无序<br/>SQL表有列顺序→不是关系]
    A --> G[性质4: 恒满足第一范式]
    A --> H[性质5: 关系≠关系图示<br/>Magritte烟斗类比]

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第1章"做好准备"1.6节 "关系的性质"(源文件:OEBPS/text00012.html) - 结论依据:原文明确"每个关系都有一个标题和一个主体……主体是元组的一个集合, 因此不允许重复的元组……而SQL的表通常是允许重复行的,所以SQL的表并不是真正 的关系""元组是无序的,从上到下……属性也是无序的,从左到右……SQL的表却是列 有序的",并以`SELECT DISTINCT CITY FROM S`和Magritte画作为例说明。 - 原始内容:主体是元组的一个集合……不允许重复的元组……SQL的表通常是允许重复 行的,所以SQL的表并不是真正的关系……ORDER BY对于显示结果很有用,但并不是 关系运算符……这不是一支烟斗(Magritte画作类比:图示不是关系本身)。