openGauss学习笔记-26 openGauss 高级数据管理-约束

2023-11-14

openGauss学习笔记-26 openGauss 高级数据管理-约束

约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。如果存在违反约束的数据行为,行为会被约束终止。

约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。

约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。

openGauss中常用的约束如下:

  • NOT NULL:指示某列不能存储NULL值。
  • UNIQUE:确保某列的值都是唯一的。
  • PRIMARY KEY:NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
  • FOREIGN KEY: 保证一个表中的数据匹配另一个表中的值的参照完整性。
  • CHECK: 保证列中的值符合指定的条件。

26.1 NOT NULL约束

创建表时,如果不指定约束,默认值为NULL,即允许列插入空值。如果您不想某列存在NULL值,那么需要在该列上定义NOT NULL约束,指定在该列上的值不允许存在NULL值。插入数据时,如果该列存在NULL值,则会报错,插入失败。

NULL与没有数据是不一样的,它代表着未知的数据。

例如,创建表staff,共有5个字段,其中NAME,ID设置不接受空值。

openGauss=# CREATE TABLE staff(
   ID             INT      NOT NULL,
   NAME           char(8)    NOT NULL,
   AGE            INT     ,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

给表staff插入数据。当ID字段插入空值时,数据库返回报错。

openGauss=# INSERT INTO staff  VALUES (1,'lily',28);
INSERT 0 1
openGauss=# INSERT INTO staff (NAME,AGE) VALUES ('JUCE',28);
ERROR:  null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, JUCE    , 28, null, null).

26.2 UNIQUE约束

UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。

对于唯一约束,NULL被认为是互不相等的。

例如,创建表staff1,表包含5个字段,其中AGE设置为UNIQUE,因此不能添加两条有相同年龄的记录。

openGauss=# CREATE TABLE staff1(
   ID             INT      NOT NULL,
   NAME           char(8)    NOT NULL,
   AGE            INT   NOT NULL  UNIQUE  ,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

给表staff1表插入数据。当字段AGE插入两条一样的数据时,数据库返回报错。

openGauss=# INSERT INTO staff1  VALUES (1,'lily',28);
INSERT 0 1
openGauss=# INSERT INTO staff1 VALUES (2, 'JUCE',28);
ERROR:  duplicate key value violates unique constraint "staff1_age_key"
DETAIL:  Key (age)=(28) already exists.

26.3 PRIMARY KEY

PRIMARY KEY为主键,是数据表中每一条记录的唯一标识。主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。

主键是非空约束和唯一约束的组合。一个表只能声明一个主键。

例如,创建表staff2,其中ID为主键。

openGauss=# CREATE TABLE staff2(
   ID             INT     PRIMARY KEY     ,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "staff2_pkey" for table "staff2"
CREATE TABLE

26.4 FOREIGN KEY

FOREIGN KEY即外键约束,指定列(或一组列)中的值必须匹配另一个表的某一行中出现的值。通常一个表中的FOREIGN KEY指向另一个表中的 UNIQUE KEY(唯一约束的键),即维护了两个相关表之间的引用完整性。

例如,创建表staff3,包含5个字段。

openGauss=# CREATE TABLE staff3(
   ID             INT    PRIMARY KEY  NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

创建一张DEPARTMENT表,并添加3个字段,其中EMP_ID为外键,参照staff3的ID字段:

openGauss=# CREATE TABLE DEPARTMENT(
   ID INT PRIMARY KEY      NOT NULL,
   DEPT           CHAR(50) NOT NULL,
   EMP_ID         INT      references staff3(ID)
);

FOREIGN Key在MySQL兼容性下,外键可以关联非唯一性索引。即一个表中的FOREIGN Key指向另一个表中的 Non-unique KEY(非唯一约束的键)。 注: 如果在MySQL兼容性下,定义外键指定ON UPDATE | DELETE CASCADE时,在非唯一性索引中,非唯一索引字段存在多个元组时,只要dml其中一行数据,则会触发外键表里关联的字段全部修改。但如果字段为NULL时,则不触发外键关联的字段做对应的修改。

MySQL兼容性需要安装dolphin插件才可生效。

