摘要:

  1. 外键 一对多
  2. 外键 多对多
  3. 外键 一对一

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一、引言:

我们在同一数据库创建的表时候,很多时候会出现相同数据的冗余问题,也就是说几个id会有一个或者同n个相同字段,这样就导致数据表结构数据重复冗余,

冗余还无所谓,关键是如果我要改其中一个相同的字段信息,其他跟他相同字段的信息也都要同步修改,这就增加了很多工作量,特别是如果要处理大量数据的时候

所以需要有一种解决方式来处理这种显而易见的问题。

例如:

id name gender dep_name dep_desc
1 jason male 外交部 形象代言人
2 egon male 教学部 教书育人
3 kevin male 教学部 教书育人
4 tank male 教学部 教书育人
5 jerry female 技术部 技术负责人

很显然,上表的id为2/3/4的人员同属于一个字段名(部门)教育部,部门描述也是一样。解决方法:拆分为2个表

+----+-------+--------+--------+
| id | name | gender | dep_id |
+----+-------+--------+--------+
| 1 | jason | male | 1 |
| 2 | egon | male | 2 |
| 3 | kevin | male | 2 |
| 4 | tank | male | 2 |
| 5 | jerry | female | 3 |
+----+-------+--------+--------+ +----+-----------+--------------------------+
| id | dep_name | dep_desc |
+----+-----------+--------------------------+
| 1 | 外交部 | 形象代言人 |
| 2 | 教育部 | 教书育人 |
| 3 | 技术部 | 技术负责人 |
+----+-----------+--------------------------+
"""
把所有数据都存放于一张表的弊端
1.组织结构不清晰
2.浪费硬盘空间
3.扩展性极差
"""
# 上述的弊端产生原因类似于把代码全部写在一个py文件中,你应该怎么做?>>>解耦合!将上述一张表拆成员工和部门两张表! # 分析表数据之间的关系:多个用户对应一个部门,一个部门对应多个用户。禁止一个用户对应多个部门 # 如何查找表与表之间的关系
"""
老师与课程表
1.站在老师表的角度:一名老师能否教授多门课程(限制死,不能,一名老师只能教python,不能同时教python和linux)
2.站在课程表的角度:一门课程能否可以被多个老师教,完全可以!
那就是课程表多对一老师表,如何表示这种关系?在课程表中创建一个字段(tea_id)指向老师表的id字段 学生与班级表
1.站在学生表的角度:???
2.站在班级表的角度:???
那就是学生表多对一班级表,如何表示这种关系?在学生表中创建一个字段(class_id)指向班级表的id字段
"""

二、一对多(foreign key)

foreign key 会将本表中的一个字段与另外一个表的字段(通常是主键字段)进行关联。

在创建表时,必须先建被关联的表dep,才能建关联表emp
create database foreign_ts; # 创建数据库
use foreign_ts; # 进入数据库
# 先创建被关联表:
create table dep(
id int primary key auto_increment, # 设置主键,自增长
dep_name char(16),
dep_desc char(16)
); # 再创建关联表emp:
create table emp(
id int primary key auto_increment, # 设置主键,自增长
name char(16),
gender enum('male','female','others'),
dep_id int,
foreign key(dep_id) references dep(id) # 外键 关联
on update cascade # 同步更新
on delete cascade # 同步删除
); # 插入数据:
在插入记录时,必须先插入被关联的表dep,才能插关联表emp
insert into dep(dep_name,dep_desc) values
('外交部','形象代言人'),('教育部','教书育人'),('技术部','技术能力有限部门'); insert into emp(name,gender,dep_id) values
('jason','male',1),
('egon','male',2),
('kevin','male',2),
('tank','male',2),
('jerry','female',3);

三、多对多:

一对多是A表中多个字段关联B表中一个字段。

而多对多就是在此基础上B表中也有多个字段关联A表中一个字段。

此时如果依然以上面一对多的形式去创建表格的话,就会出现互相矛盾的问题,也就是我再关联你的时候你还没有被创建的情况。

示例:

