数据库之约束条件与表关系
约束条件
主键--primary key
单从约束层面上来讲,相当于 not null unique >>> 非空且唯一
验证:
create table t1(id int primary key);
create table t2(id int not null unique);
主键还是InnoDB存储引擎组织数据表的依据
InnoDB规定了一个表必须要有且只有一个主键
如果你不指定主键则会采用隐藏的字段作为主键
当表中没有主键但是有非空且唯一的字段则自动升级为主键,顺序是从上往下的第一个。
# 主键是可以加快查询速度的 隐藏意味着无法使用主键即速度无法提升
create table t2(
id int,
name char(16),
age int not null unique,
addr char(16) not null unique
);
结论:在创建表的时候一般都需要有一个id(uid、sid、pid...)字段,并且该字段应该设置为表的主键字段。
联合主键
主键可以单列主键也可以联合主键,但是联合主键使用频率很低。
create table t3( id int, name char(16), primary key(id,name) );
自增--auto_increment
# 需要配合主键一起使用 create table t5( id int primary key auto_increment, name char(16) );
创建表,主键字段的固定写法如下
id int primary key auto_incrementb
补充
delete from :只删除数据
自增的特性不会因为delete操作而重置/回退。
truncate:既删除数据又重置主键
如果真的想重置需要清空表数据和表结构就可以使用truncate
外键
# 定义一张员工表为例
id name age dep_name dep_descw1
问题:
表结构不清晰:可以忽略
表数据重复: 可以忽略
数据扩展性极差: 不能忽略
解决方法:
# 解决上述三个问题:拆表
id name age
id dep_name dep_desc
新问题:
拆表解决了上面的三个问题但是员工和部门没有了关系
解决方法:
在员工表里面添加一个部门编号字典dep_id(外键)
表关系
种类
多对多关系,一对一关系,一对多关系,没有关系
判断表关系
遵循换位思考的原则。
一对多关系
员工表与部门表
1.先站在员工表的层面
问:一个员工能否对应多个部门
答:不可以
2.再站在部门表的层面
问:一个部门能否对应多个员工
答:可以
结论:一个可以,一个不可以那么员工表与部门表就是"一对多"
“一对多”关系外键字段建在“多”的一方
1.先写基本字段类型与约束条件
2.再考虑外键
create table emp1( id int primary key auto_increment, name char(16), age int, dep_id int, foreign key(dep_id) references dep(id) ); create table dep1( id int primary key auto_increment, dep_name char(16), dep_desc char(32) );
在创建表的时候一定要先创建被关联表(自身没有外键字段的表)。
在插入数据的时候也是先插入被关联表再插入关联表,只能够填写被关联字段中出现的值。
被关联表中的数据无法自由删除和修改。
级联更新、级联删除。
级联更新:on update cascade
级联删除:on delete cascade
代码演示
create table dep1( id int primary key auto_increment, dep_name char(10), dep_comment char(60) ); create table emp1( id int primary key auto_increment, name char(16), gender enum('male','female') not null default 'male', dep_id int, foreign key(dep_id) references dep1(id) on update cascade on delete cascade ); insert into dep1(dep_name,dep_comment) values ('sb教学部','sb辅导学生学习,教授python课程'), ('外交部','驻上海形象大使'), ('nb技术部','nb技术能力有限部门'); insert into emp1(name,gender,dep_id) values ('jyb','male',1), ('tom','male',2), ('tony','male',1), ('kevin','male',1), ('jim','female',3);
多对多关系
书籍表和作者表
1.先站在书籍表
问:一本书能否对应多个作者
答:可以
2.在站在作者表
问:一名作者能否对应多本书
答:可以
结论:两边都可以 那么表关系就是"多对多"
针对多对多的表关系,外键字段需要建在第三张关系表中
# 针对多对多的表关系 外键字段需要建在第三张关系表中
create table book(
id int primary key auto_increment,
name char(16),
price int
);
create table author(
id int primary key auto_increment,
name char(16),
age int
);
create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);
一对一关系
用户表与用户详情表
1.先站在用户表层面
问:一个用户能否对应多个用户详情
答:不可以
2.再站在用户详情表层面
问:一个用户详情能否对应多个用户
答:不可以
结论:两边都不可以,那么表关系要么是没有关系要么是"一对一"关系。
外键建在任意一方都可以 但是推荐建在查询频率较高的表中
create table user( id int primary key auto_increment, name varchar(16), detail_id int unique, foreign key(detail_id) references user_detail(id) on update cascade on delete cascade ); create table user_detail( id int primary key auto_increment, phone bigint, addr varchar(16) );
表关系的小总结:
判断表之间关系的方法:分别站在两张表各自的立场上判断,是否可以自己一个拥有对方多个,
如果两方都可以,那么就是多对多;
如果只有一边是可以的,那么就是一对多;
如果两边都不可以,那么就是一对一,当然也有可能是没有关系。
修改表相关SQL语句
修改表名
alter table 表名 rename 新表名;
增加字段
尾部追加
ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…], ADD 字段名 数据类型 [完整性约束条件…];
首部添加
ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] FIRST;
指定位置添加
ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
删除字段
ALTER TABLE 表名 DROP 字段名;
修改字段
modify:只能修改类型,不能改字段名
ALTER TABLE 表名 MODIFY 字段名 数据类型 [完整性约束条件…];
change:既可以改字段类型,也可以改字段名
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…]; ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];