《SQL与关系数据库理论——如何编写健壮的SQL代码》一一2.5 标量类型vs.非标量类型

简介: 本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第2章 ,第2.5节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第2章 ,第2.5节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.5 标量类型vs.非标量类型

通常,都会认为类型不是标量的就是非标量的。换言之,如果一个类型没有用户可见的分量,那么它就是标量的;否则它就是非标量的。某个类型T的值、变量、属性、运算符、参数及表达式是否是标量的,取决于类型T本身是否是标量的。例如:

  • 整数类型是标量类型,因此,整数类型的值、变量等也都是标量的,即它们没有用户可见分量。
  • 元组和关系类型是非标量的(相关的用户可见分量是对应的属性)。因此,元组和关系值、变量等也都是非标量的。

必须强调,这些概念是相当不严格的。实际上,我们已经看到数据值原子性的概念本就没有什么绝对的含义,那么“标量”本身也只不过是同一概念的另一名称罢了。因此,在任何正式意义上,关系模型都不会依赖于标量与非标量的区别。然而,在本书中要非正式地依赖它。我发现它直观上非常有用。具体说,对于既不是元组也不是关系的类型,使用术语标量;而对于元组或关系类型,使用术语非标量。注12
旁注:你有时会听到另一个表示“标量”的术语是封装(encapsulation)。然而要小心,这个术语也被(尤其在对象上下文中)用来指对代码和数据(更准确地是运算符定义和数据表示定义)的物理捆绑或打包。但是若使用了后面这种意义,就混淆了模型和实现,显然用户并不关心也不必关心代码和数据到底是物理绑定在一起的还是分离的。
我们来看一个例子。下面是Tutorial D对于基关系变量 S(supplier)的定义。注意,为了简化,我将所有的属性都定义为某种系统定义类型:

1.     VAR S BASE
2.         RELATION { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR }
3.         KEY { SNO } ;

解释:
第1行中的关键字VAR表示此句为一个变量的定义;S是变量的名称,关键字BASE特别指出变量是一个基关系变量。
第2行指定变量的类型。关键字RELATION说明它是一个关系类型。此行的剩余部分指定构成对应关系标题的属性集合(在第1章中,一个属性定义为一个“属性-名称”/“类型-名称”对,并且在标题中没有两个属性具有相同的属性名称)。当然,类型是非标量类型。属性的顺序并不重要。
第3行定义{SNO}是这个关系变量的(候选)键。
事实上,这个例子也讲解了另一要点,即下述类型是一个生成式类型的示例。

RELATION { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR }

一个生成式类型是通过调用某些类型生成器(type generator)获得的类型(此例中,类型生成器就是RELATION)。你可以认为一个类型生成器是一种特殊类型的运算符;它之所以特殊是因为:(a)它返回一个类型而不是一个值;(b)它在编译期被调用而不是在运行时被调用。比如,大部分编程语言都支持名为ARRAY的类型生成器,可以让用户定义各种特定的数组类型。然而,我们现在关心的类型生成器是TUPLE和RELATION。下面是一个包含TUPLE类型生成器的示例:

VAR STV /* 元组变量 */
    TUPLE { STATUS INTEGER , SNO CHAR , CITY CHAR , SNAME CHAR } ;

在任何时刻变量STV的取值都是一个标题与关系变量S的标题相同的元组(我特意指定了不同的属性顺序,就是为了说明次序并不重要)。注13因此,我们可以设想一个代码片段:(a)从关系变量S当前取值中抽取一个“一-元组”关系(可能这个关系就包含一个针对供应商S1的元组);(b)从那个“一-元组”关系中抽取单一的元组;(c)将抽取出的元组赋值给变量STV。在Tutorial D中:

STV := TUPLE FROM ( S WHERE SNO = 'S1' ) ;