# 图书表与作者表之间的关系
"""
仍然站在两张表的角度:
1.站在图书表:一本书可以有多个作者
2.站在作者表:一个作者可以写多本书
双方都能一条数据对应对方多条记录,这种关系就是多对多!
"""
# 先来想如何创建表?图书表需要有一个外键关联作者,作者也需要有一个外键字段关联图书。问题来了,先创建谁都不合适!如何解决?
# 建立第三张表,该表中有一个字段fk左表的id,还有一个字段是fk右表的id
----------------------------------
先将2个表建起了:
mysql> create table author( #建作者表,id和name足以
-> id int primary key auto_increment,
-> name char(16)
-> ); mysql> create table book( # 建书表,id、书名、价格
-> id int primary key auto_increment,
-> title char(16),
-> price int
-> );
插入表数据:
mysql> insert into author(name) values
-> ('唐家三少'),
-> ('金庸'),
-> ('萧鼎')
-> ; mysql> insert into book(title,price) values
-> ('光之子',99),
-> ('冰火魔厨',88),
-> ('斗罗大陆',77),
-> ('倚天屠龙记',98),
-> ('神雕侠侣',96),
-> ('诛仙',100);
mysql> select* from author; # 查看建表结果
+----+--------------+
| id | name |
+----+--------------+
| 1 | 唐家三少 |
| 2 | 金庸 |
| 3 | 萧鼎 |
+----+--------------+
mysql> select* from book; # 查看建表结果
+----+-----------------+-------+
| id | title | price |
+----+-----------------+-------+
| 1 | 光之子 | 99 |
| 2 | 冰火魔厨 | 88 |
| 3 | 斗罗大陆 | 77 |
| 4 | 倚天屠龙记 | 98 |
| 5 | 神雕侠侣 | 96 |
| 6 | 诛仙 | 100 |
+----+-----------------+-------+
--------------------------------------------------------------------------
建立第三张表,这张表作用就是关联author表和book表。
mysql> 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 # 设置外键
-> );
# 插入关联数据
mysql> insert into book2author(book_id,author_id) values
-> (1,1),
-> (2,1),
-> (3,1),
-> (4,2),
-> (5,2),
-> (6,3);
# 查看结果:
mysql> select * from book2author;
+----+---------+-----------+
| id | book_id | author_id |
+----+---------+-----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 2 |
| 5 | 5 | 2 |
| 6 | 6 | 3 |
+----+---------+-----------+ 这样就将book表和author表之间通过第三张表建立了多对多外键关联。

四、一对一:

A表的字段与B表中的某一唯一字段形成一对一的关联

示例:

# 我们可以通过客户表和投保人之间的关系来描述一对一
保险销售人员有个客户表,在每天的不断努力经营客户之下,促进了多个客户成为了投保人,这个多个投保人作为一张投保人表,他们之间的关系可以说是一对一关系:
或者说是一种类似于集合的父集与子集的关系。
mysql> create table customer(
-> id int primary key auto_increment,
-> name char(16),
-> age int,
-> sex enum('male','female','other'),
-> wechart char(16)
-> ); mysql> create table holder( # 创建投保人表
-> id int primary key auto_increment,
-> name char(16),
-> holder_price int,
-> customer_id int unique, # 将客户id设为唯一,因为客户表中客户id必须唯一
-> foreign key(customer_id) references customer(id) on update cascade on delete cascade
-> ); # 客户id与客户表中id进行关联。同步改删
--------------------------------------------------
插入数据:(先插入客户表(被关联),再插入投保人表)
mysql> insert into customer(name,age,sex,wechart) values
-> ('张三丰',18,'male',''),
-> ('张小凡',16,'male',''),
-> ('陆雪琪',17,'female',''),
-> ('秦祥林',25,'male',''),
-> ('至尊宝',999,'male',''),
-> ('韦小宝',30,'male',''); mysql> insert into holder(name,holder_price,customer_id) values
-> ('张小凡',5000000,2),
-> ('陆雪琪',10000000,3),
-> ('韦小宝',990000,6); # 查看结果:
mysql> select * from customer;
+----+-----------+------+--------+-----------+
| id | name | age | sex | wechart |
+----+-----------+------+--------+-----------+
| 1 | 张三丰 | 18 | male | 17375898 |
| 2 | 张小凡 | 16 | male | 65652456 |
| 3 | 陆雪琪 | 17 | female | 62612384 |
| 4 | 秦祥林 | 25 | male | 545654655 |
| 5 | 至尊宝 | 999 | male | 66666666 |
| 6 | 韦小宝 | 30 | male | 475247124 |
+----+-----------+------+--------+-----------+
mysql> select * from holder;
+----+-----------+--------------+-------------+
| id | name | holder_price | customer_id |
+----+-----------+--------------+-------------+
| 1 | 张小凡 | 5000000 | 2 |
| 2 | 陆雪琪 | 10000000 | 3 |
| 3 | 韦小宝 | 990000 | 6 |
+----+-----------+--------------+-------------+

五、修改表:

语法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名; 2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST;
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
3. 删除字段
ALTER TABLE 表名
DROP 字段名;
4. 修改字段
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

六、复制表:

在创建表的时候 通过select * from 表名 来获取复制表的来源

