数据库之表关系
一、字段操作
#创建一个tf1表,id为主键并且自增,x,y都为int型
create table tf1(
id int primary key auto_increment,
x int,
y int);
'''修改'''
1)
eg:alter table tf1 modify x char(4) default '哈哈';
#将x的数据类型设为char,并增加默认值'哈哈'
2)
eg:alter table tf1 change y m char(4) default '嘻嘻嘻';
#将y的字段名修改为m,并将数据类型修改为char,并增加默认值
'''增加'''
1)
alter table 表名 add 新字段 类型[长度] 约束
eg:alter table tf1 add z int unsigned; #末尾添加
2)
alter table 表名 add 新字段 类型[长度] 约束 first;
eg:alter table tf1 add m int unsigned first; #首位添加
3)
alter table 表名 add 新字段 类型[长度] 约束 after 旧字段名; #某字段之后添加
eg:alter table tf1 add n int unsigned after x; #在x字段之后添加
'''删除'''
drop 删除表、字段
delete 删除数据
alter table 表名 drop 字段名; #删除字段
eg:alter table tf1 drop x; #删除x字段
二、多表关系
什么是外键?
建立多表关联的时候,通常一个表的外键另是一个表的主键(唯一键也可以)
一对一:学生表-学生简介表(一个学生只对应一个学生简介,一个学生简介也只对应一个学生)
一对多: 国家表-学生表 (一个学生只有一个国家,一个国家可以有多个学生)
多对多:学生表-课程表(一个学生可以选择多门课程,一门课程也可以有多个学生来上)
2.1 一对一
无联级关系:学生-学生简介
'''学生简介表'''
# stu_msg:id stu_msg
create table student_msg(
id int primary key auto_increment, #id为主键且自增
stu_msg varchar(256));
'''学生表'''
#student:id name age msg_id
create table student(
id int primary key auto_increment, #id为主键且自增
name varchar(64) not null, #name不为空
age int not null, #age不为空
msg_id int unique not null, #设置简介id,一定要设置为唯一键不为空,这样才能实现一对一
foreign key(msg_id) references student_msg(id)
# msg_id 为student表的外键,关联的学生信息表的id
);
-------------------------------------------
我们要先要创建学生详情表,再创建学生表
***牢记:必须先创建被关联表数据,有关联表外键关联的记录后,关联表才可以创建数据
'''插入表字段'''
insert into student_msg(stu_msg) values('student msg haha'),('this is stu msg');
+----+------------------+
| id | stu_msg |
+----+------------------+
| 1 | student msg haha |
| 2 | this is stu msg |
+----+------------------+
insert into student(name,age,msg_id) values('yjy',21,1),('wwb','23',2);
+----+------+-----+--------+
| id | name | age | msg_id |
+----+------+-----+--------+
| 1 | yjy | 21 | 1 |
| 2 | wwb | 23 | 2 |
+----+------+-----+--------+
'''删除表字段'''
delete from student_msg where id = 1; #删除不了,因为被student表关联着
delete from student where msg_id = 1; #直接就删除了
***没有级联关系下***:
# 增加:先增加被关联表记录,再增加关联表记录
# 删除:先删除关联表记录,再删除被关联表记录
# 更新:关联与,被关联表都无法完成 关联的外键和主键 数据更新 - (如果被关联表记录没有被绑定,可以修改)
有联级关系:学生-学生简介
'''学生简介表'''
# stu_msg:id stu_msg
create table student_msg(
id int primary key auto_increment, #id为主键且自增
stu_msg varchar(256));
'''学生表'''
#student:id name age msg_id
create table student(
id int primary key auto_increment, #id为主键且自增
name varchar(64) not null, #name不为空
age int not null, #age不为空
msg_id int unique not null, #设置简介id,一定要设置为唯一键不为空,这样才能实现一对一
foreign key(msg_id) references student_msg(id)
# msg_id 为student表的外键,关联的学生信息表的id
on update cascade #联级更新
on delete cascade #联级删除
);
***牢记:必须先创建被关联表数据,有关联表外键关联的记录后,关联表才可以创建数据
'''修改关联表'''
update student set msg_id=3 where msg_id=2; # 失败,3详情不存在
update student set msg_id=1 where msg_id=2; # 失败,1详情已被关联
update student set msg_id=3 where msg_id=2; # 有未被其他数据关联的数据,就可以修改
'''修改被关联表'''
update student_msg set id=10 where id=1; # 级联修改,同步关系关联表外键,学生信息表改了,学生表里面的msg_id也会变
'''删除关联表'''
delete from student where msg_id=2;# 可以删除对被关联表无影响
'''删除被关联表'''
mysql>: delete from student_msg where msg=10; # 直接删除,关联表会被级联删除
2.2 一对多
国家表-学生表
***一对多:外键必须放在多的一方,此时外键值不唯一,也就是说外键必须放在学生表
'''创建国家表'''
#country:id,name,address
create table country(
id int primary key auto_increment,
name varchar(64) not null,
address varchar(256));
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | NULL | |
| address | varchar(256) | YES | | NULL | |
+---------+--------------+------+-----+---------+----------------+
'''创建学生表'''
#student:id,name,age,country_id
create table student(
id int primary key auto_increment,
name varchar(64) not null,
age int not null,
country_id int,
foreign key(country_id) references country(id)
on update cascade
on delete cascade
)
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| country_id | int(11) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
'''增'''
先增加被关联表(country)的数据,再增加关联表(student)的数据
#插入被关联表(country)信息
insert into country(name,address) values('china','gansu'),('canada','xixi'),('china','shanghai');
+----+--------+----------+
| id | name | address |
+----+--------+----------+
| 1 | china | gansu |
| 2 | canada | xixi |
| 3 | china | shanghai |
+----+--------+----------+
#插入关联表(student)信息
insert into student(name,age,country_id) values('yjy','21', 1),('wwb','23',3);
insert into student(name,age,country_id) values('hhh','21', 5); # 失败 没有被关联的字段,插入依旧错误
'''更新'''
#更新被关联表
update country set id=10 where id=1;
*** 直接更新被关联表的(country) 主键,关联表(student) 外键 会级联更新,(这个就好比后台更新游戏,不影响用户的游戏体验)
#更新关联表
update student set country=2 where id=3; # 成功
update student set country=4 where id=3; # 失败
***直接更新关联表的(student) 外键,修改的值对应被关联表(country) 主键 如果存在,可以更新成功,反之失败
'''删除'''
# 删被关联表,关联表会被级联删除
delete from country where id = 2;
# 删关联表,被关联表不会发生变化
delete from student where country = 3;
2.3 多对多
学生表-课程表
***牢记***
多对多:一定要创建第三张表(关系表),每一个外键值不唯一,看可以多个外键建立联合唯一
两张被关联表,没有前后关系,但关系表必须在两个表都提供数据后才能进行 关系匹配
#学生表:id name age
create table student(
id int primary key auto_increment,
name char(4) not null,
age int default 0
);
#课程表:id name
create table course(
id int primary key auto_increment,
name varchar(64));
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
#学生_课程关系表:id, c_id, s_id
create table s_c(
id int primary key auto_increment,
#关联课程表
c_id int,
foreign key(c_id) references course(id)
on update cascade
on delete cascade,
# 关联学生表
s_id int,
foreign key(s_id) references student(id)
on update cascade
on delete cascade,
# 建立两个字段的联合唯一
unique(c_id, s_id)
);
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| c_id | int(11) | YES | MUL | NULL | |
| s_id | int(11) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+----------------+
'''注:关系表 关联着 学生表 和 课程表 两张表,在表结构上 学生表和课程表 两表之间的键 没有任何关系,和第三张表才有关系'''
'''关系表操作:增、删、改,只要两张被关系表有提供对应的操作数据,都可以操作成功,且对两张被关系表没有影响'''
'''增'''
#插入学生信息
insert into student(name,age) values('yjy',21),('wwb','23');
+----+------+-----+
| id | name | age |
+----+------+-----+
| 1 | yjy | 21 |
| 2 | wwb | 23 |
+----+------+-----+
#插入课程信息
insert into course(name) values('语文'),('数学'),('英语');
+----+--------+
| id | name |
+----+--------+
| 1 | 语文 |
| 2 | 数学 |
| 3 | 英语 |
+----+--------+
insert into course(name) values('体育'); #不会影响关系表
#插入学生_课程信息
insert into s_c(c_id,s_id) values(1,1),(3,2),(2,1),(2,3);
'''改'''
update course set id=10 where id=1; #关系表都会级联更新
'''删除'''
delete from student where name='wwb'; #关系表都会级联删除