完整性及约束
数据完整性:
数据完整性是指数据的精确性和可靠性。它是应防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的。SQL Server 提供了一些工具来帮助用户实现数据完整性,其中最主要的是:约束(Constraint)、和触发器(Trigger)。
数据完整性约束主要包括四大类:
实体完整性
域完整性
引用完整性
用户自定义完整性
实体完整性:
实体完整性指的是关系数据库中所有的表都必须有主键,而且表中不允许存在如下的记录。
u 无主键值的记录
u 主键值相同的记录
在SQL Server 中可以通过建立PRIMARY KEY约束、UNIQUE 约束、唯一索引和列的IDENTITY属性等措施来实施实体完整性。
引用完整性:
引用完整性有时也称为参照完整性,引用完整性就是描述实体之间关系的。这种限制一个表中某列的取值受另一个表的某列的取值范围约束的特点就称为引用完整性。在关系数据库中用外键(Foreign key 有时也称为外部关键字)来实现引用完整性。
域完整性
域完整性或语义完整性。确保了只有在某一合法范围内的值才能存储到一列中。可以通过限制数据类型、值的范围和数据格式来实施域完整性。在SQL Server 中可以通过默认值、Foreign KEY、CHECK 等约束来实施域完整性
用户自定义完整性
用户自定义完整性就是针对某一具体应用领域定义的数据约束条件,它反映某一具体应用所涉及的数据必须要满足应用语义的要求。
如check(age between 10 and100)
约束:
约束(Constraint)是Microsoft SQL Server 提供的自动保持数据库完整性的一种方法,定义了可输入表或表的单个列中的数据的限制条件。在SQL Server 中有5 种约束:
主关键字约束(Primary Key Constraint)
外关键字约束(Foreign Key Constraint)
唯一性约束(Unique Constraint)
检查约束(Check Constraint)
缺省约束(Default Constraint)。
主关键字约束(Primary Key Constraint):
主键的作用:
主键是一个表中能标识唯一行的标志(也有其他方法表示唯一行,如唯一列)。主键主要用在查询单调数据,修改单调数据和删除单调数据上。
一般做程序的时候,都将表的主键设置为int 型的可自增的列,这样在编程的时候,很容易区分数据。
主关键字约束中(简称主键约束)指定表的一列或几列的组合的值在表中具有唯一性,即能唯一的指定一行记录。主键约束确保实体完整性。一个表中最多有一个主键.使用PRIMARY KEY约束时,列的空值属性必须定义为NOT NULL。PRIMARY KEY约束可以应用于表中一列或多列,应用于多列时,它被定义为表级PRIMARY KEY约束,否则被定义为列级PRIMARY KEY约束.SQL Server 自动为实施PRIMARY KEY约束的列建立唯一索引。如果在PRIMARY KEY约束中未指定索引类型时,默认情况下所建立的索引为簇索引(CLUSTERED)。该索引只能够通过删除PRIMARY KEY约束或其相关表的方法来删除,而不能使用DROP INDEX
语句删除。无论是建立列级PRIMARY KEY约束还是表级PRIMARY KEY约束,每个表只能创建一个PRIMARY KEY约束。
语法如下:
CONSTRAINT constraint_name
PRIMARY KEY [CLUSTERED | NONCLUSTERED]
(column_name1[, column_name2,…,column_name16])
主键列的数据类型不限,但此列必须是唯一并且非空。
如该表中已有主键为1000 的行,则不能再添加主键为1000。
创建主键有几种方式:
列约束子句
表约束子句
ALTER TABLE 语句
列约束子句:
[ CONSTRAINT constraint_name ]
PRIMARY KEY [ CLUSTERED | NONCLUSTERED ]
[ WITH [ FILLFACTOR = fillfactor ] ]
[ ON { filegroup | DEFAULT } ]
一般在创建表时指定列时,明确指定为主键。
create table tb7
(
txcode char(10) primary key,
docno char(20),
docseq smallint,
part varchar(30),
txqty numeric(12,4)
)
表约束子句:
[ CONSTRAINT constraint_name ]
PRIMARY KEY [ CLUSTERED | NONCLUSTERED ]
{ ( column [,...n] )}
[ WITH [ FILLFACTOR = fillfactor ] ]
[ ON { filegroup | DEFAULT } ]
在PRIMARY KEY约束定义中,WITH 子句设置为PRIMARY KEY约束所建立索引的页面填充度,ON 子句指出存储索引的数据库文件组名称。
表约束子句是在表定义结尾定义主键约束。表约束子句是CREATE TABLE 语句的一部分,如果约束子句有语法错误,整个语句将失败,表不会被创建。
create table tb8
(txcode char(10),
docno char(20),
docseq smallint,
part varchar(30),
txqty numeric(12,4),
CONSTRAINT [pk_tb8] PRIMARY KEY CLUSTERED
(
[txcode] ASC,
[docno] ASC,
[docseq] ASC
)
)
表约束子句允许包括多个约束,使用�D,‖分隔每一个约束定义。
ALTER TABLE 语句:
当创建了一张表,可以使用alter table 语句管理约束、增加列、改变存储参数。执行功能 ALTER 语法
Add a constraint ALTER TABLE table_name ADD CONSTRAINT etc
Drop a constraint ALTER TABLE table_name DROP CONSTRAINT etc
Disable a constraint ALTER TABLE table_name DISABLE CONSTRAINT etc
Enable a constraint ALTER TABLE table_name ENABLE CONSTRAINT etc
创建表tb1:
create table tb1
(id int identity(1,1),
co1 char(10),
co2 varchar(30),
co3 varchar(40),
co4 bit)
需将列id、co1 定义为主键,由于id 是属于自增列,因此默认属性不为空,co1 默认是乐允许空,因此使用alter table 命令修改列co1 参数为not null
alter table tb1
alter column co1 char(10) not null
定义主键约束,对列字段id、co1 进行约束
alter table tb1
add constraint PK_id primary key
(id,co1)
查看表详细情况:
sp_help tb1
自增列简述:
自增列的类型应为int 或bigint 型。可以设置起始和每次递增数
如:
create table [table1]
(
id int identity(1,1),
co1 varchar(20)
)
如上代码,每次插入数值时,列id 值初始为1,然后依次递增
若删除其中某条数据(如id=10),则再次插入数据时 ,id 从将11 开始,即使用过一次后,不会再使用第二次。
例:创建表table1,插入10 条数据
create table [table1]
(
id int identity(1,1),
co1 varchar(20)
)
insert into table1
values( 'abc')
go 10
现删除第10 条数据:
delete from table1
where id = 10
再次插入10 条数据:
insert into table1
values( 'abc')
go 10
select * from table1
删除主键约束:
alter table tb1
drop constraint pk_id
外键约束:
外关键字约束(简称外键约束)定义了表之间的关系。当一个表中的数据依赖于另一个表中的数据时,你可以使用外键约束避免两个表之间的不一致性。FOREIGN KEY约束为表中一列或多列资料提供参照完整性。实施FOREIGN KEY约束时,要求在被参照表中定义了PRIMARY KEY约束或UNIQUE 约束。FOREIGN KEY约束限制插入到表中被约束列的值必须在被参照表中已经存在。
语法:
CONSTRAINT constraint_name
FOREIGN KEY (column_name1[, column_name2,…,column_name16])
REFERENCES ref_table [ (ref_column1[,ref_column2,…, ref_column16] )]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ] ]
[ NOT FOR REPLICATION ]
表级FOREIGN KEY 约束的定义格式为:
[ CONSTRAINT constraint_name ]
FOREIGN KEY [ ( column [,...n] ) ]
REFERENCES ref_table [ ( ref_column [,...n] ) ]
[ NOT FOR REPLICATION ]
列级FOREIGN KEY 约束的定义格式为:
[ CONSTRAINT constraint_name ]
[ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ NOT FOR REPLICATION ]
其中,ref_table 为被参照表,ref_column 指出被参照表中的被参照列。被参照表中必须具有 PRIMARY KEY 约束和UNIQUE 约束。
在FOREIGN KEY 约束中,FOREIGN KEY 子句中指定的列数和每列的数据类型必须与REFERENCES 子句中的相同。对于列级FOREIGN KEY 约束,由于参照列唯一确定,所以可以省略,而只需指出被参照列即可。
例:创建表tb2,在列cBrandld定义外键约束,能照表Toybradn中列cBrandld.
create table tb2
(
ctoyid varchar(10),
vtoyname varchar(20),
vtoydescription varchar(20),
ccategoryld varchar(20),
mtoyrate money,
cBrandld char(3) references Toybradn(cBrandld),
imphoto image,
silowerage smallint,
siupperage smallint,
sitoyweight smallint,
vtoyimgpath varchar(50)
)
插入2 行数值:
insert into tb2
values('p0001','bus','A-B1','BIG','150.00','P01',null,3,4,null,null)
insert into tb2
values('p0001','bus','A-B1','BIG','150.00','S01',null,3,4,null,null)
当一条数值中列cBrandld 中值在表Toybradn 中列cBrandld 内值不存在时,出现下面错误:
消息547,级别16,状态0,第1 行
INSERT 语句与FOREIGN KEY 约束"FK__tb2__cBrandld__1A14E395"冲突。该冲突发生于数据库"demo_db",表"dbo.Toybradn",
column 'cBrandld'。
语句已终止。
当引用外键约束时,若出现下列操作:
NO ACTION:
指定如果试图删除/修改某一行,而该行的键被其他表的现有行中的外键所引用,则产生错误并回滚DELETE/UPDATE 语句。
CASCADE、SET NULL 和 SET DEFAULT:
允许通过删除或更新键值来影响指定具有外键关系的表,这些外键关系可追溯到在其中进行修改的表。如果为目标表也定义了级联引用操作,那么指定的级联操作也将应用于删除或更新的那些行。不能为具有 timestamp 列的外键或主键指定
CASCADE。
ON DELETE CASCADE:
指定如果试图删除某一行,而该行的键被其他表的现有行中的外键所引用,则也将删除所有包含那些外键的行。
ON UPDATE CASCADE:
指定如果试图更新某一行中的键值,而该行的键值被其他表的现有行中的外键所引用,则组成外键的所有值也将更新到为该键指定的新值。 (如果 timestamp 列是外键或被引用键的一部分,则不能指定 CASCADE。)
ON DELETE SET NULL:
指定如果试图删除某一行,而该行的键被其他表的现有行中的外键所引用,则组成被引用行中的外键的所有值将被设置为NULL。目标表的所有外键列必须可为空值,此约束才可执行。
ON UPDATE SET NULL:
指定如果试图更新某一行,而该行的键被其他表的现有行中的外键所引用,则组成被引用行中的外键的所有值将被设置为NULL。目标表的所有外键列必须可为空值,此约束才可执行。
ON DELETE SET DEFAULT:
指定如果试图删除某一行,而该行的键被其他表的现有行中的外键所引用,则组成被引用行中的外键的所有值将被设置为它们的默认值。目标表的所有外键列必须具 有默认值定义,此约束才可执行。如果某个列可为空值,并且未设置显式的默认值,则会使用 NULL 作为该列的隐式默认值。因 ON DELETE SET DEFAULT 而设置的任何非空值在主
表中必须有对应的值,才能维护外键约束的有效性。
ON UPDATE SET DEFAULT:
定如果试图更新某一行,而该行的键被其他表的现有行中的外键所引用,则组成被引用行中的外键的所有值将被设置为它们的默认值。目标表的所有外键列必须具 有默认值定义,此约束才可执行。如果某个列可为空值,并且未设置显式的默认值,则会使用 NULL作为该列的隐式默认值。因 ON UPDATE SET DEFAULT 而设置的任何非空值在主表
中必须有对应的值,才能维护外键约束的有效性。
DEMO:
若表已存在,且未定义外键约束,可使用ALTER TABLE 来定义外键约束:
alter table tb2
add constraint FK_tb2_cBandid
foreign key
(cBrandld) references Toybradn (cBrandld)
图形化界面创建外键约束:
数据库 → 表 → 设计 → 选择所需创建外键的列 → 右键 → 关系