openGauss=# create table t1(id int, name varchar);
CREATE TABLE
openGauss=# create table t2(id int, a_id int);
CREATE TABLE
-- create non-unique index on table t1.
openGauss=# create index a_index_1 on t1(id);
CREATE INDEX
-- create foreign key on non-unique index
openGauss=# alter table t2 add constraint t2_fk foreign key (a_id) references t1(id);
ALTER TABLE
openGauss=# \d t1
           Table "public.t1"
 Column |       Type        | Modifiers 
--------+-------------------+-----------
 id     | integer           | 
 name   | character varying | 
Indexes:
    "a_index_1" btree (id) TABLESPACE pg_default
Referenced by:
    TABLE "t2" CONSTRAINT "t2_fk" FOREIGN KEY (a_id) REFERENCES t1(id)

openGauss=# \d t2
      Table "public.t2"
 Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | 
 a_id   | integer | 
Foreign-key constraints:
    "t2_fk" FOREIGN KEY (a_id) REFERENCES t1(id)

openGauss=# insert into t1 values(1,'a'),(2,'b');
INSERT 0 2
openGauss=# select * from t1;
 id | name 
----+------
  1 | a
  2 | b
(2 rows)

openGauss=# insert into t2 values(1,1);
INSERT 0 1
openGauss=# select * from t2;
 id | a_id 
----+------
  1 |    1
(1 row)

openGauss=# insert into t2 values(1,3);
INSERT 0 1
ERROR:  insert or update on table "t2" violates foreign key constraint "t2_fk"
DETAIL:  Key (a_id)=(3) is not present in table "t1".
openGauss=# select * from t2;
 id | a_id 
----+------
  1 |    1
(1 row)

openGauss=# alter table t2 drop constraint t2_fk;
ALTER TABLE
openGauss=# alter table t2 add constraint t2_fk foreign key (a_id) references t1(id) on update cascade;
ALTER TABLE
openGauss=# select * from t1;
 id | name 
----+------
  1 | a
  2 | b
(2 rows)

openGauss=# insert into t1 values(1,'s');
INSERT 0 1
openGauss=# select * from t1;
 id | name 
----+------
  1 | a
  2 | b
  1 | s
(3 rows)

openGauss=# insert into t2 values(2,1);
INSERT 0 1
openGauss=# select * from t2;
 id | a_id 
----+------
  1 |    1
  2 |    1
(2 rows)

openGauss=# update t1 set id = 11 where name = 'a';
UPDATE 1
openGauss=# select * from t1;
 id | name 
----+------
  2 | b
  1 | s
 11 | a
(3 rows)

openGauss=# select * from t2;
 id | a_id 
----+------
  1 |   11
  2 |   11
(2 rows)

openGauss=# update t1 set id =1 where name = 'a';
UPDATE 1
openGauss=# alter table t2 drop constraint t2_fk;
ALTER TABLE
openGauss=# alter table t2 add constraint t2_fk foreign key (a_id) references t1(id) on delete cascade;
ALTER TABLE
openGauss=# select * from t1;
 id | name 
----+------
  2 | b
  1 | s
  1 | a
(3 rows)

openGauss=# select * from t2;
 id | a_id 
----+------
  1 |    1
  2 |    1
(2 rows)

openGauss=# delete from t1 where name = 's';
DELETE 1
openGauss=# select * from t1;
 id | name 
----+------
  2 | b
  1 | a
(2 rows)

openGauss=# select * from t2;
 id | a_id 
----+------
(0 rows)

26.5 CHECK约束

CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。

声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。expression表达式中,如果存在“<>NULL”或“!=NULL”,这种写法是无效的,需要写成“is NOT NULL”。

例如,创建表staff4,对字段SALARY新增CHECK约束,确保插入此列数值大于0。

openGauss=# CREATE TABLE staff4(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL    CHECK(SALARY > 0)
);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "staff4_pkey" for table "staff4"
CREATE TABLE

给表staff4插入数据。当字段SALARY插入数据不大于0时,数据库返回报错。

