← 前一天目录后一天 →

每日科普 · 2026-10-26 周一

考研 408 × 求职面试

知识点 · 数据库系统 · 进阶

除运算的定义与典型查询应用

除运算是关系代数中表达“全部/所有”的运算。设 R 的属性集为 X∪Y,S 的属性集为 Y,则 R÷S 的结果属性为 X,包含所有这样的 x:对 S 中的每一个 y,都有 (x,y) 出现在 R 中。换句话说,x 必须和 S 中所有值都配对,而不是只和其中一个配对。 典型查询:查“选修了全部课程的学生学号”,可写成 学生选课关系 ÷ 课程关系;查“供应了所有零件的供应商”,用供应关系 ÷ 零件关系。 实现时常用双重 NOT EXISTS:结果中不存在某个 S 值,使该 x 没有对应 R 记录。也可用计数/分组近似,但要注意去重、空集和 NULL。除运算结果是 R 在 X 上的投影中满足全称条件的元组,不一定包含 R 的全部 X 值。

每日一题 · 数据库系统

除运算的定义与典型查询应用

设 R(学号,课程号) 记录选课,S(课程号) 是课程集合。R÷S 的结果是( )。A 选修了 S 中至少一门课的学生学号;B 选修了 S 中全部课程的学生学号;C 没有选修 S 中课程的学生学号;D 选修课程数等于 S 元组数的学生学号。

解析

选 B。除运算结果属性为 R-S={学号},且对 S 中每个课程号 y,结果中的学号 x 都必须满足 (x,y)∈R,即选了 S 中全部课程。A 是存在语义;C 相反;D 看似计数,但未去重且未限定在 S 中,重复选课或选了其他课会误判。

面试小贴士 · 数据库系统

除运算的定义与典型查询应用

面试常问除法的语义和 SQL 实现。答:结果属性为 R-S,对 S 中每个 y 都存在 (x,y),常用双重 NOT EXISTS;易错写成 IN/计数、忘记去重、忽略空集与 NULL。

代码实现 · C++

代码示例

#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main(){
    // 示例:R 为 (x,y),S 为 y 集合,求 R÷S 的 x
    vector<pair<int,int>> R={{1,1},{1,2},{2,1}};
    set<int> S={1,2};
    set<int> X;
    for(auto &p:R) X.insert(p.first);
    for(int x:X){
        bool ok=true;
        for(int y:S){
            bool found=false;
            for(auto &p:R) if(p.first==x && p.second==y){found=true;break;}
            if(!found){ok=false;break;}
        }
        if(ok) cout<<x<<" ";
    }
    cout<<endl;
    return 0;
}
← 前一天目录后一天 →