MySQL表关系--外键
一、外键前戏
如果我们把所有的信息都记录在一张表中会带来的问题:
1.表的结构不清晰
2.浪费磁盘空间
3.表的扩展性极差
所以我们要把这种表拆成几张不同的表,分析表与表之间的关系。
确定表与表之间的关系,一定要换位思考(必须两方都考虑周全之后才能得出结论)
学生与班级表:
1.站在学生的角度看班级:能否多个学生在一个班级 (一个班级能否有多个学生) 可以!!!
2.站在班级的角度看学生:能否有多个班级对应一个学生 (一个学生能否在多个班级) 不可以!!!
结论:学生表和班级表之间仅仅只是单向的多对一,那么它们的关系就是“一对多”(无论是多对一还是一对多,都叫‘一对多’)
所以学生表多对一班级表,在学生表中创建一个字段(class_id)指向班级表的id字段。
如何让两种表有代码层面上真正的关联,就必须使用外键 (foreign key)
什么是外键? 让表与表有硬性层面上的关系。
二、一对多
foreign key
外键约束
1.在创建表的时候,必须先创建被关联表
2.插入数据的时候,也必须先插入被关联表的数据
有员工表和部门表,之间是一对多的关系,通常将关系字段称之为外键字段,外键建在多的一方。(这里外键建在员工表中)
建表:
先建部门表(被关联表)
#部门表
create table dep(
id int primary key auto_increment,
dep_name varchar(20),
dep_sec varchar(20)
);
创建员工表 除了基本的员工字段,还有一个外键和部门表的id字段绑定关系
#员工表
create table emp(
id int primary key auto_increment,
emp_name varchar(10),
emp_gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id) #dep_id是外键字段并且和dep表id字段有关系
);
插入数据:
部门表先插数据
insert into dep(dep_name,dep_desc) values('技术部','提供技术服务'),
('后勤部','后勤保障'),
('财务部','发工资');
员工表插数据 这里需要注意的点是你插入的dep_id一定要是部门表中存在的,否则就会报错
insert into emp(emp_name,dep_id) values('jason',1),
('egon',2),
('tank',3);
修改表数据:
外键虽然能够帮你强制建立关系,但是也会给表之间增加数据相关的约束。
1.在删除数据的时候,要先删除员工表的数据,才能删除部门表的数据。
因为员工表中有外键关联字段部门表,所以直接删部门表的数据会报错
2.可以使用级联更新和级联删除
在外键加上 on update cascade on delete cascade
#员工表
create table emp(
id int primary key auto_increment,
emp_name varchar(10),
emp_gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id) #dep_id是外键字段并且和dep表id字段有关系
on update cascade
on delete cascade
);
update dep set id=200 where id = 3;
delete from dep where id = 2;
三、多对多
图书与作者表 换位思考
1.先站在图书表:多本书能否是有一个作者(一个作者能否写多本图书 ) 可以!!!
2.站在作者表:多个作者能否合写一本书(一本书能否有多个作者) 可以!!!
如果双方都是可以,那么就是多对多
强调!!! foreign key只是用来帮你建表关系的,不是某个关系特有的方法
多对多关系的建立,必须手动创建第三张表,用来专门记录两种表之间的关系
建表
先建两种普通的表,不需要设置外键
图书表
create table book(
id int primary key auto_increment,
title varchar(10),
price int
);
作者表
create table author(
id int primary key auto_increment,
name varchar(20),
age int
);
关联表 两个外键(一个book_id关联book表的id字段,一个author_id关联author表的id字段)
create table book2author(
id int primary key auto_increment,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade,
author_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
);
插入数据
图书表插入数据:
insert into book(title,price) values('西游记',50),('水浒传',80),('红楼梦',60);
作者表插入数据:
insert into author(name,age) values('小红',30),('小兰',40),('小绿',50);
关联表插入数据:
insert into book2author(book_id,author_id) values(1,1),(1,2),(2,1),(1,2),(3,1);
四、一对一关系
一对一的场景,当你的表特别庞大的时候,你可以考虑拆分表
比如一张表里面有客户基本信息(名字,年龄),还有详细(爱好,身高,身份证号。。。)
外键字段建在任意一方都可以,但是推荐你建在查询频率高的一方
建表
用户表:因为用户表中含有外键所以应该先建用户详细表
create table user(
id int primary key auto_increment,
name varchar(10),
age int,
userdetail_id int unique, #唯一,一对一关系
foreign key(userdetail_id) references userdetail(id)
on update cascade
on delete cascade
);
用户详细表
create table userdetail(
id int primary key auto_increment,
hobby varchar(20),
IDcard varchar(20)
);
总结:
1.通常将关系字段称之为外键字段
一对多的外键字段,建在多的一方
多对多的外键字段,建在第三张表
一对一,外键字段建在任意一方都可以,推荐建在查询频率高的那边
2.判断表关系的最简单的方法:
图书与出版社
一本书可不可以有多个出版社 不可以!!!
一个出版社可不可以出多本书 可以!!!
一对多的关系
图书与作者表
一本书可不可以有多个作者 可以!!!
一个作者可不可以出多本书 可以!!!
多对多的关系
作者与作者详情
一个作者可不可以有多个详情 不可以!!!
一个作者详情可不可以有多个作者 不可以!!!
要么两者是一对一,要么两者之间没有关系
了解知识点:
修改表
1.修改表的完整语句
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;
2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…]; #插入多条
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST; # 直接移到最前面
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名; # 寻找插哪个字段的后面
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段 # modify只能改字段数据类型完整约束,不能改字段名,但是change可以!
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…]; 复制表 # 查询语句执行的结果也是一张表,可以看成虚拟表
# 复制表结构+记录 (key不会复制: 主键、外键和索引)
create table new_service select * from service; #复制
# 只复制表结构
select * from service where 1=2; //条件为假,查不到任何记录
create table new1_service select * from service where 1=2;
create table t4 like employees;
MySQL表关系--外键的更多相关文章
- Django框架表关系外键-多对多外键(增删改查)-正反向的概率-多表查询(子查询与联表查询)
目录 一:表关系外键 1.提前创建表关系 2.目前只剩 书籍表和 书籍作者表没创建信息. 3.增 4.删 5.修改 二:多对多外键增删改查 1.给书籍绑定作者 2.删 3.修改 4.清空 三:正反向的 ...
- [MySQL]表创建外键失败:ERROR 1005 (HY000): Can't create table (errno: 150)
在数据库中建立一个新表(表引擎为InnoDB)时, 需要用到外键, 所以就在建表的时候加了一句foreign key (column) references table_name.但是执行时出现 ER ...
- Mysql表创建外键报错
数据库表A: CREATE TABLE task_desc_tab ( id INT(11) PRIMARY KEY NOT NULL COMMENT '自增主键' AUTO_INCREMENT, t ...
- MySQL表存在外键关系无法清空数据的解决方案
先 SET FOREIGN_KEY_CHECKS=0; 然后delete删除,再 SET FOREIGN_KEY_CHECKS=1;
- MySQL学习7 - 外键的变种 三种关系
一 介绍 二 如何找两张表之间的关系 三 表的三种关系 1.书和出版社 2.作者和书籍的关系 3.用户和博客 本节的重点 如何找出两张表之间的关系 表的三种关系 一 介绍 因为有foreign key ...
- MySQ-表关系-外键-修改表结构-复制表-03
目录 前言 不合理的表结构(案例) 带来的问题 如何解决问题? 如何确定表关系? 表关系 一对多 多对多 一对一 应用场景 判断表关系最简单的语法 三种关系常见案例 如何建立表关系? 外键 forei ...
- 【MySQL】MySQL进阶(外键约束、多表查询、视图、备份与恢复)
约束 外键约束 外键约束概念 让表和表之间产生关系,从而保证数据的准确性! 建表时添加外键约束 为什么要有外键约束 -- 创建db2数据库 CREATE DATABASE db2; -- 使用db2数 ...
- Oracle查找表的外键引用关系
Oracle查找表的外键引用关系 select t1.table_name, t2.table_name as "TABLE_NAME(R)", t1.constraint_nam ...
- MySQL删除所有表的外键约束、禁用外键约束
转: MySQL删除所有表的外键约束.禁用外键约束 2017年10月27日 00:11:34 李阿飞 阅读数:4512 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...
随机推荐
- 4.学习springmvc的响应数据和结果视图
一.返回值分类: 字符串:返回值为需要展示的视图 void:返回为默认的页面(方法名.jsp) ModleAndView:存储对象并返回设置的页面 1.字符串: jsp: <a href=&qu ...
- 获取shell脚本自身所在目录
解决了使用ln -s target linkName创造软链接无法正确取到真实脚本的问题. #!/bin/bash SOURCE="$0" while [ -h "$SO ...
- python字符串转整形异常
python字符串转整形异常 问题 在使用int("xx")转化字符串为整形时,如果字符串是float形式,这样转化会异常 int('3.0') Traceback (most r ...
- 模拟30A 题解
A. 树 联想起远古考试时做的题 记忆的轮廓. 树上走一些步数的期望. 显然可以直接解方程. 然而复杂度$O(qn^3)$,利用树上的性质优化一下, 直接一遍dfs过程中解出来,可以$O(qnlogm ...
- 淘宝接口-IP返回运营商
#!/usr/bin/evn python# -*- coding:utf-8 -*-import jsonimport urllib2import datetimeimport reimport Q ...
- js Map的使用
setExpenseAndAmountSum: function() { var detailList = vehicleVueObj.vehicleData; var expenseAmountSu ...
- DNA replication timing数据库 - Replication Domain
DNA Replication Timing ReplicationDomain: a visualization tool and comparative database for genome-w ...
- 解决:File "/usr/lib/python2.7/site-packages/more_itertools/more.py", line 340 def _collate(*iterables, key=lambda a: a, reverse=False): 的报错
cyberb commented on 15 Apr Traceback (most recent call last): File "/snap/users/x1/python/bin/l ...
- Linux performance monitor tool
https://www.tecmint.com/command-line-tools-to-monitor-linux-performance/ https://www.tecmint.com/lin ...
- java读取IFC文件
The IFC JAVA Toolbox can read IFC STEP files and IFCZIP files from any data source that implementsja ...