百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

在SQL中:一切皆关系

mhr18 2025-02-13 13:12 17 浏览 0 评论

在计算机领域有许多伟大的设计理念和思想,例如:

  • 在 Unix 中,一切皆文件。
  • 在面向对象的编程语言中,一切皆对象。

关系数据库同样也有自己的设计思想:在 SQL 中,一切皆关系。

关系模型

关系模型(Relational model)由 E.F.Codd 博士于 1970 年提出,以集合论中的关系概念为基础;无论是现实世界中的实体对象还是它们之间的联系都使用关系表示。我们在数据库系统中看到的关系就是二维表(Table),由行(Row)和列(Column)组成。因此,也可以说关系表是由数据行构成的集合。

关系模型由数据结构、关系操作、完整性约束三部分组成。

  • 关系模型中的数据结构就是关系表,包括基础表、派生表(查询结果)和虚拟表(视图)。
  • 常用的关系操作包括增加、删除、修改和查询(CRUD),使用的就是 SQL 语言。其中查询操作最为复杂,包括选择(Selection)、投影(Projection)、并集(Union)、交集(Intersection)、差集(Exception)以及笛卡儿积(Cartesian product)等。
  • 完整性约束用于维护数据的完整性或者满足业务约束的需求,包括实体完整性(主键约束)、参照完整性(外键约束)以及用户定义的完整性(非空约束、唯一约束、检查约束和默认值)。

数据结构

在关系模型中,用于存储数据的逻辑结构称为关系(Relation);对于使用者而言,关系就是二维表(Table)。

以下是一个员工信息表,它和 Excel 表格非常类似,由行(Row)和列(Column)组成。

在不同的场景下,大家可能会听到关于同一个概念的不同说法。在此,我们列出了关系数据库中的一些常见概念:

  • 关系,也称为表,用于表示现实世界中的实体(Entity)或者实体之间的联系(Relationship)。举例来说,一个公司的员工、部门和职位都是实体,分别对应员工信息表、部门信息表和职位信息表;销售的产品和订单都是实体,同时它们之间存在联系,对应订单明细表。
  • 行,也称为记录(Record),代表了关系中的单个实体。上图中工号为 4 的数据行存储了“诸葛亮”的相关信息。关系(表)可以看作是由行组成的集合。
  • 列,也称为字段(Field),表示实体的某个属性。上图中的第二列包含了员工的姓名。表中的每个列都有一个对应的数据类型,常见的数据类型包括字符类型、数字类型、日期时间类型等。

有了关系结构之后,就需要定义基于关系的数据操作。

操作集合

常见的数据操作包括增加(Create)、查询(Retrieve)、更新(Update)以及删除(Delete),或者统称为增删改查(CRUD)。

其中,使用最多、也最复杂的操作就是查询,具体来说包括选择(Selection)、投影(Projection)、并集(Union)、交集(Intersection)、差集(exception)以及笛卡儿积(Cartesian product)等。我们将会介绍如何使用 SQL 语句完成以上各种数据操作。

为了维护数据的完整性或者满足业务需求,关系模型还定义了完整性约束。

完整性约束

关系模型中定义了三种完整性约束:实体完整性、参照完整性以及用户定义完整性。

  • 实体完整性是指表的主键字段不能为空。现实中的每个实体都具有唯一性,比如每个人都有唯一的身份证号;在关系数据库中,这种唯一标识每一行数据的字段称为主键(Primary Key),主键字段不能为空。每个表可以有且只能有一个主键。
  • 参照完整性是指外键参照的完整性。外键(Foreign Key)代表了两个表之间的关联关系,比如员工属于某个部门;因此员工表中存在部门编号字段,引用了部门表中的部门编号字段。对于外键引用,被引用的数据必须存在,员工不可能属于一个不存在的部门;删除某个部门之前,也需要对部门中的员工进行相应的处理。
  • 用户定义完整性是指基于业务需要自定义的约束。非空约束(NOT NULL)确保了相应的字段不会出现空值,例如员工一定要有姓名;唯一约束(UNIQUE)用于确保字段中的值不会重复,每个员工的电子邮箱必须唯一;检查约束(CHECK)可以定义更多的业务规则。例如,薪水必须大于 0 ,字符必须大写等;默认值(DEFAULT)用于向字段中插入默认的数据。

存储引擎(Storage Engine)是 MySQL 中用于管理、访问和修改物理数据的组件,不同的存储引擎提供了不同的功能和特性。从 MySQL 5.5 开始默认使用 InnoDB 存储引擎,支持事务处理(ACID)、行级锁定、故障恢复、多版本并发控制(MVCC)以及外键约束等。

关系数据库使用 SQL 作为访问和操作数据的标准语言。现在,让我们来直观感受一下 SQL 语句的特点。

