数据完整性

一、数据完整性的基本概念

1、什么是数据完整性?

数据完整性是指存储在数据库中的数据要能正确反映实际情况,规定输入的数据不能是无效值、错误值或者乱码等。

2、数据完整性的类型

① 实体完整性:标识符或者主键的完整性,使其值唯一。
② 域完整性:限制类型、格式和取值范围等。
③ 引用完整性:保持原表和引用表数据的一致性。
④ 自定义完整性:用户自定义的业务规则

3、数据完整性的实现方式

实体完整性:主键约束、唯一值约束
域完整性:检查约束、默认值约束
引用完整性:外键约束
用户自定义完整性:以上约束的自由组合

4、什么是约束?

数据完整性约束也就是创建表( create table )时的约束条件,是用来限制属性或者表中数据的,也可以通过修改语句( alter table )修改约束条件。

5、约束又分为行级约束和表级约束,行级约束和表级约束本质上是一样的,只是约束的效力和范围不同。

非空约束、默认值约束、主键约束一般为行级约束;
外键约束(联合主键)是表级约束;
检查约束(check) 既可以是行级约束也可以是表级约束;

存储完整性 java 存储完整性是什么意思_主键

二、完整性约束

1、MySQL添加或修改约束的方式

怎样添加或修改约束?

① 创建表时添加约束
② 修改表时添加或修改约束
③ 删除表的约束
④ 查询表的约束

注意:

modify column关键字用于行级约束的添加、删除

add、drop关键字用于表级约束的添加、删除

非空约束(行级约束)

非空约束:确保当前约束的属性不为空值,非空约束只能出现在表对象的列中,是行级约束。表示该属性的取值不能为空,如果插入的数据为空,会被系统阻止插入。

-- 非空约束关键字:not null
-- 创建非空约束的语法格式:
create table <table_name>(
	no int not null,
	name varchar(20) not null
);   -- 创建一个表,使编号和名称不能为空

INSERT INTO staff VALUES(1,'张三','男',30); -- 插入成功

-- 数据库中如果不给定属性值,属性的取值会默认为空
INSERT INTO staff(staff_name) VALUES('李四');
-- 错误代码: 1364 Field 'staff_id' doesn't have a default value
-- 对添加了非空约束的属性必须给定一个取值,没有取值则会插入失败

/*表约束的修改*/
-- 修改表中行级属性约束的一般格式:
alter table <表名> modify column <属性名> <数据类型> [约束];
alter table teachar modify column t_name varchar(20) not null; 
-- 通过修改表去掉非空属性约束:
alter table teachar modify column t_no varchar(20); 
-- 在修改表时不添加非空约束就是去掉非空约束

-- 注意:修改表属性的时候,会对原表中的数据进行一个检查,如果出现取值冲突,则无法修改表约束。

唯一约束(表级约束)

指定某列或者某几列数据的取值不能重复。
唯一约束关键字:unique

-- 如果属性已经存在重复的值,则不能添加唯一约束。
-- ① 创建表时添加唯一约束
create table teacher_tb(
	t_no int unique, -- 唯一约束
	t_name varchar(20));
-- ② 指定列添加唯一约束:
alter table <表名> add 约束类型(属性名);
ALTER TABLE staff ADD UNIQUE(staff_id);

-- 示例:可以通过constraint给约束取别名
alter table <表名> add constraint <约束名> unique(属性名);
-- ③ 删除唯一约束:
alter table  <表名> drop index <属性名/约束名>;
ALTER TABLE staff DROP INDEX staff_id;

复合唯一约束(表级约束)

创建复合唯一约束(表级约束)
可以对多个列进行唯一约束,约束两个以上的字段(属性)不能同时一致。

-- ① 在创建表时添加复合唯一约束
constraint <约束名> unique(<属性1>[,属性2][,…属性n])
CREATE TABLE staff(
staff_id INT NOT NULL,	-- 工号(不为空)
staff_name VARCHAR(30),  -- 姓名
staff_gender VARCHAR(4), -- 性别
staff_age INT,
CONSTRAINT S UNIQUE(staff_id,staff_name) -- 为staff_id,staff_name两个属性添加复合唯一约束
    -- constraint用于给约束取别名
);

-- ② 在创建表后添加复合唯一约束
alter table <表名> add constraint <约束名> unique(<属性1>[,属性2][,…属性n]);
-- 这里也就是约束属性1、属性2到属性n中可以允许其中存在取相同值的属性,但不能同时相同,至少要有一个不同。
  ALTER TABLE staff ADD CONSTRAINT S UNIQUE(staff_age,staff_name);
-- 数据库默认第一个非空且唯一的属性为主属性(主键)

-- 复合唯一约束的删除
ALTER TABLE staff DROP INDEX S; -- 根据约束名删除复合唯一约束

三、主键约束(表级约束)

主键约束就是非空约束+唯一约束,且每个表只能有一个主键约束(表级),在多列联合的主键约束时,联合主键的值不能同时重复。

-- 主键约束关键字:primaty key。
-- ① 在创建表时设置单列主键
create table <表名>(
属性名 数据类型 primary key,	-- 设置主键约束
属性名 数据类型 not null )

-- ② 设置多个属性为联合主键
alter table <表名> add [constraint <约束名>] primary key(属性1[,属性2,…,属性n]);

-- ③ 删除主键约束
alter table <表名> drop primary key;	-- 直接丢掉主键


-- 主键约束就是非空约束+唯一约束,非空且唯一,用于规定表格的实体完整性
-- 同一个数据表中非空且唯一属性可以有多个,但是主键约束(主属性)有且只有一个
-- 如果表中添加主键的字段已经存在空值或重复值,则不允许添加主键
ALTER TABLE staff ADD PRIMARY KEY(staff_id);

-- 联合主键约束
  -- 数据表中可能存在多个属性同时作为一个主键的情况,一个主键包含多个属性的情况
  -- 多列作为联合主键,其主键不能为空,且取值不能同时重复
  -- 联合主键约束:非空约束+复合唯一约束
CREATE TABLE staff(
staff_id INT NOT NULL,	-- 工号(不为空)
staff_name VARCHAR(30),  -- 姓名
PRIMARY KEY(staff_id,staff_name) -- 为staff_id,staff_name两个属性添加联合主键约束
);

ALTER TABLE staff ADD PRIMARY KEY(staff_id,staff_name);
 -- 修改表时为staff_id,staff_name两个属性添加联合主键约束

自增列约束(行级约束)

自增列就是在插入数据时,如果不规定属性的值,其值就会根据上一个属性的值自动加1。

-- 自增列关键字:auto_increment(行级约束)
-- 给一个属性添加自增列约束需要这个属性有唯一约束,一般只为主键添加自增列

-- ① 创建表时添加自增列
CREATE TABLE staff(
staff_id int PRIMARY KEY AUTO_INCREMENT,	-- 工号(主键约束,自增)
staff_name VARCHAR(30),  -- 姓名
staff_gender VARCHAR(4), -- 性别
staff_age INT
)AUTO_INCREMENT = 100;	-- 设置自增列的初始值为100(初始值默认为0)

-- ② 添加自增列
alter table <表名> modify column <属性名> <数据类型> auto_increment = 100;  -- 可以设置自增列的初始值(默认值为1)
ALTER TABLE staff MODIFY COLUMN staff_id INT  AUTO_INCREMENT;

-- ③ 删除自增列
alter table <表名> modify column <属性名> <数据类型>;


-- 不给定带有自增列属性的值,其属性值会根据上一个属性值自增1
INSERT INTO staff(staff_id,staff_name) VALUES(NULL,'王五');
-- 如果给定带有自增列属性的取值,则用你给定的值
INSERT INTO staff(staff_id,staff_name) VALUES(7,'王五');

默认值约束(行级约束)

给带有默认值约束的属性添加数据时,如果没有给定属性值,会自动添加一个默认值。

-- 默认值约束关键字:default
-- ① 在创建表时设置默认值约束
create table <表名>( 
name varchar(20) not null,
sex varchar(4) default '男'     --  性别默认为'男'
);	

-- 添加/删除默认值约束
alter table <表名> modify column <属性名> <属性类型> [default <默认值>];
ALTER TABLE staff MODIFY COLUMN staff_gender VARCHAR(4) DEFAULT '男'; 

-- 由于默认值约束是行级约束,其添加、删除的基本格式与非空约束类似
ALTER TABLE staff MODIFY COLUMN staff_gender VARCHAR(4);

检查约束

