关系模型的数据完整性主要是为了保证数据不会被破坏,具体有可以分为域完整性、实体完整性、参照完整性和用户定义完整性,其中用户定义完整性是指用户在具体的应用环境下对数据库提出的约束要求。本小节主要关注SQL语言中关于域完整性、实体完整性和参照完整性的实现方法,如表2-6所示。
表2-6 基本表的数据组织形式
| 名称 | 方法 | 描述 |
| 域完整性 | NULL约束 | 可以指定一个列中的值是否可以为NULL |
| CHECK约束 | 用来检查输入的值是否满足某一约束条件 | |
| DEFAULT约束 | 如果输入数据中没有指定该列具体的值,可以直接使用DEFAULT约束指定的默认值 | |
| 实体完整性 | 主键 | 指定的键值组合在集合内只能有唯一的一个值(不可以包含NULL值) |
| UNIQUE约束 | 指定的键值组合在集合内只能有唯一的一个值(可以包含NULL值) | |
| 参照完整性 | 外键 | 指定的键值组合和外部的键值相对应 |
在创建基本表的同时,还可以指定表中数据完整性约束,例如在创建warehouse基本表时,通过分析可以得到如下结论:
不同的warehouse信息必须有不同的w_id,且w_id不能为NULL。
warehouse必须有具体的名字,不能为NULL。
warehouse所在的街区地址的长度不能为0。
warehouse所在的国家默认为‘CN’。
因此可以在创建warehouse基本表时指定如下约束:
例2-7:创建带有完整性约束的基本表,具体语句如下:
CREATE TABLE warehouse
(
w_id SMALLINT PRIMARY KEY,
w_name VARCHAR(10) NOT NULL,
w_street_1 VARCHAR (20) CHECK (LENGTH(w_street_1) <> 0),
w_street_2 VARCHAR (20) CHECK (LENGTH(w_street_1) <>0),
w_city VARCHAR (20),
w_state CHAR(2) DEFAULT ‘CN’,
w_zip CHAR (9),
w_tax DECIMAL(4,2),
w_ytd DECIMAL (12,2)
);
如果向warehouse基本表中写入不符合完整性约束的值,那么数据不能被写入,数据库会提示错误。
例2-8:向w_name列中写入NULL值,不符合完整性约束,具体语句如下:
INSERT INTO warehouse VALUES(1, NULL, '', '', NULL, 'CN', NULL, 1.0, 1.0);
ERROR: null value in column "w_name" violates not-null constraint
DETAIL: Failing row contains (1, null, null, null, null, CN, null, null, null).
除了在列定义之后指定完整性约束之外,还可以在使用表级的完整性约束来指定。
例2-9:在表定义上指定完整性约束,注意NULL约束只能在列定义上指定,具体语句如下:
CREATE TABLE warehouse
(
w_id SMALLINT,
w_name VARCHAR(10) NOT NULL, -- 设置NULL约束
w_street_1 VARCHAR (20),
w_street_2 VARCHAR (20),
w_city VARCHAR (20),
w_state CHAR(2) DEFAULT ‘CN’, -- 设置默认值
w_zip CHAR (9),
w_tax DECIMAL(4,2),
w_ytd DECIMAL (12,2),
CONSTRAINT w_id_pkey PRIMARY KEY(w_id), --增加主键约束
--增加CHECK约束
CONSTRAINT w_street_1_chk CHECK(LENGTH(w_street_1) < 100),
CONSTRAINT w_street_2_chk CHECK(LENGTH(w_street_2) < 100),
);
当一个表中的某一个列或一组列恰好引用的是另一个表的主键(或具有唯一性)时,可以考虑将其定义为外键,外键表示两个表之间的相互的关联关系,包含主键的表通常可以成为主表,而包含外键的表则可以被成为从表。外键的定义可以直接在属性上定义,也可以在基本表的创建语句中定义,两种方法本质上没有区别。
例2-10:新订单表(new_orders)中引用了仓库表(warehouse)的列做外键,具体语句如下:
CREATE TABLE new_orders
(
no_o_id INTEGER NOT NULL,
no_d_id SMALLINT NOT NULL,
no_w_id SMALLINT NOT NULL REFERENCE warehouse(w_id)
);
CREATE TABLE new_orders
(
no_o_id INTEGER NOT NULL,
no_d_id SMALLINT NOT NULL,
no_w_id SMALLINT NOT NULL,
FOREIGN KEY (no_w_id) REFERENCES warehouse(w_id)
);
除了在创建基本表的同时指定完整性约束之外,还可以通过ALTER TABLE语句对完整性约束进行修改。
例2-11:在基本表warehouse上增加主键列,具体语句如下:
ALTER TABLE warehouse ADD PRIMARY KEY(w_id);
例2-12:在基本表warehouse上增加CHECK约束,具体语句如下:
ALTER TABLE warehouse ADD CHECK (LENGTH(w_street_1) < 100);
例2-13:在基本表warehouse上增加外键引用,具体语句如下:
ALTER TABLE warehouse ADD FOREIGN KEY (no_w_id) REFERENCES warehouse(w_id);
例2-14:在基本表new_orders上增加唯一列,具体语句如下:
ALTER TABLE new_orders ADD UNIQUE (no_o_id, no_d_id, no_w_id);




