跳到主要内容

包语义

包与集合有什么区别?​

  • 集合: 同一个元组只能出现一次;
  • 包: 同一个元组可以多次出现;
  • 关系模型: 纯关系代数默认按集合处理;
  • SQL: 表默认按包处理, 同一行可以重复出现;

包上的运算与集合上的运算有什么不同?​

  • 独立个体: 包的运算把每个元组 (含重复项) 视为独立个体;
  • 不去重: 运算结果不必去除重复元组;
  • 可增殖: 结果中可以出现多个重复的元组;
  • 代价: 结果的元组数取决于重复个数, 不能只按"有无"判断;

为什么需要包语义?​

  • 计数: 同一个值出现几次必须能表达, 例如某演员出演了几部电影;
  • 统计: 求和、平均等聚集操作按重复个数累加;
  • 默认行为: SQL 默认保留重复, 需要去重时显式使用 DISTINCT, 见 重复与聚集;

消重复操作符做什么?​

  • 作用: 去掉包中重复的元组, 使结果成为集合;
  • 对应 SQL: SELECT DISTINCT;
  • 代价: 需要排序或哈希比较, 耗费较大;

聚集操作符做什么?​

  • 作用: 作用于包的某一列, 把该列的多行值压缩为一个值;
  • 常见操作: 求和、平均、最小值、最大值、计数;
  • 对应 SQL: SUM、AVG、MIN、MAX、COUNT;

分组操作符做什么?​

  • 作用: 根据若干列上的属性值把元组划分成若干组;
  • 后续: 聚集操作符分别作用于每个分组, 而不是整个包;
  • 对应 SQL: GROUP BY, 见 分组与 HAVING;

拓展投影做什么?​

  • 定义: 投影的扩展;
  • 计算单位: 以列为单元进行计算;
  • 能力: 可以产生原关系中没有的新列, 例如计算 length / 60;
  • 对应 SQL: SELECT 中的表达式与别名;

排序算子做什么?​

  • 作用: 根据若干属性重新排列元组顺序;
  • 常见需求: 排名、分页、按顺序输出;
  • 对应 SQL: ORDER BY, 见 排序与表达式;

(source: 010-关系数据模型.md §包/§包的拓展操作)