# 复制表结构+记录 (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数据库之-foreign key 外键(一对多、多对多、一对一)、修改表、复制表的更多相关文章

  1. day38:MySQL数据库之约束&索引&外键&存储引擎

    目录 part1:数据类型 part2:约束 part3:主键索引 PRI &唯一索引 UNI &普通索引 MUL part4:外键:foreign key part5:在外键中设置联 ...

  2. mysql foreign key(外键) 说明与实例

    一,什么是foreign key,及其完整性 个人觉得,foreign key就是表与表之间的某种约定的关系,由于这种关系的存在,我们能够让表与表之间的数据,更加的完整,关连性更强.关于完整性,关连性 ...

  3. mysql foreign key 外键

    ALTER TABLE `fd_rel_customer_doctor` ADD CONSTRAINT `FK_fd_rel_customer_doctor_1` FOREIGN KEY (`CUST ...

  4. FOREIGN KEY 外键约束; UNIQUE和PRIMARY KEY 主键约束、CREATE INDEX建立索引的使用

    1)foreign key 是个约束,意思是说如果你给A字段设置了外键约束,以后你要往A字段插入数据,这个数据一定是要在foreign key 后面跟的那个字段中存在的值.这个的意义就是约束了数据的完 ...

  5. 关于数据库主从表、主键PRIMARY KEY 外键约束 FOREIGN KEY 约束----NOT NULL,DEFAULT,CHECK

    如果由两个列共同组成主键,而且一个子表将主键作为可为空值的外键来继承,就可能得到错误的数据.可在一个外键列中插入有效的值,但在另一个外键列中插入空值.然后,可添加一个数据表检查约束,在可为空的外键中检 ...

  6. 总结: MySQL(基础,字段约束,索引,外键,存储过程,事务)操作语法

    1. 显示数据库列表 show databases; # 查看当前所有数据库 show databases \G   #以行的方式显示 2. 在命令行中,执行sql语句 mysql -e 'show ...

  7. sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务

    外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...

  8. mysql(视图 事务 索引 外键)

    视图   视图本质就是对查询的封装   创建视图(定义视图 起名以v_开头) create view v_students as select classes.name as c_name ,stud ...

  9. mysql之浅谈主外键

    主键(PRIMARY KEY) 主键在一个数据表中只能有唯一的一个,约束当前字段的值不能重复,且非空保证数据的完整性,也可以当做当前数据表的标识符用来查询(当做索引,唯一性索引的一种) 创建带主键的表 ...

随机推荐

  1. python之self本类对象

    不知道写点啥好,讲的都太绕了 似懂非懂,貌似懂了 以后再补充吧,视频day8_3中的20——60分钟那一部分

  2. android动画(3)layout动画,layoutChanged动画及算定义它,ListViewActivity的Layout动画(代码和xm配置两种实现l)

    1.layout切换动画 代码: 本示例是fragment切换.在它的oncreateView中 public class LayoutAnimationFrgmt extends Fragment ...

  3. iOS7改变状态栏文字颜色

    1在Info.plist中设置UIViewControllerBasedStatusBarAppearance 为NO2 在需要改变状态栏颜色的 AppDelegate中在 didFinishLaun ...

  4. SpringCloud开发学习总结(七)—— 声明式服务调用Feign(二)

    参数绑定 在上一章的示例中,我们使用Spring Cloud Feign实现的是一个不带参数的REST服务绑定.然而现实系统中的各种业务接口要比它复杂得多,我们有时会在HTTP的各个位置传入各种不同类 ...

  5. scau 1144 数星星 bit + 扫描线的思想

    这题如果用二维树状数组,则会直接爆内存. 那么可以运用扫描线的思路. 就是,它同时被x和y限制了,那么可以在查询的时候,确保x先满足了,(把x按小到大排序) 然后就相当于是关于y的一个一维bit了, ...

  6. PowerShell~文件操作和对象遍历

    ps提供了丰富的文件操作,如建立,删除,改名,移动,复制,文件夹建立,显示文件列表,同时对数组对象的遍历也很方便,如果在使用PS脚本时,希望现时传入参数,可以把参数声明为param,当然需要把它写在文 ...

  7. logging模块进阶

    python利用logging模块来记录日志主要涉及四个类 logger提供了应用程序可以直接使用的接口 handler将logger创建的日志提供的输出发送到指定目的地. filter起到过滤作用, ...

  8. 【学习笔记】深入理解js原型和闭包(1)—— 一切都是对象

    “一切都是对象”这句话的重点在于如何去理解“对象”这个概念. ——当然,也不是所有的都是对象,值类型就不是对象. 首先咱们还是先看看javascript中一个常用的运算符——typeof.typeof ...

  9. 盘点那些年,被Oracle收购的公司

    微博上看到一图,很清晰.盘点那些年,被Oracle收购的公司,Oracle日益强大,都收购了哪些公司呢?别再以为只有Sun啦...看看你都知道哪些? ps:Strategic Acquisitions ...

  10. C# 移动控件

    最近要做车牌识别的,不同地区收费标准不一,所以想做个可以移动控件来给客户选择停车场收费条件的.   首先因为要自动排序控件选FlowLayoutPanel做容器,加若干Panel和FlowLayout ...