openGauss=# INSERT INTO staff4(ID,NAME,AGE,SALARY) VALUES (2, 'JUCE',16,0);
ERROR:  new row for relation "staff4" violates check constraint "staff4_salary_check"
DETAIL:  N/A

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openGauss学习笔记-26 openGauss 高级数据管理-约束 的相关文章

  • MySQL 中的断言

    我有一个针对大型数据库运行的 SQL 脚本 我想在开始时提出几个简单的查询 作为健全性检查 有没有办法在MySQL中写断言 或者任何类型的 选择 如果它与该值不匹配 则中止整个脚本 一些疯狂的代码 要点是 SET可能会引发 mysql 变量
  • 将列的值添加到 LIKE 语句中?

    我有 3 个标签表 标签类别和使用过的标签 我想要获取所有标签的列表以及已使用标签的计数 所使用标签的格式是每个具有标签的文档 ID 的逗号分隔值 我一直在尝试类似的方法 但无法将tags tag 字段的值插入到LIKE 语句中 SELEC
  • 从存储过程中的动态 SQL 获取结果

    我正在编写一个存储过程 需要在过程中动态构造 SQL 语句以引用传入的表名称 我需要让这个 SQL 语句返回一个结果 然后我可以在整个过程的其余部分中使用该结果 我尝试过使用临时表和所有内容 但我不断收到一条消息 提示我需要声明变量等 例如
  • SQL Server 查询结果集的大小

    SQL Server 中是否有确定结果集中 Mgmt Studio 查询中返回的数据大小 以 MEGS 为单位 您可以打开客户端统计信息 查询菜单 包括客户端统计信息 它给出执行查询时从服务器返回的字节数
  • 使用MySQL计算单个表中借方和贷方的余额

    下面的 MySQL 表包含带有关联金额的借方或贷方 操作 如何选择具有非零 余额 的所有 CLIENT ID 我尝试将表连接到自身以计算所有借方和贷方总额 但有些东西无法正常工作 CLIENT ID ACTION TYPE ACTION A
  • Quartz.NET 设置 MisfireInstruction

    我正在使用 Quartz NET 在 C 中工作 并且在 CronTrigger 上设置失火指令时遇到问题 我正在运行安装了 Quartz DB 的 SQL 后端 我有以下代码 可以很好地创建作业和运行调度程序 IScheduler sch
  • SQL Server 相当于 MySQL 的 USING

    在 MySQL 中 当您连接不同表中具有相同名称的列时 可以在连接中使用关键字 USING 例如 这些查询产生相同的结果 SELECT FROM user INNER JOIN perm USING uid SELECT FROM user
  • 如何在动态查询中将行值连接到列名

    我正在开发一个允许配置问题和答案的应用程序 目前最多可以有 20 个答案 但也可能更少 我的结构如下 问题 ID FormId QuestionText AnswerField 1 1 Name Answer01 2 1 Address A
  • 让 Prometheus 发送 SQL 查询

    我正在尝试使用普罗米修斯 https prometheus io 监视我的 MySQL 数据库 但似乎找不到添加 SQL 查询的区域 例如 我想运行一个返回值的 SQL 查询 然后将该值添加到图表中 发送警报 有没有办法让 Promethe
  • 案例陈述以确定我是否应该结合

    我目前想做某种条件联合 给出以下示例 SELECT age name FROM users UNION SELECT 25 AS age Betty AS name 假设我只想在 用户 计数 gt 2 时合并第二个语句 否则不合并两者 总之
  • 通过将行旋转为动态数量的列来在 MySQL 中创建摘要视图

    我在 MySQL 中有一个表 其中包含以下字段 id company name year state 同一客户和年份有多行 以下是数据示例 id company name year state 1 companyA 2008 1 2 com
  • 使用包含空值列的 WHERE 子句的更新语句

    我正在使用另一个表中的数据更新一个表上的列 这WHERE子句基于多个列 并且某些列为空 根据我的想法 这个空值是什么throwing off你的标准UPDATE TABLE SET X Y WHERE A B陈述 See 这个 SQL 小提
  • 与 FOREIGN KEY 约束冲突

    我有两张桌子 学术界 CREATE TABLE dbo R ACADEMIE ID ACADEMIE dbo IDENTIFIANT NOT NULL LC ACADEMIE CODE dbo LIBELLE COURT NOT NULL
  • ORA-01749: 您不能向自己授予/撤销权限

    我正在运行以下查询RATOR MONITORING授予引用权限的架构RATOR MONITORING CONFIGURATION SMSC GATEWAY表到RATOR MONITORING schema GRANT REFERENCES
  • 当我输入 dateadd 或 datediff 代码时,我总是收到此错误“ORA-00904“DATEADD”无效标识符。”

    我有一个大学项目 并且有一个包含入院和出院日期属性的患者表 我需要删除超过 7 年的记录 我使用了以下代码 delete from patient where dis date gt datedadd yy 7 getdate 我收到错误
  • 如何将整行(在 SQL 中,而不是 PL/SQL 中)传递给存储函数?

    我遇到以下 非常简单 问题 我想编写一个 Oracle SQL 查询 大致如下 SELECT count MyFunc MyTable FROM MyTable GROUP BY MyFunc MyTable 在 PL SQL 中 可以使用
  • ActiveRecord 嵌套 SELECT——我可以在没有手动 SQL 的情况下完成它吗?

    我有一张桌子 上面有 除其他外 一个名字和一个等级 我想返回所有唯一名称的集合 但对于返回的每个名称 我想选择排名最高的行 这很简单 有两个嵌套的 SELECT 语句 SELECT FROM SELECT FROM foo ORDER BY
  • 在 Doctrine DQL 中选择 count() ,并使用左连接多对多单向关系,其中用户没有关系特定组

    情况 我尝试在 DQL 中为不属于特定组的用户选择 count 标准ManyToMany之间的单向关系User and Group实体来自FOSUserBundle and SonataUserBundle 系统 Symfony 2 5 D
  • 将此 MySQL 查询转换为 PyGreSQL

    我正在开发一个 Ruby 应用程序 它使用 mysql 函数 XOR 和 BIT COUNT 不过 我现在需要在运行 PyGreSQL 的 Heroku 上运行该应用程序 我找不到任何可以帮助我的 PyGreSQL 文档 那么任何人都可以翻
  • MySQL 中的 group_concat 性能问题

    我添加了一个group concat到一个查询并杀死了性能 添加之前和之后的解释计划是相同的 所以我对如何优化它感到困惑 这是查询的简化版本 SELECT curRow curRow 1 AS row number docID docTyp