重点:我可不想让你在这里产生误解。尽管某些存取suppliers-and-parts数据库的应用程序需要STV这样的变量,但在数据库内部不可以出现这样的变量。一个关系数据库只包含一种变量,即关系变量(relvars)。换句话说,关系变量是关系数据库中唯一允许存在的变量类型。(后面提到——关系变量是关系数据库中允许存在的唯一变量类型——构成了信息原理(Information Principle)。附录A中将进行更详细的说明)。
另外,要特别注意的是(如前例所示)一个元组t和一个仅仅包含元组t的关系r是存在逻辑差异的。尤其是,它们属于不同类型——t是某个元组类型而r是某个关系类型(尽管这些类型确实有一样的属性标题,或者说有相同的属性)。
最后,以下内容为其他要点:

  • 尽管元组和关系类型都有用户可见分量(即它们的属性),但并不是说这些分量也必须进行同样的物理存储。实际上,元组及关系的物理表示应该对用户是掩藏的,就好像标量值一样。(参考第1章中对于物理数据独立性的讨论。)
  • 类似于标量类型,元组和关系类型肯定需要与其关联的选择器运算符(字面值是特例)。下一章将详细说明。不过,它们并不需要THE_运算符;替代的,它们有对相应属性进行存取的运算符,这些运算符的角色相当于THE_运算符之于标量类型。
  • 元组和关系类型还需要赋值和相等比较运算符。本节已经给出了元组赋值的示例;下一章会对其他的运算符进行详细说明。
相关实践学习
MySQL数据库快速部署实践
本场景主要介绍如何在一台配置了CentOS 7.7版本的ECS实例(云服务器)上安装mysql,执行mysql的常用操作,学习基本的SQL语句。
相关文章
|
存储 关系型数据库 数据库
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
本文通过一个 Agentic RAG 应用的完整构建流程,展示了如何借助 RDS Supabase 快速搭建具备知识处理与智能决策能力的 AI 应用,展示从数据准备到应用部署的全流程,相较于传统开发模式效率大幅提升。
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1985 152
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1379 156
|
存储 缓存 数据库
数据库数据删除策略:硬删除vs软删除的最佳实践指南
在项目开发中,“删除”操作常见但方式多样,主要分为硬删除与软删除。硬删除直接从数据库移除数据,操作简单、高效,但不可恢复;适用于临时或敏感数据。软删除通过标记字段保留数据,支持恢复和审计,但增加查询复杂度与数据量;适合需追踪历史或可恢复的场景。两者各有优劣,实际开发中常结合使用以满足不同需求。
1677 4
|
SQL 容灾 安全
云时代SQL Server的终极答案:阿里云 RDS SQL Server如何用异地容灾重构系统可靠性
在数字化转型的浪潮中,数据库的高可用性已成为系统稳定性的生命线。作为经历过多次生产事故的资深开发者,肯定深知传统自建SQL Server架构的脆弱性——直到遇见阿里云 RDS SQL Server,其革命性的异地容灾架构彻底改写了游戏规则。
|
SQL 关系型数据库 PostgreSQL
CTE vs 子查询:深入拆解PostgreSQL复杂SQL的隐藏性能差异
本文深入探讨了PostgreSQL中CTE(公共表表达式)与子查询的选择对SQL性能的影响。通过分析两者底层机制,揭示CTE的物化特性及子查询的优化融合优势,并结合多场景案例对比执行效率。最终给出决策指南,帮助开发者根据数据量、引用次数和复杂度选择最优方案,同时提供高级优化技巧和版本演进建议,助力SQL性能调优。
|
存储 数据采集 数据挖掘
CSV vs 数据库:数据存储的最佳选择是什么
本文介绍了爬虫数据存储中CSV和数据库的优缺点,分析了两者在不同场景下的适用性。CSV简单易用、资源消耗低,适合小量数据;数据库则在处理大量数据和复杂查询时表现出色,支持并发操作。通过Python代码示例,展示了如何使用多线程和爬虫代理IP技术将百度搜索数据存储到MySQL数据库中,适用于大型项目和复杂数据分析需求。
1105 2
|
缓存 物联网 数据库
InfluxDB vs TDengine :2025 年了,谁家用的数据库还不能高效读缓存?
在工业互联网和物联网的大数据应用场景中,实时数据的写入和查询性能至关重要。如何快速获取最新设备状态并实时处理数据,直接影响到业务的高效运转。本文将深入分析 TDengine 和 InfluxDB 在缓存机制上的差异,帮助读者更好地理解这两款主流时序数据库在性能优化方面的优劣。
1426 1