mysql 关系_MySQL之关系
關(guān)系
多對多的關(guān)系,如何通過mysql來表示
站在老師的角度
一個(gè)老師可以教多個(gè)學(xué)生,
一個(gè)老師也可以教一個(gè)學(xué)生。
站在學(xué)生的角度
一個(gè)學(xué)生可以被一個(gè)老師教
一個(gè)學(xué)生也可以被多個(gè)老師教
結(jié)論:如果站在兩邊看都是一對多的情況,那么這個(gè)關(guān)系就是多對多的。
問題:
如果表示a老師教過x學(xué)生和y學(xué)生,x學(xué)生和y學(xué)生同時(shí)也被b老師教
解決方法
多對多關(guān)系,無論是把外鍵放在哪一張表都不合適,因?yàn)榭赡苡卸鄠€(gè)值
解決方案:建立一個(gè)中間的關(guān)系表
create table student(
id int primary key auto_increment,
name char(10)
) charset utf8;
create table teacher(
id int primary key auto_increment,
name char(10)
) charset utf8;
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)
) charset utf8 ;
insert into teacher values(null,"bgon"),(null,"nike");
insert into student values(null,"老王"),(null,"老李");
# 老王被bgon教過
insert into t_s_r values(null,1,1);
# nike教過老李
insert into t_s_r values(null,2,2);
# nike教過老王
insert into t_s_r values(null,2,1);
# 現(xiàn)在已知老師名稱為bgon,請找出他教過的那些學(xué)生
mysql> select id from teacher where name="bgon";
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
mysql> select s_id from t_s_r where t_id=1;
+------+
| s_id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select name from student where id=1;
+--------+
| name |
+--------+
| 老王 |
+--------+
# 子查詢
mysql> select name from student where id=(select s_id from t_s_r where t_id=(select id from teacher where name="bgon"));
+--------+
| name |
+--------+
| 老王 |
+--------+
1 row in set (0.00 sec)
# 已知學(xué)生名為老李,請查詢出哪些老師教過他.
mysql> select id from student where name = "老李";
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.00 sec)
mysql> select t_id from t_s_r where s_id=2;
+------+
| t_id |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
mysql> select name from teacher where id=2;
+------+
| name |
+------+
| nike |
+------+
1 row in set (0.00 sec)
# 子查詢
mysql> select name from teacher where id=(select t_id from t_s_r where s_id=(select id from student where name = "老李"));
+------+
| name |
+------+
| nike |
+------+
1 row in set (0.00 sec)
總結(jié):
如何確認(rèn)多對多的關(guān)系?
站在兩個(gè)表的角度去想
處理方式,通過在兩個(gè)表中間建立一個(gè)外鍵表,該外鍵表分別都關(guān)聯(lián)兩表的字段。
聯(lián)合唯一約束
對于上面的t_s_r表進(jìn)行改進(jìn)
# 原表
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),
) charset utf8 ;
# 改進(jìn)方法一(表已創(chuàng)建的情況下):unique key
alter table t_s_r add unique key(t_id,s_id);
# 改進(jìn)方法二(表沒創(chuàng)建的情況下):unique key
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)
) charset utf8 ;
# 聯(lián)合主鍵
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),
primary key(t_id,s_id)
) charset utf8 ;
對于上面的t_s_r表進(jìn)行改進(jìn)------最終版
# 創(chuàng)建學(xué)生表
create table student(
id int primary key auto_increment,
name char(10)
) charset utf8;
# 創(chuàng)建教師表
create table teacher(
id int primary key auto_increment,
name char(10)
) charset utf8;
# 創(chuàng)建學(xué)生和老師關(guān)系表
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)
) charset utf8 ;
insert into teacher values(null,"bgon"),(null,"nike");
insert into student values(null,"老王"),(null,"老李");
# 老王被bgon教過
insert into t_s_r values(null,1,1);
# nike教過老李
insert into t_s_r values(null,2,2);
# nike教過老王
insert into t_s_r values(null,2,1);
# 問題:現(xiàn)在已知老師名稱為bgon,請找出他教過的那些學(xué)生
mysql> select id from teacher where name="bgon";
+----+
| id |
+----+
| 1 |
+----+
1 row in set (0.00 sec)
mysql> select s_id from t_s_r where t_id=1;
+------+
| s_id |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select name from student where id=1;
+--------+
| name |
+--------+
| 老王 |
+--------+
# 整合查詢語句:子查詢
mysql> select name from student where id=(select s_id from t_s_r where t_id=(select id from teacher where name="bgon"));
+--------+
| name |
+--------+
| 老王 |
+--------+
1 row in set (0.00 sec)
# 問題:已知學(xué)生名為老李,請查詢出哪些老師教過他.
mysql> select id from student where name = "老李";
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.00 sec)
mysql> select t_id from t_s_r where s_id=2;
+------+
| t_id |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
mysql> select name from teacher where id=2;
+------+
| name |
+------+
| nike |
+------+
1 row in set (0.00 sec)
# 整合查詢語句:子查詢
mysql> select name from teacher where id=(select t_id from t_s_r where s_id=(select id from student where name = "老李"));
+------+
| name |
+------+
| nike |
+------+
1 row in set (0.00 sec)
一對一關(guān)系
例如:每一個(gè)人都有一個(gè)身份證。一個(gè)身份證只對應(yīng)一個(gè)人
分表:
垂直分表,例如:人物的詳細(xì)信息,就可以垂直分表
# 全表
create table person(
id int primary key auto_increment,
name char(10),
age int,
height float,
weigth float
)
# 垂直分表:person
create table person(
id int primary key auto_increment,
name char(10),
age int
) charset utf8;
# 垂直分表:person_info
create table person_info(
id int primary key,
height float,
weigth float,
foreign key(id) references person(id)
) charset utf8;
水平分表
數(shù)據(jù)量很大,使用一個(gè)表,查詢效率低,使用兩個(gè)表來存取這些數(shù)據(jù)
處理一對一關(guān)系處理方式:
先確定先后順序
將先存在的數(shù)據(jù)作為主表
后存在的作為從表
使兩個(gè)表的id保持一一對應(yīng)
方法1:從表的id即是主鍵又是外鍵
方法2:從表的id設(shè)置為外鍵,并保證唯一
人物關(guān)系表,從客戶演變?yōu)閷W(xué)生:
# 創(chuàng)建客戶表
create table kehu_t(
id int primary key auto_increment,
name char(10),
phone char(11)
)
# 創(chuàng)建學(xué)生表
create table student_t(
id int primary key auto_increment,
card_id char(18)
)
為什么要分表:
數(shù)據(jù)分擔(dān)在多個(gè)表,提高了查詢的效率
總結(jié)
以上是生活随笔為你收集整理的mysql 关系_MySQL之关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android入门(八) | 常用的界面
- 下一篇: leetcode1075. 项目员工 I