数据库表约束

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SQL表约束

约束

数据类型是限制我们可以在表里存储什么数据的一种方法。不过,对于许多应用来说,这种限制实在是太粗糙了。比如,一个包含产品价格的字段应该只接受正数。但是没有哪种标准数据类型只接受正数。另外一个问题是你可能需要根据其它字段或者其它行的数据来约束字段数据。比如,在一个包含产品信息的表中,每个产品编号都应该只有一行。

对于这些问题,SQL 允许你在字段和表上定义约束。约束允许你对数据施加任意控制。如果用户企图在字段里存储违反约束的数据,那么就会抛出一个错误。这种情况同时也适用于数值来自缺省值的情况。

5.3.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)

);我们还要注意的是,当约束表达式计算结果为NULL 的时候,检查约束会被认为是满足条件的。因为大多数表达式在含有NULL 操作数的时候结果都是NULL ,所以这些约束不能阻止字段值为NULL 。要确保一个字段值不为NULL ,可以使用下一节介绍的非空约束。

5.3.2. 非空约束

非空约束只是简单地声明一个字段必须不能是NULL 。下面是一个例子:

CREATE TABLE products (

product_no integer NOT NULL,

name text NOT NULL,

price numeric

);一个非空约束总是写成一个字段约束。非空约束在功能上等效于创建一个检查约束CHECK (column_name IS NOT NULL) ,但在PostgreSQL 里,创建一个明确的非空约束效率更高。缺点是你不能给它一个明确的名字。

当然,一个字段可以有多个约束。只要一个接着一个写就可以了:

CREATE TABLE products (

product_no integer NOT NULL,

name text NOT NULL,

price numeric NOT NULL CHECK (price > 0)

);它们的顺序无所谓。顺序并不影响约束检查的顺序。

NOT NULL 约束有个相反的约束:NULL 约束。它并不意味着该字段必须是空,因为这样的字段也没用。它只是定义了该字段可以为空的这个缺省行为。在SQL 标准里没有定义NULL 约束,因此不应该在可移植的应用中使用它。在PostgreSQL 里面增加这个约束只是为了和其它数据库系统兼容。不过,有些用户喜欢它,因为这个约束可以让他们很容易在脚本文件里切换约束。比如,你可以从下面这样开始

CREATE TABLE products (

product_no integer NULL,

name text NULL,

price numeric NULL

);然后在需要的时候插入NOT 关键字。

【提示】在大多数数据库设计里,主要的字段都应该标记为非空。

5.3.3. 唯一约束

唯一约束保证在一个字段或者一组字段里的数据与表中其它行的数据相比是唯一的。它的语法是:

CREATE TABLE products (

product_no integer UNIQUE,

name text,

price numeric

);上面是写成字段约束,下面这个则写成表约束:

CREATE TABLE products (

相关文档
最新文档