关系

多对多的关系,如何通过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. 手动搭建的react环境中,关于图片引入的问题

    react手动搭建的环境,require引进来图片不显示,网页src显示[object module] 解决方案 (1)import引进图片 import anli from './img/anli. ...

  2. python代码在linux终端中执行报错:Unable to init server: Could not connect: Connection refused

    python代码在linux终端中执行时报错: Unable to init server: Could not connect: Connection refused Unable to init ...

  3. sqlmap+burpsuit

    sqlmap可以批量扫描burpsuit导出的requests日志文件,从而进行批量扫描是否存在SQL注入. 首先设置burpsuit记录代理的Requests 把记录的日志文件保存在sqlmap的目 ...

  4. php 加解密函数

    PHP 加密解密函数: /** * 系统加密方法 * @param string $data 要加密的字符串 * @param string $key 加密密钥 * @param int $expir ...

  5. jquery 根据值 设置radio选中

    $("[name='selector'][value='value']").prop("checked", "checked");

  6. bugku 过狗一句话

    题目描述: 题目描述:                                上面的php进行格式化之后: <?php     $poc="a#s#s#e#r#t"; ...

  7. radhat 6.7修改mac地址方法

    vi ifcfg-eth0 #HW……,即注释掉原硬件地址. 再自己照着原地址写:MACADDR="新mac地址" 重启

  8. Python函数基础进阶

    函数参数的另一种使用方式 def print_info(name,age): print("Name: %s" %name) print("age: %d" % ...

  9. 企业级Docker镜像仓库Harbor部署与使用

    yum install docker 官网地址:https://docs.docker.com/compose/install/ 运行此命令以下载Docker Compose的当前稳定版本 1 sud ...

  10. java语法基础--动手动脑问题及课后实验问题

    ---恢复内容开始--- 动手动脑: 1:仔细阅读示例:EnumTest.java,运行它,分析运行结果 结果 :枚举类型是引用类型!枚举类型不属于原始数据类型,它的每个具体指都引用一个特定的对象.相 ...