关系

多对多的关系,如何通过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. ISR模块

    SM-SRE-700-K9:先来介绍一下这个模块 Q:它是用来干嘛的?A:思科服务就绪引擎模块是思科集成多业务路由器第2代(ISR G2)的高性能路由器刀片,可提供托管思科,第三方和自定义应用程序的功 ...

  2. Java - Test - TestNG: testng.xml 简介

    1. 概述 简介 testng.xml 中的格式, 元素 2. 背景 testng.xml 概述 测试套件 的配置文件 问题 一下生成了那么多内容 我有点看不懂 一上来就看不懂, 其实很正常, 慢慢说 ...

  3. css颜色+透明度的写法

    今天在学习页面的时候,看到视频里用到颜色的十六进制表达式直接设置透明度,但是后来在实践过程中发现是有误的,特此记录一下,也算是学习了一个新知识. RGBA表示式 比如我们设置rgba(0, 0, 0, ...

  4. 五分钟学Java:打印Java数组最优雅的方式是什么?

    在逛 Stack Overflow 的时候,发现了一些访问量像‎安第斯山一样高的问题,比如说这个:打印 Java 数组最优雅的方式是什么?访问量足足有 220W+,想不到啊,这么简单的问题竟然有这么多 ...

  5. Qt: 释放窗口资源

    1. 对于使用指针,使用new创建的窗口,当然可以使用delete显示的释放其占用的资源: Widget *w = new Widget(); delete w;   2. 对于使用指针,使用new创 ...

  6. 创建Maven project 提示pom.xml 首行错误

    背景 使用eclipse创建Maven SpringBoot 2.2.0 项目时报错,更换springboot 版本也不行,排除框架依赖原因.然后别人的eclipse创建的同样2.2.2 maven项 ...

  7. ztree-编辑节点(树节点添加,删除,修改)

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - addNodes / editName / rem ...

  8. 神奇的requestAnimationFrame解决传统定时器bug

    可能你还没见过这个东西是个啥,其实他就是类似于setTimeout和setInterval,然而它与setTimeout和setInterval又有所不同,requestAnimationFrame不 ...

  9. 用纯css实现双边框效果

    1. box-shadow:0 0 0 1px #feaa9e,0 0 0 5px #fd696f 2. border:1px solid #feaa9e; outline:5px solid #fd ...

  10. QGridLayout栅格布局函数参数设置

    对于PyQt5的栅格布局函数,主要是实现多个控件之间的栅格布局形式,一般有两种设置方式: 1.Qdesigner布局设置时直接使用栅格布局函数,便可以把所需要布局的控件直接按照栅格方式来进行布局: 2 ...