概念性——了解 SQL 约束

news2024/12/28 8:54:45

前些天发现了一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站。

概念性——了解 SQL 约束

介绍

在设计数据库时,有时我们可能希望对某些列中允许的数据进行限制。例如,如果我们要创建一个保存摩天大楼信息的表,我们可能希望保存每栋建筑物高度的列禁止出现负值。

关系数据库管理系统 (RDBMS) 允许我们控制将哪些数据添加到带有约束的表中。约束是一种特殊规则,适用于一个或多个列(或整个表),它限制可以对表数据进行的更改(无论是通过 INSERTUPDATEDELETE)。

本文将详细回顾什么是约束以及它们在 RDBMS 中的使用方式。它还将逐步介绍 SQL 标准中定义的五个约束,并解释它们各自的功能。

什么是约束?

在 SQL 中,约束是应用于列或表的任何规则,用于限制可以输入的数据。每当我们尝试执行更改表中保存的数据的操作(例如INSERTUPDATEDELETE语句)时,RDBMS 都会测试该数据是否违反任何现有约束,如果是,则返回错误。

数据库管理员通常依靠约束来确保数据库遵循一组定义的业务规则。在数据库的上下文中,业务规则是企业或其他组织遵循的任何策略或过程,并且其数据也必须遵守。例如,假设我们正在构建一个数据库来对客户的商店库存进行编目。如果客户指定每个产品记录应具有唯一的标识号,我们可以创建一个带有UNIQUE约束的列,以确保该列中没有两个条目相同。

约束也有助于维护数据完整性。数据完整性是一个广义术语,通常用于根据特定用例描述数据库中保存的数据的整体准确性、一致性和合理性。数据库中的表通常密切相关,一个表中的列依赖于另一个表中的值。由于数据输入通常容易出现人为错误,因此约束在这种情况下很有用,因为它们可以帮助确保错误输入的数据不会影响此类关系,从而损害数据库的数据完整性。

想象一下,我们正在设计一个包含两个表的数据库:一个用于列出学校当前的学生,另一个用于列出该学校篮球队的成员。我们可以FOREIGN KEY对篮球队表中引用学校表中的列的列应用约束。这将通过要求团队表中的任何条目引用学生表中的现有条目来建立两个表之间的关系。

用户在首次创建表时定义约束,或者稍后使用语句添加约束,ALTER TABLE只要它不与表中已有的任何数据冲突即可。当我们创建约束时,数据库系统将自动为其生成一个名称,但在大多数 SQL 实现中,我们可以为任何约束添加自定义名称。这些名称用于ALTER TABLE在更改或删除语句时引用语句中的约束。

SQL 标准正式定义了五个约束:

  • PRIMARY KEY
  • FOREIGN KEY
  • UNIQUE
  • CHECK
  • NOT NULL

注意:许多 RDBMS 都包含DEFAULT关键字,该关键字用于定义列的默认值,除非NULL在插入行时未指定值。其中一些数据库管理系统的文档称为DEFAULT约束,因为它们的 SQL 实现使用DEFAULT类似于UNIQUE或 等约束的语法CHECK。但是,DEFAULT从技术上讲,这不是一个约束,因为它不限制可以在列中输入哪些数据。

现在我们已经大致了解了如何使用约束,让我们仔细看看这五个约束中的每一个。

PRIMARY KEY

PRIMARY KEY约束要求给定列中的每个条目既唯一又不唯一NULL,并允许我们使用该列来标识表中的每个单独行

在关系模型中,是表中的一列或一组列,其中每个值都保证是唯一的并且不包含任何NULL值。主键是一种特殊的键,其值用于标识表中的各个行,构成主键的列可用于在数据库的其余部分中标识该表。

这是关系数据库的一个重要方面:使用主键,用户不需要知道他们的数据在计算机上的物理存储位置,他们的 DBMS 可以跟踪每条记录并临时返回它们。反过来,这意味着记录没有定义的逻辑顺序,用户可以按任何顺序或通过他们希望的任何过滤器返回数据。

我们可以在 SQL 中使用约束创建主键,该约束本质上是和约束PRIMARY KEY的组合。定义主键后,DBMS 将自动创建与其关联的*索引。*索引是一种数据库结构,有助于更快地从表中检索数据。与教科书中的索引类似,查询只需检查索引列中的条目即可找到关联的值。这使得主键可以充当表中每一行的标识符。