语法特性

SQL 是一种声明性的编程语言,语法接近于自然语言(英语)。通过几个简单的英文单词,例如 SELECT、INSERT、UPDATE、CREATE、DROP 等,完成大部分的数据库操作。以下是一个简单的查询示例:

SELECT emp_id, emp_name, salaryFROM employeeWHERE salary > 10000ORDER BY emp_id;

它查询员工表(employee)中月薪(salary)大于 10000 的员工,返回工号、姓名以及月薪,并且按照工号进行排序。可以看出,SQL 语句非常简单直观。

以上查询中的 SELECT、FROM 等称为关键字(也称为子句),一般大写;表名、列名等内容一般小写;分号(;)表示语句的结束。SQL 语句不区分大小写,但是遵循一定的规则可以让代码更容易阅读。

SQL 是一种声明式的语言,声明式语言的主要思想是告诉计算机想要什么结果(what),但不指定具体怎么做。这类语言还包括 HTML、正则表达式以及函数式编程等。

面向集合

对于 SQL 语句而言,它所操作的对象是一个集合(表),操作的结果也是一个集合(表)。例如以下查询:

SELECT emp_id, emp_name, salaryFROM employee;

其中 employee 是一个表,它是该语句查询的对象;同时,查询的结果也是一个表。所以,我们可以继续扩展该查询:

SELECT emp_id, emp_name, salaryFROM (SELECT emp_id, emp_name, salaryFROM employee) dt;

我们将括号中的查询结果(取名为 dt)作为输入值,传递给了外面的查询;最终整个语句的结果仍然是一个表。

SQL 中的查询可以完成各种数据操作,例如过滤转换、分组汇总、排序显示等;但是它们本质上都是针对表的操作,结果也是表。

不仅仅是查询语句,SQL 中的插入、更新和删除都以集合为操作对象。我们再看一个插入数据的示例:

CREATE TABLE t(id INTEGER);-- 适用于 MySQL、SQL Server 以及 PostgreSQLINSERT INTO t(id)VALUES (1), (2), (3);

我们首先使用 CREATE TABLE 语句创建了一个表,然后使用 INSERT INTO 语句插入数据。在执行插入操作之前,会在内存中创建一个包含 3 条数据的临时集合(表),然后将该集合插入目标表中。由于我们通常一次插入一条数据,以为是按照数据行进行插入;实际上,一条数据也是一个集合,只不过它只有一个元素而已。

Oracle 不支持以上插入多行数据的语法,可以使用下面的插入语句:

-- 适用于 OracleINSERT INTO t(id)SELECT 1 FROM DUALUNION ALLSELECT 2 FROM DUALUNION ALLSELECT 3 FROM DUAL;

UNION ALL 是 SQL 中的并集运算,用于将两个集合组成一个更大的集合。此外,SQL 还支持交集运算(INTERSECT)、差集运算(EXCEPT)以及笛卡儿积(Cartesian product)。我们会在第 18 篇中介绍这些内容,它们也都是以集合为对象的操作。

我们已经介绍了 SQL 语言的声明性和面向集合的编程思想。在正式学习编写 SQL 语句之前,还需要进行一些准备工作,主要就是安装示例数据库。

示例数据库

在学习过程中,我们主要使用一个虚构的公司数据模型。该示例数据库包含 3 个表:员工表(employee)、部门表(department)和职位表(job)。以下是它们的结构图,也称为实体-关系图(Entity-Relational Diagram):

  • 部门表(department),包含部门编号(deptid)和部门名称(deptname)字段,主键为部门编号。该表共计 6 条数据。
  • 职位表(job),包含职位编号(jobid)和职位名称(jobtitle)字段,主键为职位编号。该表共计 10 条数据。
  • 员工表(employee),包含员工编号(empid)和员工姓名(empname)等字段,主键为员工编号,部门编号(deptid)字段是引用部门表的外键,职位编号(jobid)字段是引用职位表的外键,经理编号(manager)字段是引用员工表自身的外键。该表共计 25 条数据。

我们在 GitHub 上为大家提供了示例表和初始数据的创建脚本和安装说明,支持 Oracle、MySQL、SQL Server 以及 PostgreSQL。点击链接进行下载。

运行这些脚本之前,需要先安装数据库软件。网络上有很多这类安装教程可以参考;如果无法安装数据库,也可以使用这个免费的在线 SQL 开发环境:http://sqlfiddle.com,它提供了各种常见的关系数据库服务。下图是使用 MySQL 运行示例脚本的结果:

选择数据库之后,将创建表和插入数据的脚本复制到左边窗口,点击“Build Schema”进行初始化;点击“Browser”可以查看表结构;在右侧窗口输入 SQL 语句,点击“Run SQL”运行并查看结果。该工具提供的数据库不是最新版本,但是可以运行大部分的示例。

文章中所有的示例都在以下数据库版本中进行了验证:

  • Oracle database 18c
  • MySQL 8.0
  • SQL Server 2017
  • PostgreSQL 12

小结

关系模型中定义了一个简单的数据结构,即关系(表),用于存储数据。SQL 是关系数据库的通用标准语言,它使用接近于自然语言(英语)的语法,通过声明的方式执行数据定义、数据操作、访问控制等。对于 SQL 而言,一切都是关系(表)。

相关推荐

使用 Docker 部署 Java 项目(通俗易懂)

前言:搜索镜像的网站(推荐):DockerDocs1、下载与配置Docker1.1docker下载(这里使用的是Ubuntu,Centos命令可能有不同)以下命令,默认不是root用户操作,...

Spring Boot 3.3.5 + CRaC:从冷启动到秒级响应的架构实践与踩坑实录

去年,我们团队负责的电商订单系统因扩容需求需在10分钟内启动200个Pod实例。当运维组按下扩容按钮时,传统SpringBoot应用的冷启动耗时(平均8.7秒)直接导致流量洪峰期出现30%的请求超时...

《github精选系列》——SpringBoot 全家桶

1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...

Nacos简介—1.Nacos使用简介

大纲1.Nacos的在服务注册中心+配置中心中的应用2.Nacos2.x最新版本下载与目录结构3.Nacos2.x的数据库存储与日志存储4.Nacos2.x服务端的startup.sh启动脚...

spring-ai ollama小试牛刀

序本文主要展示下spring-aiollama的使用示例pom.xml<dependency><groupId>org.springframework.ai<...

SpringCloud系列——10Spring Cloud Gateway网关

学习目标Gateway是什么?它有什么作用?Gateway中的断言使用Gateway中的过滤器使用Gateway中的路由使用第1章网关1.1网关的概念简单来说,网关就是一个网络连接到另外一个网络的...

Spring Boot 自动装配原理剖析

前言在这瞬息万变的技术领域,比了解技术的使用方法更重要的是了解其原理及应用背景。以往我们使用SpringMVC来构建一个项目需要很多基础操作:添加很多jar,配置web.xml,配置Spr...

疯了!Spring 再官宣惊天大漏洞

Spring官宣高危漏洞大家好,我是栈长。前几天爆出来的Spring漏洞,刚修复完又来?今天愚人节来了,这是和大家开玩笑吗?不是的,我也是猝不及防!这个玩笑也开的太大了!!你之前看到的这个漏洞已...

「架构师必备」基于SpringCloud的SaaS型微服务脚手架

简介基于SpringCloud(Hoxton.SR1)+SpringBoot(2.2.4.RELEASE)的SaaS型微服务脚手架,具备用户管理、资源权限管理、网关统一鉴权、Xss防跨站攻击、...

SpringCloud分布式框架&amp;分布式事务&amp;分布式锁

总结本文承接上一篇SpringCloud分布式框架实践之后,进一步实践分布式事务与分布式锁,其中分布式事务主要是基于Seata的AT模式进行强一致性,基于RocketMQ事务消息进行最终一致性,分布式...

SpringBoot全家桶:23篇博客加23个可运行项目让你对它了如指掌

SpringBoot现在已经成为Java开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成。本项目对目前Web开发中常用的各个技术,通过和SpringBoot的集成,并且对各种技术通...

开发好物推荐12之分布式锁redisson-sb

前言springboot开发现在基本都是分布式环境,分布式环境下分布式锁的使用必不可少,主流分布式锁主要包括数据库锁,redis锁,还有zookepper实现的分布式锁,其中最实用的还是Redis分...

拥抱Kubernetes,再见了Spring Cloud

相信很多开发者在熟悉微服务工作后,才发现:以为用SpringCloud已经成功打造了微服务架构帝国,殊不知引入了k8s后,却和CloudNative的生态发展脱轨。从2013年的...

Zabbix/J监控框架和Spring框架的整合方法

Zabbix/J是一个Java版本的系统监控框架,它可以完美地兼容于Zabbix监控系统,使得开发、运维等技术人员能够对整个业务系统的基础设施、应用软件/中间件和业务逻辑进行全方位的分层监控。Spri...

SpringBoot+JWT+Shiro+Mybatis实现Restful快速开发后端脚手架

作者:lywJee来源:cnblogs.com/lywJ/p/11252064.html一、背景前后端分离已经成为互联网项目开发标准,它会为以后的大型分布式架构打下基础。SpringBoot使编码配置...

取消回复欢迎 发表评论: