所有的关系数据库都支持对数据表使用约束,
通过约束可以更好地保证数据表里数据的完整性。
约束是表上强制执行的校验规则,
除此之外,当表中数据存在相互依赖性时,
可以保护相关数据不被删除。
约束通常无法修改。
5种完整性约束:
1)NOT NULL: 指定某列不能为空
2)UNIQUE: 指定某列或某几列不能重复
3)PRIMARY KEY: 指定该列的值可以唯一地标识该条记录
4)FOREIGN KEY: 指定该行记录从属于主表中的一条记录,主要用于保证参照完整性
5)CHECK: 指定一个布尔表达式,用于指定对应列的值必须满足该表达式
【mysql不支持check】
2类约束:
1)单列约束:
2)多列约束:
指定约束的时机:
1)建表的同时为相应的数据列指定约束
2)建表后创建,以修改表的方式来增加约束(用alter来修改)
【大部分约束都可以采用列级约束语法或者表级约束语法】
*NOT NULL约束:
它只能作为列级约束使用,只能使用列级约束语法定义。 SQL中null: 1)所有数据类型的值都可以是null值,包括 int、float、boolean等 2)与 java 类似,空字符串不等于 null ,0 也不等于 null
----建表时为指定列指定非空约束:
create table hehe(
# 建立了非空约束
hehe_id int not null,
# Mysql的非空约束不能指定名字
hehe_name varchar(255) default 'xyz' not null,
# 下面列可以为空,默认就是可以为空
hehe_gender varchar(2) null
);
----使用alter table 修改表时 增加 / 删除 非空约束:
# 增加非空约束
alter table hehe
modify hehe_gender varchar(2) not null;
# 取消非空约束
alter table hehe
modify hehe_name varchar(2) null;
# 取消非空约束,并指定默认值
alter table hehe
modify hehe_name varchar(255) default 'abc' null;
*UNIQUE约束:
唯一约束用于保证指定列或指定列组合不允许出现重复值。 但可以出现多个null值(数据库中null值不等于null值) 当建立唯一约束时,Mysql在唯一约束所在列或者列组合上建立对应的唯一索引。
----列级约束语法建立唯一约束:
create table unique_test(
# 建立非空约束,test_id不可以为null
test_id int not null,
# unique 就是唯一约束,使用列级语法建立唯一约束
test_name varchar(255) unique
);
----如果需要为多列组合建立唯一约束,或者想自行制定约束名,则需要使用表级约束语法, [ constraint 约束名 ] 约束定义 它既可以放在create table 语句中与列定义并列, 也可以放在alter table 语句中使用 add 关键字来添加约束
create table unique_test2(
test_id int not null,
test_name varchar(255),
test_pass varchar(255),
# 使用表级约束语法建立唯一约束
unique (test_name),
constraint test2_uk unique(test_pass)
);
----除此之外,还可以为两列组合建立唯一的约束:
create table unique_test3(
test_id int not null,
test_name varchar(255),
test_pass varchar(255),
# 使用表级约束语法建立唯一约束,指定两列组合不允许重复
constraint test3_uk unique(test_name,test_pass)
);
----修改表结构时使用 add 关键字来增加唯一约束:
# 增加唯一约束
alter table unique_test3
add unique(test_name,test_pass);
----修改表时使用 modify 关键字,为单列采用列级约束语法来增加唯一约束:
# 为unique_test3表中的test_name 列增加唯一约束
alter table unique_test3
modify test_name varchar(255) unique;
----对于大部分数据库而言,删除约束都是在alter table 语句后使用 “drop constraint 约束名”语法来完成的, 但是Mysql并不使用这种方式, 而是使用“drop index 约束名 ” 的方式来删除约束
# 删除unique_test3 表上的test3_uk 这个唯一约束
alter table unique_test3
drop index test3_uk;
*PRIMARY KEY约束:
主键约束相当于非空约束和唯一约束,即主键约束的列既不允许出现重复值,也不允许出现null值; 如果对多列组合建立主键约束,则多列里包含的每一列都不能为空,但只要求这些列组合不能重复(只能使用表级约束语 法); 使用表级约束语法建立约束时,可以为该约束指定约束名, 但不管用户是否为该主键约束指定约束名,MySQL总是将所有的 主键约束 命名为PRIMARY ; 主键列的值可用于唯一地标识表中的一条记录; 每一个表中最多允许有一个主键 ; 当创建主键约束时,MySQL在主键约束所在列或列组合上建立对应的唯一索引; 与建立唯一约束不同的是,建立主键约束使用 primary key
----建表时创建主键约束,列级语法
create table primary_test(
# 建立了主键约束
test_id int primary key,
test_name varchar(255)
);
----建表时创建主键约束,表级语法:
create table primary_test2(
test_id int not null,
test_name varchar(255),
test_pass varchar(255),
# 指定主键约束名为test2_pk,对大部分数据库有效,但对Mysql无效
# Mysql数据库中该主键约束名仍为 PRIMARY
constraint test2_pk primary key(test_id)
);
----建表时创建主键约束,以多列建立组合主键,只能使用表级约束语法:
create table primary_test3(
test_name varchar(255),
test_pass varchar(255),
# 建立多列组合的主键约束
primary key(test_name, test_pass)
);
----删除指定表的主键约束:
# 删除主键约束
alter table primary_test3
drop primary key;
----为指定表增加主键约束(2种):
# 通过 modify 修改列定义,采用列级约束语法
alter table primary_test3
modify test_name varchar(255) primary key;
# 通过 add 来增加主键约束,采用表级约束语法
alter table primary_test3
add primary key(test_name, test_pass);
----很多数据库对主键列都支持一种“ 自增长 ”的特性——(如果某个主键列的类型是整型,则可指定该列具有自增长功能) 指定自增长功能用于设置逻辑主键列——该列的值没有任何物理意义,仅用来表示每行记录, MySQL使用auto_increment 来设置自增长 , 一旦指定了某列具有自增长特性,则向该表插入记录时可不为该列指定值,该列的值由数据库系统自动生成
create table primary_test4(
# 建立主键约束,使用自增长
test_id int auto_increment primary key,
test_name varchar(255),
test_pass varchar(255)
);
*FOREIGN KEY约束:
外键约束主要用于保证一个或两个数据表之间的参照完整性, 外键时构建于一个表的两个字段或者两个表的两个字段之间的关系。 外键确保了相关的两个字段的参照关系:字表外键列的值必须在主表被参照的值范围之内 , 或者为空(也可以通过非空约束来约束外键列不允许为空); 当主表的记录被从表记录参照时,主表记录不允许被删除, 必须先把从表里参照记录的所有记录全部删除后,才可以删除主表的该记录, ——另一种方式,删除主表记录时级联删除从表中所有参照该记录的从表记录; 从表外键参照的只能是主表的主键列或者唯一键列(可保证从表记录可以准确定位到被参照的主标记录); 同一表内可以有多个外键; 建立外键约束时,MySQL也会为该列建立索引
----采用列级约束语法建立外键约束直接使用 references 关键字,references 指定该列参照哪个主表,以及参照主表的哪一列: 但这种列级语法建立的外键约束不会生效,MySQL提供这种列级语法仅仅是为了和标准SQL保持良好的兼容性
# 为了保证从表参照的主表存在,通常应该先建立主表
create table teacher_table(
teacher_id int auto_increment,
teacher_name varchar(255),
primary key(teacher_id)
);
create table student_table(
# 为本表建立主键约束
student_id int auto_increment primary key,
student_name varchar(255),
# 指定 fk 参照到 teacher_table 的 teacher_id 列
fk int references teacher_table(teacher_id)
);
----因此,要使MySQL中的外键约束生效,应使用表级约束语法, 需要使用foreign key 来指定本表的外键列
# 为了保证从表参照的主表存在,通常应该先建主表
create table teacher_table1(
# auto_increment: 代表数据库的自动编号策略,通常用作数据表的逻辑主键
teacher_id int auto_increment,
teacher_name varchar(255),
primary key(teacher_id)
);
create table student_table1(
# 为本表建立主键约束
student_id int auto_increment primary key,
student_name varchar(255),
# 指定 java_teacher 参照到 teacher_table1 的 teacher_id列
java_teacher int,
foreign key(java_teacher) references teacher_table1(teacher_id)
);
----为外键约束指定约束名: 如果创建外键约束时没有指定约束名,则MySQL会为该外键约束命名为 从表表名_ibfk_n , (n是从1开始的整数) 如果需要显式指定外键约束的名字,用 constraint 关键字
create table teacher_table2(
teacher_id int auto_increment,
teacher_name varchar(255),
primary key(teacher_id)
);
create table student_table2(
student_id int auto_increment primary key,
student_name varchar(255),
java_teacher int,
# 使用表级约束语法建立外键约束,指定外键约束的约束名为student_teacher_fk
constraint student_teacher_fk foreign key(java_teacher) references
teacher_table2(teacher_id);
);
----建立多列组合的外键约束,则必须使用表级约束语法:
create table teacher_table3(
teacher_name varchar(255),
teacher_pass varchar(255),
# 以两列建立组合主键
primary key(teacher_name,teacher_pass)
);
create table student_table3(
# 为本表建立主键约束
student_id int auto_increment primary key,
student_name varchar(255),
java_teacher_name varchar(255),
java_teacher_pass varchar(255),
# 使用表级约束语法建立外键约束,指定两列的联合外键
foreign key(java_teacher_name,java_teacher_pass) references
teacher_table3(teacher_name,teacher_pass)
);
----增加外键约束通常使用add foreign key 命令:
# 修改 student_table3 的数据表,增加外键约束
alter table student_table3
add foreign key(java_teacher_name,java_teacher_pass)
references teacher_table3(teacher_name,teacher_pass);
----删除外键约束,在 alter table 后增加 “drop foreign key 约束名” 即可:
# 删除 student_table3 表上名为 student_table3_ibfk_1 的外键约束
alter table student_table3
drop foreign key student_table3_ibfk_1;
----外键约束不仅可以参照其他表,而且可以参照自身,这种情况称为 “ 自连接 ”:
# 使用表级约束语法建立外键约束,且直接参照自身
create table foreign_self(
foreign_id int auto_increment primary key,
foreign_name varchar(255),
# 使用该表的 refer_id 参照到本表的 foreign_id 列
foreign key(refer_id) references foreign_self(foreign_id)
);
----如果想定义删除主表记录时,从表记录也会随之删除: 1)需要在建立外键约束后添加 on delete cascade (删除主表记录时,把参照主表记录的从表记录全部级联删除) 2)余姚在建立外键约束后添加 on delete set null (删除主表记录时,把参照该主表记录的外键设为 null )
# 为了保证从表参照的主表存在,先建立主表
create table teacher_table4(
teacher_id int auto_increment,
teacher_name varchar(255),
primary key(teacher_id)
);
create table student_table4(
student_id int auto_increment primary key,
student_name varchar(255),
java_teacher int,
# 使用表级约束语法建立外键约束,定义级联删除
foreign key(java_teacher) references teacher_table4(teacher_id)
on delete cascade # 第二种:on delete set null
);
*CHECK约束:
enum(条件) --- gender enum('f','m')
check(条件) --- check(gender in('f','m'))--mysql的check约束 当前版本的MySQL支持建表时指定CHECK约束,但这个CHECK约束不会有任何作用; 建立CHECK约束的语法:只要在建表的列定义后增加check(逻辑表达式)即可
create table check_test(
emp_id int auto_increment,
emp_name varchar(255),
emp_salary decimal,
primary key(emp_id),
# 建立 CHECK 约束
check(emp_salary > 0)
);