一张表只能有一个主键,但与常规键一样,主键可以包含多个列。话虽如此,主键的一个定义特征是它们仅使用唯一标识表中每一行所需的最小属性集。为了说明这个想法,想象一个使用以下三列存储有关学校学生信息的表:

  • studentID:用于保存每个学生唯一的身份证号码
  • firstName:用于保存每个学生的名字
  • lastName:用于保存每个学生的姓氏

学校里的一些学生可能会共用一个名字,从而使该firstName列成为一个会重复的主键选择。对于其它列来说也是如此。

FOREIGN KEY

FOREIGN KEY约束要求给定列中的每个条目必须已存在于另一个表的特定列中。

如果我们有两个表想要相互关联,一种方法是使用约束定义外键FOREIGN KEY。外是一个表(“子”表)中的一列,其值来自另一个表(“父”)中的键。这是表达两个表之间关系的一种方式:FOREIGN KEY约束要求它所应用的列中的值必须已经存在于它引用的列中。

下图突出显示了两个表之间的这种关系:一个用于记录公司员工的信息,另一个用于跟踪公司的销售情况。在此示例中,表的主键EMPLOYEES由表的外键引用SALES

EMPLOYEE 表的主键如何充当 SALES 表的外键的图表示例

如果我们尝试向子表添加记录,并且在外键列中输入的值在父表的主键中不存在,则插入语句将无效。这有助于维护关系级完整性,因为两个表中的行始终正确关联。

通常,表的外键是父表的主键,但情况并非总是如此。在大多数 RDBMS 中,父表中应用了UNIQUEPRIMARY KEY约束的任何列都可以由子表的外键引用。

UNIQUE

UNIQUE约束禁止将任何重复值添加到给定列。

顾名思义,UNIQUE约束要求给定列中的每个条目都是唯一值。任何尝试添加已出现在列中的值都将导致错误。

UNIQUE约束对于强制表之间的一对一关系很有用。如前所述,我们可以使用外键在两个表之间建立关系,但表之间可以存在多种关系:

  • 一对一:如果父表中的行与子表中的一行且仅一行相关,则称两个表具有一对一关系
  • 一对多:在多对多关系中,父表中的一行可以与子表中的多行相关,但子表中的每一行只能与父表中的一行相关
  • 多对多:如果父表中的行可以与子表中的多行相关,反之亦然,则称两者具有多对多关系

UNIQUE通过向已应用约束的列添加约束FOREIGN KEY,可以确保父表中的每个条目在子表中只出现一次,从而在两个表之间建立一对一的关系。

UNIQUE请注意,我们可以在表级别和列级别定义约束。当在表级别定义时,UNIQUE约束可以应用于多个列。在这种情况下,约束中包含的每一列都可以有重复的值,但每一行必须在受约束的列中具有唯一的值组合。

CHECK

约束CHECK定义了对列的要求(称为谓词),其中输入的每个值都必须满足该要求。

CHECK约束谓词以表达式的形式编写,可以计算为TRUEFALSE或潜在的UNKNOWN。如果我们尝试在具有约束的列中输入一个值CHECK,并且该值导致谓词计算为TRUEor UNKNOWN(对于NULL值会发生这种情况),则操作将会成功。但是,如果表达式解析为FALSE,它将失败。

CHECK谓词通常依赖于数学比较运算符(例如<, >, <=, OR >=)来限制允许进入给定列的数据范围。例如,CHECK约束的一种常见用途是在负值没有意义的情况下防止某些列保留负值,如下例所示。

CREATE TABLE语句创建一个表,该表productInfo以每个产品的名称、标识号和价格的列命名。由于产品的价格为负数是没有意义的,因此此语句对该列施加了约束,CHECKprice确保它仅包含正值:

CREATE TABLE productInfo (
productID int,
name varchar(30),
price decimal(4,2)
CHECK (price > 0)
);

并非每个CHECK谓词都必须使用数学比较运算符。通常,我们可以在谓词中使用任何可计算为TRUEFALSE、 或 的SQL 运算符,包括UNKNOWNCHECKLIKEBETWEEN 等。某些 SQL 实现(但不是全部)甚至允许我们在谓词中包含子查询。但请注意,大多数实现不允许我们在谓词中引用另一个表。

