1012.表-约束-检查
1.1 约束
数据类型只是初范的约束。
列的check可以做到具体的约束(满足表达式的布尔值 true/null)
列约束、表约束;都可以指定自定义的约束名(CONSTRAINT),列约束只能是本列。
一个非空约束仅仅指定一个列中不会有空值,作为列约束。
多个列约束顺序没有影响。
数据类型是一种限制能够存储在表中数据类别的方法。但是对于很多应用来说,它们提供的约束太粗糙。
约束让我们能够根据我们的愿望来控制表中的数据。如果一个用户试图在一个列中保存违反一个约束的数据,一个错误会被抛出。即便是这个值来自于默认值定义,这个规则也同样适用。
1.1.1 检查约束
列的check可以做到具体的约束(满足表达式的布尔值 true/null)
列约束、表约束;都可以指定自定义的约束名(CONSTRAINT),列约束只能是本列。
指定一个特定列中的值必须要满足一个布尔表达式。
例如,为了要求正值的产品价格,我们可以使用:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);
约束定义就和默认值定义一样跟在数据类型之后。默认值和约束之间的顺序没有影响。检查约束表达式应该涉及到被约束的列,否则该约束也没什么实际意义。
我们也可以给与约束一个独立的名称。这会使得错误消息更为清晰,同时也允许我们在需要更改约束时能引用它。
CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
);
不指定的话,系统将会为我们选择一个。
一个检查约束也可以引用多个列。例如我们存储一个普通价格和一个打折后的价格,而我们希望保证打折后的价格低于普通价格:
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),
CONSTRAINT valid_discount CHECK (price > discounted_price)
);
一个检查约束在其检查表达式值为真或空值时被满足。因为当任何操作数为空时大部分表达式将计算为空值,所以它们不会阻止被约束列中的空值。
1.1.1 非空约束
一个非空约束仅仅指定一个列中不会有空值。语法例子:
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric
);
一个非空约束总是被写成一个列约束。
一个非空约束等价于创建一个检查约束CHECK (column_name IS NOT NULL),但在PostgreSQL中创建一个显式的非空约束更高效。这种方式创建的非空约束的缺点是我们无法为它给予一个显式的名称。
提示:在大部分数据库中多数列应该被标记为非空。