随机推荐

  • linux是一种开源的操作系统,又一个操作系统开源

    导读 9月18日 腾讯宣布开源自主研发的轻量级物联网实时操作系统 TencentOS tiny TencentOS tiny是腾讯面向物联网领域开发的实时操作系统 具有低功耗 低资源占用 模块化 安全可靠等特点 可有效提升物联网终端产品开发
  • 【牛客SQL】SQL7 查找薪水记录超过15次的员工号emp_no以及其对应的记录次数t

    题目描述 描述 有一个薪水表 salaries简况如下 请你查找薪水记录超过15次的员工号emp no以及其对应的记录次数t 以上例子输出如下 题解 本题考察分组GROUP BY和分组过滤HAVING操作 运行时间 17ms 超过52 75
  • Scala入门到精通——第一节 Scala语言初步

    本节主要内容 Scala简介 为什么要学习Scala Scala语言初步 1 Scala简介 Scala Scala Language的简称 语言是一种能够运行于JVM和 Net平台之上的通用编程语言 既可用于大规模应用程序开发 也可用于脚
  • 微信小程序应用”腾讯位置服务路线规划“插件

    1 申请路线规划插件 微信公众平台 微信小程序后台 设置 第三方设置 插件管理 里点击 添加插件 搜索 腾讯位置服务路线规划 选择添加插件即可 2 申请key 调用路线规划插件需要申请腾讯位置服务的服务账号 key是开发者的唯一标识 申请地
  • vue/webpack 引入 cdn 资源

    使用 vue 的 webpack 模版开发 spa 项目时 我们习惯使用 npm install 安装各种组件和依赖到本地 但引入的组件越来越多 打包时可能会导致 app js 过大的问题 对加载很不友好 准确的说 vue webpack
  • 嫖一嫖显示器的Over drive (OD) 功能

    1 背景 如下图 快速运动的画面会产生拖影现象 影响游戏体验 视觉观感 2 产生的原因 当响应时间大于刷新时间的时候 就会产生拖影 因为 上一帧还没有渲染完 又来了新的帧 3 首先明确上面两个时间的概念 3 1 Response time
  • es通过脚本来进行更新某个List字段

    Map
  • 软件测试最新“年薪50万”骗局来了,让我们来康康你们是如何上当受骗的

    小编热衷于收集整理资源 记录踩坑到爬坑的过程 希望能把自己所学 实际工作中使用的技术 学习方法 心得及踩过的一些坑 记录下来 也希望想做软件测试的你一样 通过我的分享可以少走一些弯路 可以形成一套自己的方法 并应用到实际中 小编整理了一些零
  • 【Java】基于哈希表的随机字符替换加密算法

    Java 基于哈希表的随机字符替换加密算法 一 简介 1 1 背景 1 2 目的 二 算法设计 2 1 HashTableCreator类 2 2 MessageEncryptor类 三 算法实现 3 1 HashTableCreator类
  • [UnityUI]UGUI自适应

    关键点 0 自适应的测试 通过设置多种的屏幕大小进行测试 测试时最好要打开Maximize on Play 在屏幕放大的情况下容易观察自适应情况 1 所谓的自适应 就是 a 保持相对位置不变 例如UI设计在屏幕的左上角 那么在各种的分辨率下
  • vue渲染数据时,v-html中的图片如何点击放大 以及 markdowm数据中的图片点击如何放大

    记录一下在部署博客的时候 文章中的内容点击图片不能放大的问题 效果展示 http zfc life sm 我先展示实现的代码 1 template 2 data 3 created 4 methods 上面的代码不是我写的 我只是在原有代码
  • C++实现通讯录管理系统(完整代码)课设或实验

    好久没写文章了 终于结束了满课的前三周以及烦人的考试 可以有多余的时间来自己学习 今天学习了利用C 实现通讯录管理系统 自己手敲了一遍 可以用来当实验题的答案或课设哦 具体的解释在代码注释当中 include
  • Qt中的d指针和q指针

    概述 如果程序从一个以前版本的库动态链接到新版本的库之后 能够继续正常运行 而不需要重新编译 那么我们就说这个库是二进制兼容的 如果一个程序需要重新编译来运行一个新版本的库 但是不需要对程序的源代码进一步的修改 这个库就是源代码兼容的 如果
  • 为什么做弱网测试?怎么做

    为什么要做弱网测试 弱网测试 属于健壮性测试的内容 为什么要做呢 尤其是现在的人们更习惯在地铁里 公交上 甚至是电梯 车库等等的场景里去关注一些新闻 看看小说 直播 玩游戏等等 在这个时候 我们就需要针对这些场景 去关注一下应用的运行状态
  • 尚硅谷-尚品汇项目开发总结(第三天)

    4 Home静态组件的拆分与postman测试接口是否可用 4 1 Home组件的拆分 注意点 HTML CSS 图片 4 2 postman测试接口 5 axios二次封装与配置代理服务器 nprogress进度条插件的使用 5 1 ax
  • 反转链表的四种方法

    目录 1 第一种方法 原地反转 2 第二种方法 利用头插法进行反转链表 3 第三种方法 利用迭代法进行反转链表 4 第四种方法 利用递归法进行反转链表 5 应用 当我们学习链表之后 就要学习一些链表的操作 而反转链表是我们必备技能 这里总结
  • SQL注入详解

    一 sql基础 1 sql注入原理 针对SQL注入的攻击行为可描述为通过用户可控参数中注入SQL语法 破坏原有SQL结构 达到编写程序意料之外结果的攻击行为 其成因可归结为以下两个原理叠加造成 1 程序编写者在处理程序和数据库交互时 使用字
  • stm32 OV7670/摄像头模块颜色区域定位(腐蚀中心算法)

    前两天用到的摄像头模块ov7670 想在摄像头做一个色块识别 查阅了部分资料和教程 发现有用的文章挺多 于是下载了几个demo 学习了一下 感谢一些博主的分享 今天整理一下分享给大家 实现原理 将摄像头的数据读出写入tft屏 读取tft屏幕
  • Qt设置不规则窗体(Mask)

    创建新项目testMask 继承QWidget 添加Qt Resource file文件 添加图片资源 往ui界面中拖入一个label标签部件 标签文字内容设置为空白 widget h ifndef WIDGET H define WIDG
  • openGauss学习笔记-26 openGauss 高级数据管理-约束

    文章目录 openGauss学习笔记 26 openGauss 高级数据管理 约束 26 1 NOT NULL约束 26 2 UNIQUE约束 26 3 PRIMARY KEY 26 4 FOREIGN KEY 26 5 CHECK约束 o