NOT NULL

NOT NULL约束禁止将任何NULL值添加到给定列。

在大多数 SQL 实现中,如果添加一行数据但没有为特定列指定值,数据库系统将默认将缺失的数据表示为NULL。在 SQL 中,NULL是一个特殊关键字,用于表示未知、缺失或未指定的值。然而,NULL它本身并不是一个值,而是一个未知值的状态

顾名思义,该NOT NULL约束防止给定列中的任何值成为NULL。这意味着对于任何具有NOT NULL约束的列,在插入新行时必须为其指定一个值。否则,INSERT操作将会失败。

结论

对于任何想要设计具有高水平数据完整性和安全性的数据库的人来说,约束都是必不可少的工具。通过限制输入列中的数据,我们可以确保正确维护表之间的关系,并且数据库遵守定义其用途的业务规则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1415297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT发生弹出警告窗口

QTC开发程序弹出警告窗口&#xff0c;如上图 实施代码&#xff1a; #include <QMessageBox> int main() {// 在发生错误的地方QMessageBox::critical(nullptr, "错误", "发生了一个错误&#xff0c;请检查您的操作。");}上面的文字可以更改&#x…

python实现的简化版构建Kdtree(k=2)

Python Kdtree 使用示例 文章目录 Python Kdtree 使用示例一、关于 KDTree二、关于最近邻搜索三、复杂度分析四、python实现的简化版构建k-d tree&#xff08;k2&#xff09; 一、关于 KDTree 点云数据主要是&#xff0c; 表征 目标表面 的海量点集合&#xff0c; 并不具备传统…

【云原生】Docker私有仓库搭建以及四大容器重启策略

目录 一、registry私有仓库 步骤一&#xff1a;先拉取registry的镜像 步骤二&#xff1a;修改docker的配置文件重启 步骤三&#xff1a;基于registry镜像启动一个容器&#xff0c;可以设置为always重启策略 步骤四&#xff1a;修改想要上传的镜像的标签并上传验证 步骤五&…

vulnhub靶场之Five86-2

一.环境搭建 1.靶场描述 Five86-2 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing. The ultimate goal of this challenge is to get root and to read the one and only flag. Linux skills and fa…

LVGL移植准备

一.LVGL移植关键&#xff08;框架&#xff09; 显示驱动&#xff1a;实现与目标平台兼容的显示驱动程序&#xff0c;包括初始化显示设备、绘制像素和设置显示区域等功能。确保与LVGL库进行交互的正确性和有效性。 输入设备驱动&#xff1a;适配目标平台的输入设备驱动程序&…

世界渲染大赛多久一届?

世界渲染大赛&#xff0c;又名世界3D渲染挑战赛&#xff0c;是国外艺术家Pwnisher开启的知名赛事&#xff0c;非常受欢迎。在这个比赛中&#xff0c;你可以看到世界各地不同艺术家进行的创意和主题比拼&#xff0c;有极高的欣赏价值和审美标准。 那么这个比赛举办时间是多少呢&…

C#反射详解

一、反射是什么 1、C#编译运行过程 高级语言->编译->dll/exe文件->CLR/JIT->机器码 2、原理解析 metadata&#xff1a;元数据数据清单&#xff0c;记录了dll中包含了哪些东西,是一个描述。 IL&#xff1a;中间语言&#xff0c;编译把高级语言编译后得到的C#中…

JS之隐式转换与布尔判定

大家思考一下 [ ] [ ] &#xff1f; 答案是空字符串 为什么呢&#xff1f; 当做加法运算的时候&#xff0c;发现左右两端存在非原始类型&#xff0c;也就是引用类型对象&#xff0c;就会对对象做隐式类型转换 如何执行的&#xff1f;或者说怎么查找的&#xff1f; 第一步&…

网络安全02--负载均衡下的webshell连接

目录 一、环境准备 1.1ubentu虚拟机一台&#xff0c;docker环境&#xff0c;蚁剑 1.2环境压缩包&#xff08;文件已上传资源&#xff09;&#xff1a; 二、开始复原 2.1上传ubentu&#xff1a; 2.2解压缩 2.3版本20没有docker-compose手动下载&#xff0c;包已上传资源 …

netty源码前置一:Nio

