一、多對多
1、如何確定多對多關系
例如 老師表 和 學生表
套路一樣 先站在老師表 在站在學生表
老師表角度: 一個老師可以對應多個學生 一對多
學生表角度: 一個學生可以對應多個老師 一對多
如果雙方都是一對多的關系 那么 兩者是多對多關系
2、處理方式
建立一個中間表,用於存儲關系,至少具備兩個字段分別指向老師和學生的主鍵,兩個字段都是外鍵 如下:
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);
# 創建表時指定 多字段聯合唯一
create table t_s_r2(t_id int,s_id int,unique key(t_id,s_id));
方式2:
# 推薦 將中間的關系表 兩個id 作為聯合主鍵 同時具備了 唯一且非空約束
create table t_s_r3(t_id int,s_id int,primary key(t_id,s_id));
處理多對多關系
1.創建兩個主表 如學員 和 老師
2.創建關系表 包含兩個字段 分別設置外鍵 指向對應的表
3.將兩個字段 作為聯合主鍵
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 = "老李"
)
);
二、一對一關系
如一個客戶對應一個學生:
站在兩邊看都是一對一的關系,
1、處理方式,
確定先后順序
將先存在的數據作為主表
后存在的作為從表
使兩個表的id保持一一對應
方法1: 從表的id 即是主鍵又是外鍵
方法2:從表的id設置為外鍵 並保證唯一
2、案例:
# 人員表
create table person(
id int primary key auto_increment,
name char(10),
age int
);
# 詳情表
create table person_info(
id int primary key,
height float,
weight float,
foreign key(id) references person(id)
);
#再這樣的關系中 必須先插入主表即person 拿到一個id 在添加詳情表的數據
#將一條完整數拆分到不同表中,可以提高查詢的效率,上述方式稱之為垂直分表!