数据库表的运算及表示方法
在数据库中,表之间的运算核心基于关系代数,主要用于对多个表的元组(行)或属性(列)进行组合、筛选、合并等操作。这些运算需要遵循一定规则(如部分运算要求表“同构”——属性数量、类型、顺序一致),实际开发中常通过SQL语句实现。以下按运算类型分类,详细说明核心运算的符号、表示方法及示例。
一、基础集合运算(要求表“同构”)
基础集合运算包括并、交、差,三者均要求参与运算的两个表是“同构表”(属性数量、数据类型、顺序完全一致),结果仍为同构表。
1. 并运算(Union)
-
定义:将两个表的所有元组合并,去除重复元组(保留所有不重复的行)。
-
符号:∪(关系代数符号);SQL中用
UNION
(去重)或UNION ALL
(不去重)。 -
表示方法:设表A和表B为同构表,则并运算表示为
A ∪ B
。 -
示例:
现有两个学生表(同构,属性:学号、姓名):
表A(一班学生):学号 姓名 001 张三 002 李四 表B(二班学生):
学号 姓名 002 李四 003 王五 并运算
A ∪ B
结果(去重后):学号 姓名 001 张三 002 李四 003 王五 SQL实现(去重):
SELECT 学号, 姓名 FROM 表A UNION SELECT 学号, 姓名 FROM 表B;
2. 交运算(Intersection)
-
定义:取两个表中共有的元组(同时存在于两个表中的行)。
-
符号:∩(关系代数符号);SQL中用
INTERSECT
(部分数据库支持,如PostgreSQL、Oracle),或通过IN
/JOIN
模拟。 -
表示方法:
A ∩ B
(结果为A和B共有的元组)。 -
示例:
基于上述表A和表B,交运算A ∩ B
结果(仅共有的“李四”):学号 姓名 002 李四 SQL实现(用
JOIN
模拟):SELECT A.学号, A.姓名 FROM 表A A JOIN 表B B ON A.学号 = B.学号 AND A.姓名 = B.姓名; -- 同构表需匹配所有属性
3. 差运算(Difference)
-
定义:取“属于第一个表但不属于第二个表”的元组(仅保留第一个表独有的行)。
-
符号:-(关系代数符号);SQL中用
EXCEPT
(部分数据库支持),或通过NOT IN
/LEFT JOIN + IS NULL
模拟。 -
表示方法:
A - B
(结果为A中存在、B中不存在的元组)。 -
示例:
基于上述表A和表B,A - B
结果(A独有的“张三”):学号 姓名 001 张三 SQL实现(用
LEFT JOIN
模拟):SELECT A.学号, A.姓名 FROM 表A A LEFT JOIN 表B B ON A.学号 = B.学号 AND A.姓名 = B.姓名 WHERE B.学号 IS NULL; -- 筛选B中无匹配的A元组
二、组合运算(不要求同构,核心为“笛卡尔积”及衍生)
组合运算用于将多个表的属性或元组“组合”,核心是笛卡尔积,以及基于笛卡尔积的连接运算(实际开发中更常用)。
1. 笛卡尔积(Cartesian Product)
-
定义:将表A的每个元组与表B的每个元组“两两组合”,结果表的属性为A和B的所有属性(顺序:A在前,B在后),元组数量 = A的行数 × B的行数。
-
符号:×(关系代数符号);SQL中直接写多个表名(无连接条件时默认笛卡尔积)。
-
表示方法:
A × B
(结果属性为A的所有属性 + B的所有属性)。 -
示例:
表A(学生表,属性:学号、姓名):学号 姓名 001 张三 表B(课程表,属性:课程号、课程名):
课程号 课程名 C01 数学 C02 语文 笛卡尔积
A × B
结果(1×2=2行):学号 姓名 课程号 课程名 001 张三 C01 数学 001 张三 C02 语文 SQL实现(无连接条件的多表查询):
SELECT A.学号, A.姓名, B.课程号, B.课程名 FROM 表A A, 表B B; -- 等价于 A × B
-
注意:笛卡尔积结果行数可能极大(如1万行表×1万行表=1亿行),实际中几乎不直接使用,而是通过“连接运算”加条件筛选。
2. 连接运算(Join)
连接运算基于“笛卡尔积 + 条件筛选”,是多表查询的核心(解决“表之间关联”问题,如“学生-选课-课程”的关联)。按条件不同可分为以下几类:
(1)等值连接(Equi-Join)
-
定义:基于“某一属性值相等”的连接(从笛卡尔积中筛选出A的属性a与B的属性b相等的元组)。
-
符号:⨝ₐ=ᵦ(关系代数中用⨝加条件a=b);SQL中用
JOIN ... ON 条件
。 -
表示方法:
A ⨝ₐ=ᵦ B
(筛选A.a = B.b的元组)。 -
示例:
表A(学生表:学号、姓名):学号 姓名 001 张三 表B(选课表:学号、课程号):
学号 课程号 001 C01 等值连接(条件:A.学号 = B.学号)结果:
学号(A) 姓名 学号(B) 课程号 001 张三 001 C01 SQL实现:
SELECT A.学号, A.姓名, B.学号, B.课程号 FROM 表A A JOIN 表B B ON A.学号 = B.学号; -- 等值条件
(2)自然连接(Natural Join)
-
定义:特殊的等值连接——自动匹配两个表中名称相同的属性(无需手动指定条件),并去除重复的属性列(只保留一次相同属性)。
-
符号:⨝(关系代数符号);SQL中用
NATURAL JOIN
(需确保同名字段语义一致)。 -
表示方法:
A ⨝ B
(自动匹配同名字段,如A.学号和B.学号)。 -
示例:
基于上述表A(学生)和表B(选课),自然连接结果(自动匹配“学号”,去除重复学号列):学号 姓名 课程号 001 张三 C01 SQL实现:
SELECT * FROM 表A A NATURAL JOIN 表B B; -- 自动匹配“学号”,结果无重复学号列
-
注意:自然连接依赖“同名字段语义一致”(如均为“学号”),若存在同名字段但语义不同(如A.“编码”和B.“编码”分别指学生、课程),会导致错误,因此实际中更常用“等值连接+手动指定条件”。
(3)内连接(Inner Join)
-
定义:仅保留“两个表中满足连接条件”的元组(不满足条件的元组全部丢弃)。
-
符号:⨝(默认内连接,与等值连接符号一致,强调“只保留匹配项”);SQL中用
INNER JOIN
(可省略INNER
)。 -
与等值连接关系:内连接是“连接的筛选规则”,等值连接是“连接的条件类型”;等值连接默认是内连接(仅保留匹配元组)。
-
示例:
表A(学生):学号 姓名 001 张三 002 李四 表B(选课):
学号 课程号 001 C01 内连接(A.学号 = B.学号)结果(仅保留匹配的“张三”):
学号 姓名 课程号 001 张三 C01 SQL实现:
SELECT A.学号, A.姓名, B.课程号 FROM 表A A INNER JOIN 表B B ON A.学号 = B.学号; -- 李四无匹配,被丢弃
(4)外连接(Outer Join)
外连接与内连接的核心区别:保留不满足连接条件的元组(来自左表、右表或两者),未匹配的属性用NULL
填充。分为左外连接、右外连接、全外连接。
外连接类型 | 定义(保留的元组) | 符号(关系代数) | SQL关键字 |
---|---|---|---|
左外连接 | 保留左表所有元组,右表无匹配则用NULL填充 | ⟕ | LEFT OUTER JOIN |
右外连接 | 保留右表所有元组,左表无匹配则用NULL填充 | ⟖ | RIGHT OUTER JOIN |
全外连接 | 保留左表和右表所有元组,无匹配则用NULL填充 | ⟗ | FULL OUTER JOIN |
-
示例(左外连接):
基于上述表A(含李四)和表B(选课),左外连接(保留左表所有学生,包括未选课的李四):学号 姓名 课程号 001 张三 C01 002 李四 NULL SQL实现:
SELECT A.学号, A.姓名, B.课程号 FROM 表A A LEFT OUTER JOIN 表B B ON A.学号 = B.学号; -- 保留左表所有行
(5)非等值连接(Non-Equi Join)
-
定义:基于“非等于”条件的连接(如>、<、>=、<=、BETWEEN等)。
-
表示方法:
A ⨝ₐ>ᵦ B
(关系代数);SQL中用JOIN ... ON 非等值条件
。 -
示例:
表A(学生成绩):学号 成绩 001 85 表B(等级标准):
等级 最低分 最高分 A 80 100 非等值连接(条件:A.成绩 BETWEEN B.最低分 AND B.最高分):
学号 成绩 等级 最低分 最高分 001 85 A 80 100 SQL实现:
SELECT A.学号, A.成绩, B.等级 FROM 表A A JOIN 表B B ON A.成绩 BETWEEN B.最低分 AND B.最高分; -- 非等值条件
(6)自连接(Self Join)
-
定义:表与自身进行连接(需给表起别名区分“两个副本”),用于查询表内“存在关联的元组”(如“查询学生的同班同学”)。
-
表示方法:
A AS a ⨝ A AS b
(用别名a和b区分同一表的两个副本);SQL中通过别名实现。 -
示例:
表A(学生,含“班级”属性):学号 姓名 班级 001 张三 一班 002 李四 一班 003 王五 二班 自连接查询“张三的同班同学”(条件:a.班级 = b.班级 且 a.学号 ≠ b.学号):
a.姓名 b.姓名 班级 张三 李四 一班 SQL实现:
SELECT a.姓名, b.姓名, a.班级 FROM 表A a JOIN 表A b ON a.班级 = b.班级 -- 同班级AND a.学号 != b.学号; -- 排除自身 WHERE a.姓名 = '张三';
三、运算总结与核心区别
运算类型 | 核心逻辑 | 关键符号/关键字 | 适用场景 |
---|---|---|---|
并/交/差 | 基于同构表的元组合并/筛选 | ∪/∩/-;UNION /INTERSECT /EXCEPT | 合并结果、找共同/独有数据 |
笛卡尔积 | 元组两两组合(无筛选) | ×;多表无连接条件查询 | 作为连接运算的基础(极少直接用) |
内连接 | 保留满足条件的元组 | ⨝;INNER JOIN | 只需要“匹配的数据”(如已选课学生) |
外连接 | 保留匹配+不匹配的元组(含NULL) | ⟕/⟖/⟗;LEFT/RIGHT/FULL JOIN | 需要“完整数据”(如含未选课学生) |
自连接 | 表与自身关联查询 | 别名;JOIN +别名 | 表内存在关联关系(如同班同学) |
通过以上运算,可实现多表数据的灵活组合与筛选,其中内连接、外连接、自连接是实际开发中最常用的(解决表间关联问题),而并/交/差多用于同结构数据的合并或对比。