MySQL之关系
关系
多对多的关系,如何通过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)
总结:
如何确认多对多的关系?
站在两个表的角度去想
处理方式,通过在两个表中间建立一个外键表,该外键表分别都关联两表的字段。
联合唯一约束
对于上面的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)
一对一关系
例如:每一个人都有一个身份证。一个身份证只对应一个人
分表:
垂直分表,例如:人物的详细信息,就可以垂直分表
# 全表
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;
水平分表
数据量很大,使用一个表,查询效率低,使用两个表来存取这些数据
处理一对一关系处理方式:
先确定先后顺序
将先存在的数据作为主表
后存在的作为从表
使两个表的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)
)
为什么要分表:
- 数据分担在多个表,提高了查询的效率
MySQL之关系的更多相关文章
- MySQL主从关系设置(转)
来源:LAMP兄弟连 作者:李恺 http://***/php/bencandy.php?fid=70&id=635 要做MySQL主从关系的设置,那么就得有两台MySQL主机.所以在开始之前 ...
- 用mysql workbench导出mysql数据库关系图
用mysql workbench导出mysql数据库关系图 1. 打开mysql workbench,选择首页中间"Data Modeling"下方的第二栏"Create ...
- mysql 表关系 与 修改表结构
目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...
- java类型 jdbcType类型 mysql类型关系
java类型 jdbcType类型 mysql类型关系 Java类型 JdbcType Mysql类型 备注 String VARCHAR VARCHAR 变长字符串 String LONGVARCH ...
- 使用MySQL Workbench导出MySQL数据库关系图
1. 点击MySQL Workbench中间Data Modeling下的Create EER Model From Existing Database: 2. 在Stored Connection中 ...
- mysql实体关系(mysql学习五)
实体关系 表设计 1:1 两个实体表内,存在相同的主键字段 如果记录的主键值等于另一个关系表内记录的主键值,则两条记录的对应为一一对应 优化上称为垂直分割 1:n 一个实体对应多个其他实体(一个班级 ...
- mysql 各种关系代数的使用
连接(JOIN) 选择运算表示为: R⋈S ,其中R和S为不同的两个关系 连接运算是选取两个指定关系中的属性满足给定条件的元祖连接在一起来组成一个新的关系 数学形式: JOIN 关系名1 AND 关系 ...
- 如何保障MySQL主从复制关系的稳定性?关键词(新特性、crash-safe)
一 前言 MySQL 主从架构已经被广泛应用,保障主从复制关系的稳定性是大家一直关注的焦点.MySQL 5.6 针对主从复制稳定性提供了新特性: slave 支持 crash-safe.该功能可以解决 ...
- mysql复制关系
一旦建立好主从复制关系后就不要在从库上执行任何dml和ddl操作,包括创建用户也不行. 那么万一在从库上执行了dml或者ddl操作了,会有何影响,以及如何恢复? slave同步状态中出现Slave_S ...
随机推荐
- Bug搬运工-CSCux99539:Intermittent error message "Power supply 2 failed or shutdown"
Description Symptom:Following error messages will be seen intermittently.%PFMA-2-PS_FAIL: Power supp ...
- Eclipse代码规范
配置代码自动格式化 1.导入规范文件 codeStyle.xml <?xml version="1.0" encoding="UTF-8" standa ...
- 【转】VMware Converter迁移linux系统虚拟机
原始出处 今天接到一个需求,迁移一台linux的业务系统到vCenter云管理平台,其中遇到一些问题,于是进行了排错,这个过程与大家分享,下面把整个步骤进行截图说明. 1. 首先,登录到VMware ...
- XFire调用CXF参数为Null的问题
最近,领导分配了一个任务,做接口联调.情况是这样,对方客户升级了接口采用CXF,而我们还是用的XFire1.2.6,首先就遇到了这个问题:XFire调用CXF参数为Null的问题 . 在网上搜了一大堆 ...
- 使用python同时替换json多个指定key的value
1.如何同时替换json多个指定key的value import json from jsonpath_ng import parse def join_paths(regx_path,new_val ...
- javascipt——jQuery
1.首先需要导入jQuery1.12.4.js文件,把文件和当前目录放同一目录下.在<body>中写上<script scr = 'jQuery1.12.4.js'><s ...
- js遍历传参到html
<p id="subp" hidden><button id= "upsub"shiro:hasPermission="sys:me ...
- [采坑记录] OneDrive同步失败 不能自动上传 不能同步 不能登陆
虽然OneDrive送的空间并不大 但是用来传文档什么的还是够了 但是国内各种不舒服 比如说登陆不上(其他的微软系应用解决方法同理) 原因是因为DNS污染的问题 默认电脑链接上网络之后 DNS是路由器 ...
- Chrome浏览器切页快捷键
Chrome浏览器切换标签页快捷键 1.Ctrl + Tab 向左切换标签页 2.Ctrl + shift + Tab 向右切换 3.Ctrl + 1 切换到第一个页面 4.Ctrl + 9 切换到最 ...
- Kosaraju's algorithm
推荐到我的这篇博客中看完整版的. 该算法用于求解有向图的强连通分量,也就是强连通子图的个数. 算法实现摘自Kosaraju's algorithm - 百度百科: #include <iostr ...