专业只做数据库实训和认证的品牌机构

微信公众号新浪微博
免费咨询电话:400-0909-964
当前位置: 网站首页 > postgresql > pg概述 > PostgreSQL教程-数据定义-检查约束

PostgreSQL教程-数据定义-检查约束

文章来源: 更新时间:2021/10/9 10:24:23

在线老师点击咨询:

最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!

我要咨询

5.4.1. 检查约束

一个检查约束是最普通的约束类型。它允许我们指定一个特定列中的值必须要满足一个布尔表达式。例如,为了要求正值的产品价格,我们可以使用:

CREATE TABLE products (

product_no integer,

name text,

price numeric CHECK (price > 0)

);

如你所见,约束定义就和默认值定义一样跟在数据类型之后。默认值和约束之间的顺序没有影响。一个检查约束有关键字CHECK以及其后的包围在圆括号中的表达式组成。检查约束表达式应该涉及到被约束的列,否则该约束也没什么实际意义。

我们也可以给与约束一个独立的名称。这会使得错误消息更为清晰,同时也允许我们在需要更改约束时能引用它。语法为:

CREATE TABLE products (

product_no integer,

name text,

price numeric CONSTRAINT positive_price CHECK (price > 0)

);

要指定一个命名的约束,请在约束名称标识符前使用关键词CONSTRAINT,然后把约束定义放在标识符之后(如果没有以这种方式指定一个约束名称,系统将会为我们选择一个)。

一个检查约束也可以引用多个列。例如我们存储一个普通价格和一个打折后的价格,而我们希望保证打折后的价格低于普通价格:

CREATE TABLE products (

product_no integer,

name text,

price numeric CHECK (price > 0),

discounted_price numeric CHECK (discounted_price > 0),

CHECK (price > discounted_price)

);

前两个约束看起来很相似。第三个则使用了一种新语法。它并没有依附在一个特定的列,而是作为一个独立的项出现在逗号分隔的列列表中。列定义和这种约束定义可以以混合的顺序出现在列表中。

我们将前两个约束称为列约束,而第三个约束为表约束,因为它独立于任何一个列定义。列约束也可以写成表约束,但反过来不行,因为一个列约束只能引用它所依附的那一个列(PostgreSQL并不强制要求这个规则,但是如果我们希望表定义能够在其他数据库系统中工作,那就应该遵循它)。上述例子也可以写成:

CREATE TABLE products (

product_no integer,

name text,

price numeric,

CHECK (price > 0),

discounted_price numeric,

CHECK (discounted_price > 0),

CHECK (price > discounted_price)

);

甚至是:

CREATE TABLE products (

product_no integer,

name text,

price numeric CHECK (price > 0),

discounted_price numeric,

CHECK (discounted_price > 0 AND price > discounted_price)

);

这只是口味的问题。

表约束也可以用列约束相同的方法来指定名称:

CREATE TABLE products (

product_no integer,

name text,

price numeric,

CHECK (price > 0),

discounted_price numeric,

CHECK (discounted_price > 0),

CONSTRAINT valid_discount CHECK (price > discounted_price)

);

需要注意的是,一个检查约束在其检查表达式值为真或空值时被满足。因为当任何操作数为空时大部分表达式将计算为空值,所以它们不会阻止被约束列中的空值。为了保证一个列不包含空值,可以使用下一节中的非空约束。

注意

PostgreSQL不支持引用表数据以外的要检查的新增或更新的行的CHECK约束。 虽然违反此规则的CHECK约束在简单测试中看起来能工作,它不能保证数据库不会达到约束条件为假(false)的状态(由于涉及的其他行随后发生了更改)。 这将导致数据库转储和重新加载失败。 即使完整的数据库状态与约束一致,重新加载也可能失败,因为行未按照满足约束的顺序加载。 如果可能的话,使用UNIQUE, EXCLUDE,或 FOREIGN KEY约束以表示跨行和跨表限制。

如果你希望的是在插入行时的时候对其他行进行一次性检查,而不是持续维护的一致性保证,一个自定义的 trigger 可以用于实现这个功能。 (此方法避免了转储/重新加载问题,因为pg_dump不会重新安装触发器直到重新加载数据之后,因此不会在转储/重新加载期间强制执行检查。)注意

PostgreSQL假定CHECK约束的条件是不可变的,也就是说,它们始终为同一输入行提供相同的结果。 这个假设是仅在插入或更新行时,而不是在其他时间检查CHECK约束的原因。 (上面关于不引用其他表数据的警告实际上是此限制的特殊情况。)

打破此假设的常见方法的一个示例是在 CHECK表达式中引用用户定义的函数,然后更改该函数的行为。 PostgreSQL不会禁止那样,但它不会注意到现在表中是否有行违反了CHECK约束。这将导致后续数据库转储和重新加载失败。 处理此类更改的建议方法是删除约束(使用ALTER TABLE),调整函数定义,然后重新添加约束,从而对所有表行进行重新检查。

本文地址:http://www.cuug.com.cn/postgresql/pggaishu/28999587024.html 转载请注明!


在线预约 抢先报名 获取课程排期

Oracle培训机构

金牌讲师<>

冉乃纲-老师CUUG金牌讲师
冉老师 CUUG金牌讲师 Oracle及RedHat高级讲师、Unix/Linux 资深专家...[详细了解老师]

免费咨询上课流程 客服在线中

陈卫星-老师CUUG金牌讲师
陈老师 CUUG金牌讲师 精通Oracle管理、备份恢复、性能优化 11年Ora...[详细了解老师]

免费咨询上课流程 客服在线中

选学校如何选择适合自己的学校

CUUG -CHINA UNIX USER GROUP,是国际UNIX组织UNIFORUM的中国代表,是国内悠久的专业UNIX培训机构,被誉为中国UNIX 的摇篮。多年来,以提高教学质量为本,强调素质教育,积极引进、消化国外的新技术,有效的结合中国....[详情]

一站式服务(从入学到就业一帮到底)

入学

学习

就业

实操

食宿
地址:北京市海淀区田村山南路35号院17号楼
课程咨询:010-59426307 010-59426319 400-0909-964
企业服务:137 1818 8639(陈经理)
部分信息来源于网络,如有错误请联系指正!
版权所有@北京神脑资讯技术有限公司 (CUUG,中国UNIX用户协会) Copyright 2016 ALL Rights Reserved 京ICP备11008061号-1