约束

mysql中的约束

unique:

? 唯一性的约束,表示这个字段不能出现重复的值,用于唯一标识一条记录

? e.g.:身份证,学号

not null:

? 非空约束,表示这个字段的值不能为空

? e.g.:账户名,密码

null:

? 一些数据类型默认就是可以为空的

default:

? 默认值,用于给某一个字段设置默认值

普通约束

#完整的建表语句

create table table_name(字段名称 字段类型【(宽度)约束】charset utf8;

#学生表

create table student(

#非空

name char(10) not null,

#默认值

gender enum('g','b') default 'b')

#唯一

id int unique)

#测试

insert into student values(null,null,null)#错误 原因是name不能为空

insert into student values('jack',null,null)#可以插入,原因是null作为一个特殊的值,并且id的唯一约束也可以为null

insert into student (name,id)values('jack',null);#可以插入 当没有给gender指定参数时,可以用默认值

alter table student modify id int unique not null

#为已经存在的字段添加约束

primary key:

? 主键约束,从约束角度老看就等同于 非空+唯一

? 主键和普通约束的区别在于:

create table person(

id char(19) primary key,

name char(20)

);

insert into person values('1','rose');#ok

insert into person values('1','jack')# ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'主键冲突;

insert into person values('2','jack')#ok

insert into person values(null,'tomor')

#Column 'id' cannot be null #主键不能为空

#从约束角度来看,等同于,非空+唯一

#create table person(

id char(10),

name char(20)

);

#在innodb存储引擎中,主键用于组织数据(树形结构)

#也就是说主键对于innodb引擎来说是必要的,没有不行

#如果没有手动指定主键

#mysql 会自动查找一个具备非空且唯一的字段作为主键

#如果没有这样的字段,mysql会创建一个隐藏字段 作为主键

#首先明确主键是一个索引,unique也是,索引的作用是加速查询

#如果我们在查询语句中没有使用索引字段,mysql讲无法为我们查询加速,一位置如果没有主键,将无法加速查询

总的来说:主键具备约束的作用,还能加快我们的查询速度,所以今后在创建表的时候都应该创建索引字段

将什么样字段创建主键:

#如果本来的业务就存在非空且唯一的字段,那就把他设为主键

#如果没有那就自己添加一个字段专门作为主键

通常我们将主键设置为类 int 类型 为了方便保证唯一

案例:

mysql>create table Pc(

id in primary key,

pinpai char(20),

model char(10),

price float

);

mysql> insert into PC values(1,"IBM","1214SB",40000);

mysql> insert into PC values(2,"DELL","1200DSB",4000);

mysql> select *from PC;

mysql> select *from PC where id = 1;

mysql> select *from PC where pp = "DELL";

为主键设置自动增长:

? mysql有一个自动增长的属性,可以添加在整形字段上,每次插入数据时,都可以自动的插入值,并且每次加1不会冲突;

create table teacher(

id int primary key auto_increment,

name char(10)

);

insert into teacher values(null,'jack');

#对于自定增长的字段可以给null,会自动生成值

insert into teacher(name) values('jack');

#可以跳过这个字段

自动增长可以用在具备索引,并且是数字类型的字段上,但是通常与主键一起使用

表yu表之间的关系:

foregin key:外键约束,用于指向另一个表的主键字段

#创建标的时候添加外键

create table teacher (

id int primary key auto_increment,

name char(10),

gender char(1),

dept_id int,

foreign key (dept_id) references dept(id)

);

#注解

foregin key (dept_id) references dept(id)

#其中dept_id 表示表的外键字段

#dept 表示要关联哪个表

#dept(id) id 表示的是关联的dept表的id字段

先后循序

先有主表,,再有从表

先有dept ,,再有teacher

foreign key 带来的约束作用

1.先从表中插入一条记录,关联了一个主表不存在的id 会导致插入失败

必须保证部门id(外键的值)必须是在主表中存在的

2.插入数据的顺序:

先主表 再插入从表

3.从表更新外键时也必须保证 外键的值在主表中是存在的

4.删除主表记录前,要保证从表中没有外键关联被删除的id

-必须先删除从表再删除主表

5.更新主表记录的主键时,要保证从表中没有外键关联被删除的id

6.必须先创建主表

7.删除表 其必先删从表

==foreign key 就是用来保证两张表之间的关联是正确的==

练习:班级表和学员表

主:班级 从:学员

create table class(

id int primary key auto_increment,

name char(20),

);

create table student(

id int primary key auto_increment,

name char(20),

gender char(1),

c_id int,

foreign key (c_id) references class(id)

);

级联操作 cascade

当我们需要删除主表信息时,必须先删除从表中的关联数据,很麻烦

那级联操作可以帮助解决--->也就是说当你操作主表时,自动的操作从表

两种操作:

1《 级联的删除

? 当删除主表时自动删除从表中相关数据

2《级联的更新

? 当主表的主键更新时,会自动的更新关联从表的数据

案例:

create table if exists class;

#如果这个表存在,创建新的表会产生重名的话,可以避免报错,if exists

# if not exists 如果不存在才执行

create table claaa(

id int primary key auto_increment,

name char(20),

);

insert into class values (null,'py9');

insert into class values(null,'py10');

#创建表的时候指定级联操作

drop table if exists student;

create table stydent(

id int primary key auto_increment,

name char(20),

gender char(1),

c_id int,

foreign key (c_id) references class(id)

on update cascade

on delete cascade

);

#级联操作可以单独使用 也可以一起使用,空格隔开即可

insert into student values(null,"jack","m",1);

insert into student values(null,"rose","m",1);

insert into student values(null,"tom","m",2);

外键的使用:

? 什么时候时候外键:---------表之间存在关联关系

首先确定表之间的关系

1:多对一 (一对多)

案例:部门==老师

#部门:

create table dept(

id int primary key auto_increment,

name char(20),

job char(50),

manager char(10)

);

#老师表:

create table teacher(

id int primary key auto_increment,

name char(20),

gender char(1),

dept_id int,

foreign key(t_id) references teacher(id),

);

2:多对多

需要建立一个中间表

学生 ==老师==共同的id

处理方式:

? 建立一个中间表,用于存储关系,至少具备两个字段分别指向学生和老师的主键,两个字段都是外键 如下:

create table t_s_r (

id int primary key auto_increment,

t_id int,

s_id int,

foreign key (t_id) references teacher (id),

foreign key (s_id) references student(id),

unique key (t_id,s_id)

);

#问题是 上表的id是可选的,如何保证没有重复关系

1:

#给两个字段设置联合唯一+非空

alter table t_s_r add unique key(t_id,s_id);

2:创建表时指定 多字段联合唯一

alter table t_s_r(t_id int ,s_id int,unique key(t_id,s_id));

#推荐 将中间的关系表 两个id作为联合主键同时具备了唯一且非空约束

create table t_s_r (t_id, int s_id int,primary key(t_id,s_id));

处理多对多关系

1创建两个主表 如学员 和 老师

2创建关系表 包含两个字段 分别设置外键 指向对应的表

3将两个字段 作为联合主键

案列:

create table student(id int primary key auto_increment,name char(10));

create table teacher(id int primary key auto_increment,name char(10));

create table t_s_r(

t_id int,

s_id int,

foreign key(t_id) references teacher(id),

foreign key(s_id) references student(id),

primary key(t_id,s_id)

);

# 先插入 学生或是老师都可以 但是关系表一定是最后添加的

insert into teacher values(null,"bgon"),(null,"nike");

insert into student values(null,"老王"),(null,"老李");

# 老王被bgon教过

insert into t_s_r values(1,1);

# nike教过老李

insert into t_s_r values(2,2);

# nike教过老王

insert into t_s_r values(2,1);

已知老师名称为bgon 请找出他教过那些学生

1.通过名字获取 bgon的id

2.拿着id取关系表中拿到一堆学生的id

3.通过学生的id取出学生的信息

select id from teacher where name = "bgon";

select s_id from t_s_r where t_id = 1;

select * from student where id = 1;

# 子查询方式 把一条语句的结果作为另一条语句的条件!

select * from student where id = (select s_id from t_s_r where t_id = (select id from teacher where name = "bgon"));

已知学生名为老李 请查询出 哪些老师教过他

1.通过名字获取老李的id

select id from student where name = "老李";

2.拿着id去关系表 找出老师的id

select t_id from t_s_r where s_id = 2;

3.通过老师的id取出老师的信息

select name from teacher where id = x;

# 子查询方式:

select name from teacher where id = (

select t_id from t_s_r where s_id = (

select id from student where name = "老李"

)

);

3:一对一

处理顺序:

将先存在的数据作为主表

后存在的作为从表

使两个表的id保持一致 ---对应起来

? 方法1:从表的id 即是主键 又是外键

? 2:从表的id设置为外键 并保证唯一

案列:

#人员表

create table person(

id int primary key auto_increment,

name char(10),

age int

);

#详情表

create table person_info(

id int primary key,

heigent float,

weight float,

foreign key(id) references person(id)

);

#在这样的关系中,必须先插入主表即person,拿到id之后在添加详情表额数据

#将一条完整数拆分到不同的表中,可以提高查询的效率,上述方法称之为垂直分表

!@#¥%……***

约束:精华

unique 唯一

not null 非空

null 可以为空

default 默认值

primary key --->主键==(非空+唯一)加速查询

auto_increment 自动增长‘

foreign key 外键约束,保证两张表的关系是完整的

级联操作 :用在外键关联中,可以级联的删除或更新从表记录