NIO算是实现Reactor设计模式&#xff08;单Selector 单工作线程&#xff09;底层window用的是select&#xff0c;linux用的是epoll 网络NIO代码实现&#xff1a; public NIOServer(int port) throws Exception {selector Selector.open();serverSocket ServerSocketChannel.…

逻辑回归(Logistic Regression)和正则化

1.分类问题 案例&#xff1a; 在分类问题中&#xff0c;我们尝试预测的是结果是否属于某一个类&#xff08;例如正确或错误&#xff09;。分类问题的例子有&#xff1a;判断一封电子邮件是否是垃圾邮件&#xff1b;判断一次金融交易是否是欺诈&#xff1b;之前我们也谈到了肿瘤…

Python网络爬虫实战——实验4:Python爬虫代理的使用

【实验内容】 本实验主要介绍在爬虫采集数据的过程中代理的使用。 【实验目的】 1、掌握代理使用的基本场景&#xff1b; 2、解决IP封锁问题&#xff1b; 3、提高爬虫访问效率&#xff1b; 【实验步骤】 步骤1选择代理服务提供商 步骤2配置爬虫使用代理 步骤3 采集数据生成…

Ubuntu添加AppImage到桌面及应用程序菜单

将AppImage添加到桌面&#xff0c;以PicGo为例 效果&#xff1a; 在桌面创建PicGo.desktop文件&#xff0c;输入以下内容&#xff1a; [Desktop Entry] EncodingUTF-8 TypeApplication #应用名称 NamePicGo #图标路径 Icon/usr/local/AppImage/icons/PicGo.png #启动是否开启…

cmake设置Debug版本和Release版本的输出路径

项目背景&#xff1a;指定可执行文件和动态库输出路径都在bin目录文件夹下&#xff0c;由于项目中存在osg插件&#xff0c;然后我在项目中需要重写osg的插件&#xff0c;这时候就会遇到指定输出路径的问题&#xff0c;由于需要输出到osgPlugins-3.6.5文件夹下&#xff0c;所以使…

嘿嘿,vue之输出土味情话

有点好玩&#xff0c;记录一下。通过按钮调用网站接口&#xff0c;然后解构数据输出土味情话。 lovetalk.vue: <!--vue简单框架--> <template> <!-- 这是一个div容器&#xff0c;用于显示土味情话 --> <div class"talk"> <!-- 当点…

【现代密码学基础】详解完美安全与香农定理

目录 一. 介绍 二. 完美安全的密钥与消息空间 三. 完美安全的密钥长度 四. 最优的完美安全方案 五. 香农定理 &#xff08;1&#xff09;理论分析 &#xff08;2&#xff09;严格的正向证明 &#xff08;3&#xff09;严格的反向证明 六. 小结 一. 介绍 一次一密方案…

正则匹配 | 正则实际应用探索分享

这并不是一篇教正则基础的文章&#xff0c;其正则式不能对您进行使用后的结果负责&#xff0c;请以研究的眼光看待本篇文章。 技术就是懒人为了更好的懒才会想办法搞的东西&#xff0c;我最近因为某些原因需要频繁删除注释 我就想到通过替换的正则功能快速删除文件中的简单注…

Qslog开源库使用

Qslog源码下载地址&#xff1a;https://github.com/victronenergy/QsLog 1.QSLOG使用方式 &#xff08;1&#xff09;源码集成 在你的工程中&#xff0c;直接包含QsLog.pri文件&#xff0c;进行源码集成。当然你也可以包含QsLog.pri后&#xff0c;编译为xx.dll&#xff0c;在…

数据可视化练习

文章目录 试题示例 试题示例 绘制下图所示的表格 根据下表的数据&#xff0c;将班级名称一列作为x轴的刻度标签&#xff0c;将男生和女生两列的数据作为刻度标签对应的数值&#xff0c;使用bar()函数绘制下图所示的柱形图。 方式一 import numpy as np import matplotlib.p…

CUDA编程- - GPU线程的理解 thread,block,grid - 再次学习

GPU线程的理解 thread,block,grid 一、从 cpu 多线程角度理解 gpu 多线程1、cpu 多线程并行加速2、gpu多线程并行加速2.1、cpu 线程与 gpu 线程的理解&#xff08;核函数&#xff09;2.1.1 、第一步&#xff1a;编写核函数2.1.2、第二步&#xff1a;调用核函数&#xff08;使用…