关系

多对多的关系,如何通过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. Codeforces Round #624 (Div. 3) A. Add Odd or Subtract Even(水题)

    You are given two positive integers aa and bb . In one move, you can change aa in the following way: ...

  2. 使用JDBC完成分类表CRUD的操作

    工具类 通过之前的案例回顾,不难发现,有很多的代码操作是重复的,比如“获取链接”和“释放资源”等,将来在增删改查中经常遇到,开发中遇到这种情况,将采用工具类的方法进行抽取,从而达到代码的重复利用. 此 ...

  3. Mac配置内网穿透

    闲语: Java开发过程中,往往会对接第三方,而在对接过程中,双方间使用的最多的"通讯"方式就是异步通知.可是异步通知过程中,只能通知到外网地址,可是在调试过程我们都是在本地进行- ...

  4. 【转】Vue.js 2.0 快速上手精华梳理

    Vue.js 2.0 快速上手精华梳理 Sandy 发掘代码技巧:公众号:daimajiqiao 自从Vue2.0发布后,Vue就成了前端领域的热门话题,github也突破了三万的star,那么对于新 ...

  5. opencv:图像查找表 与 颜色表

    LUT 使用 颜色查找表 example LUT applyColorMap // 读入制作好的lut.png Mat color = imread("D:/images/lut.png&q ...

  6. 微信js sdk分享开发摘记java版

    绑定域名和引入js的就不说了 废话不说直接上代码 public void share(HttpServletRequest request) throws Exception { StringBuff ...

  7. Java面向对象编程 -6

    数组的基本概念 数组的本质:一组相关变量的集合. 但是需要注意的一点是:在java里面讲数组定义为了引用数据类型,所以数组的使用一定要牵扯到内存分配,那么首先一定要想到使用关键字new来处理 数组的定 ...

  8. super this 关键字

    super 关键字的三种用法: 1.在子类成员方法中,访问父类成员变量 2.在子类成员方法中,访问父类成员方法 3.在子类构造方法中,访问父类构造方法 this 关键字的三种用法: 1.在本类的成员方 ...

  9. 07-Docker-Image深入理解

    目录 07-Docker-Image深入理解 参考 镜像简介 什么是Docker镜像 什么是Docker容器 镜像结构 镜像特性 镜像层 容器层 镜像存储 07-Docker-Image深入理解 Do ...

  10. js的JSON新方法和历史记录管理

    今天看妙味的视频,一下是一些简单的笔记: 1.JSON的一些新方法: JSON.stringify(); JSON.parse(); 第一个是把js脚本转换成JSON的字符串形式. 而第二个则是吧这种 ...