检查约束就是检查列中属性的取值范围,判断字段的值是否为指定的值,如果不是就不允许数据的插入或修改。

-- 检查约束关键字:check
CREATE TABLE staff(
staff_id INT NOT NULL,	-- 工号(不为空)
staff_name VARCHAR(30),  -- 姓名
staff_gender VARCHAR(4)  CHECK(staff_gender='男' || staff_gender='女'), -- 检查约束
staff_age INT CHECK(staff_age >=0 && staff_age <=100) -- 检查约束
);

alter table staff modify colum staff_age int CHECK(staff_age >=0 && staff_age <=100); 
-- 检查年龄取值是否在0~100之间
    

-- 注意:MySQL不支持修改表时添加检查约束,支持在创建表时为属性添加检查约束

外键约束(表级约束)

外键约束是指一个表中的属性值参考另一个表中的主属性的值,也就是外键值参考主键值,由于外键约束是表级约束,所以在创建参考表之前要先创建被参考表。

-- ① 创建表时建立外键约束;
constraint <约束名> foreign key(<属性名>) references 被参考表(<被参考属性名>)
  -- 外键约束用于描述两个实体集之间的关系
  -- 外键值参考主键值
  CREATE TABLE staff_tb(
staff_id INT PRIMARY KEY AUTO_INCREMENT,	-- 工号(不为空)
staff_name VARCHAR(30) NOT NULL,  -- 姓名
staff_gender VARCHAR(4), -- 性别
staff_did INT ,		 -- 部门编号(外键,参考于部门表中的部门编号)
staff_age INT,
CONSTRAINT for_sdid FOREIGN KEY(staff_did) REFERENCES department(d_id) -- 外键约束
);

-- 在创建员工表之前,需要创建被参考表(父表) 部门表
-- 创建部门表
CREATE TABLE department(
d_id INT PRIMARY KEY AUTO_INCREMENT,	-- 部门编号
d_name VARCHAR(40) NOT NULL,		-- 部门名称
d_number INT DEFAULT 0 			-- 部门员工人数
)AUTO_INCREMENT = 100;

-- ② 添加外键约束
alter table <表名> add constraint <约束名> foreign key(<属性名>) references 被参考表(<被参考属性名>);

-- ③ 删除外键约束
alter table <表名> drop constraint <约束名>;
-- 根据约束名删除约束
级联更新、删除:

级联更新/删除是指父表中的元组更新或删除等操作对子表的处理方法,其有三种处理方法:

# 在更新/删除中(on update/on delete)
-- ① cascade:父表中的元组更新或删除,在子表中跟着更新或者删除
	# 在外键约束后加上:on update cascade/on delete cascade
	
-- ② no action:无动作,若子表中有匹配的记录,就不允许更新/删除父表的数据(外键默认为no action)
	# 在外键后加上:on update no action/on delete no action
	
-- ③ set null:设置为空,若子表中有匹配的记录,更新/删除父表中的数据,子表中对应数据设置为空
	# 在外键约束后加上:on update set null/on delete set null

  CREATE TABLE staff_tb(
staff_id INT PRIMARY KEY AUTO_INCREMENT,	-- 工号(不为空)
staff_name VARCHAR(30) NOT NULL,  -- 姓名
staff_gender VARCHAR(4), -- 性别
staff_did INT ,		 -- 部门编号(外键,参考于部门表中的部门编号)
staff_age INT,
CONSTRAINT for_sdid FOREIGN KEY(staff_did) REFERENCES department(d_id) -- 外键约束
 ON DELETE CASCADE ON UPDATE SET NULL -- 级联更新、删除
 -- 在删除操作时存在对应数据跟着更新,在更新操作时存在对应数据设置为空
 -- 可以只规定级联更新,也可以只规定级联删除,也可以都规定
 -- 处理方式也可以分别设置
);


可以同时设置更新和删除所对应的操作
-- 在外键约束后加上:on update cascade on delete no action
	# 父表在更新数据时,若子表中有匹配的记录,子表同步更新匹配的数据,并且若子表中有匹配的记录无法删除父表数据
示例:create table student1(
s_id int primary key,
s_name varchar(20) not null,
s_cid int not null,
s_age int,s_sex varchar(2),
constraint for_scid foreign key(s_cid) references class(class_id) on update cascade on delete set null );
	# 学生表中的班级编号s_cid参考班级表中的班级编号class_id