关系

多对多的关系,如何通过mysql来表示

站在老师的角度

一个老师可以教多个学生,

一个老师也可以教一个学生。

站在学生的角度

一个学生可以被一个老师教

一个学生也可以被多个老师教

结论:如果站在两边看都是一对多的情况,那么这个关系就是多对多的。
问题:

如果表示a老师教过x学生和y学生,x学生和y学生同时也被b老师教

解决方法

多对多关系,无论是把外键放在哪一张表都不合适,因为可能有多个值

解决方案:建立一个中间的关系表

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); # 现在已知老师名称为bgon,请找出他教过的那些学生
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) # 已知学生名为老李,请查询出哪些老师教过他.
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)
总结:
  1. 如何确认多对多的关系?

    站在两个表的角度去想

  2. 处理方式,通过在两个表中间建立一个外键表,该外键表分别都关联两表的字段。

联合唯一约束

对于上面的t_s_r表进行改进
# 原表
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 ; # 改进方法一(表已创建的情况下):unique key
alter table t_s_r add unique key(t_id,s_id); # 改进方法二(表没创建的情况下):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 ; # 联合主键
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表进行改进------最终版
# 创建学生表
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(
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); # 问题:现在已知老师名称为bgon,请找出他教过的那些学生
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) # 问题:已知学生名为老李,请查询出哪些老师教过他.
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)

一对一关系

例如:每一个人都有一个身份证。一个身份证只对应一个人

分表:
  1. 垂直分表,例如:人物的详细信息,就可以垂直分表

    # 全表
    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;
  2. 水平分表

    数据量很大,使用一个表,查询效率低,使用两个表来存取这些数据

处理一对一关系处理方式:
  1. 先确定先后顺序

  2. 将先存在的数据作为主表

  3. 后存在的作为从表

  4. 使两个表的id保持一一对应

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

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

人物关系表,从客户演变为学生:

# 创建客户表
create table kehu_t(
id int primary key auto_increment,
name char(10),
phone char(11)
) # 创建学生表
create table student_t(
id int primary key auto_increment,
card_id char(18)
)
为什么要分表:
  1. 数据分担在多个表,提高了查询的效率

MySQL之关系的更多相关文章

  1. MySQL主从关系设置(转)

    来源:LAMP兄弟连 作者:李恺 http://***/php/bencandy.php?fid=70&id=635 要做MySQL主从关系的设置,那么就得有两台MySQL主机.所以在开始之前 ...

  2. 用mysql workbench导出mysql数据库关系图

    用mysql workbench导出mysql数据库关系图 1. 打开mysql workbench,选择首页中间"Data Modeling"下方的第二栏"Create ...

  3. mysql 表关系 与 修改表结构

    目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...

  4. java类型 jdbcType类型 mysql类型关系

    java类型 jdbcType类型 mysql类型关系 Java类型 JdbcType Mysql类型 备注 String VARCHAR VARCHAR 变长字符串 String LONGVARCH ...

  5. 使用MySQL Workbench导出MySQL数据库关系图

    1. 点击MySQL Workbench中间Data Modeling下的Create EER Model From Existing Database: 2. 在Stored Connection中 ...

  6. mysql实体关系(mysql学习五)

    实体关系  表设计 1:1 两个实体表内,存在相同的主键字段 如果记录的主键值等于另一个关系表内记录的主键值,则两条记录的对应为一一对应 优化上称为垂直分割 1:n 一个实体对应多个其他实体(一个班级 ...

  7. mysql 各种关系代数的使用

    连接(JOIN) 选择运算表示为: R⋈S ,其中R和S为不同的两个关系 连接运算是选取两个指定关系中的属性满足给定条件的元祖连接在一起来组成一个新的关系 数学形式: JOIN 关系名1 AND 关系 ...

  8. 如何保障MySQL主从复制关系的稳定性?关键词(新特性、crash-safe)

    一 前言 MySQL 主从架构已经被广泛应用,保障主从复制关系的稳定性是大家一直关注的焦点.MySQL 5.6 针对主从复制稳定性提供了新特性: slave 支持 crash-safe.该功能可以解决 ...

  9. mysql复制关系

    一旦建立好主从复制关系后就不要在从库上执行任何dml和ddl操作,包括创建用户也不行. 那么万一在从库上执行了dml或者ddl操作了,会有何影响,以及如何恢复? slave同步状态中出现Slave_S ...

随机推荐

  1. Wx-小程序-组件式开发之Vant

    开始:https://youzan.github.io/vant-weapp/#/intro 小程序开发者工具中 -->工具栏-->构建npm 一.初始化package.json npm ...

  2. 各种颜色空间之间的转换算法(XYZ → Standard-RGB ,Standard-RGB → XYZ)

    http://www.easyrgb.com/en/convert.php#Result http://www.easyrgb.com/en/math.php

  3. windows10 -- mysql5.5 + python3.4 + django1.11 +pycharm2016.2 + PyMySQL(DB DRIVER) 环境搭建

    环境介绍 2016-07-2513:32:26 name value comment OS win10 操作系统 python python3.4 python主程序 IDE pycharm:  20 ...

  4. [Python] Tkinter的食用方法_01_简单界面

    #开始 放假之后感觉整个人已经放飞自我了,完全不知道自己一天天在干什么,明明有很多的事情需要做,但是实际上每天啥都没做,,,虚度光阴... 晚上突然心烦意乱,开始思考今天一天都做了什么,感觉很有负罪感 ...

  5. 微信支付开发h5调用

    这两天做微信支付开发.碰到大坑.纠结死我了.好不容做完. 后台java:直接上代码:注意区分前后端的变量大小写... @RequestMapping(value = "/index" ...

  6. js分享微信 ,微博 ,qq空间

    目前pc微信分享,是通过扫描二维码进行分享 var _title,_source,_sourceUrl,_pic,_showcount,_desc,_summary,_site, _width = , ...

  7. python实现基于百度路径规划接口的坐标对获取两点驾车距离的计算

    今天为大家介绍一种通过python实现坐标对间距离数据的获取方法.接口采用百度开发的路径规划接口. 1.调用接口: 接口:(传入起点坐标串,结束坐标串:ak值需要注册百度开发者) 接口详细说明 htt ...

  8. 计算机二级-C语言-程序修改题-190113记录-对指定字符串的大小写变换处理。

    //给定程序中fun函数的功能是:将p所指的字符串中每个单词的最后一个字母改成大写.(这里的“单词”是指由空格隔开的字符串) //重难点:指针对数组的遍历.大小写转换的方法.第一种使用加减32 得到, ...

  9. WinForm开发(3)——使用vs2017打包winform安装程序的过程

    一.安装打包插件 注:安装好重启vs2017 ​ ​ 二.打包过程 ​ ​ 添加文件入口 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​

  10. Http 状态码总结

    HTTP 状态码列表 一. 1 开头 (继续执行) 服务器收到请求,需要请求者继续执行操作 100:(continue) 客户端继续请求 101:(Switching Protocols) 切换协议, ...