4Python全栈之路系列之MYSQL外键

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

Python全栈之路系列之MySQL外键


先来个例子来说明什么是外键以及外键的作用,so,XO公司现正处于一种迅速发展的状态,从最初的12人的团队发展到现在的300人,那么问题就来了,发展的越快,人员与部门就越来越多,这是老大要求我们做一个人员管理系统,用于查询入职人员的信息等。


起初我们想用一个表来实现所有的人员统计,创建Personnel库,用于存放公司员工的信息,指令如下:

1
CREATE DATABASE personnel DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

然后在创建一个人员信息表,在这个person_info表中,idname列是联合主键,引擎是InnoDB,字符集是utf8格式的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE `person_info` (
   - -  人员 ID
   ` id int ( 11 ) NOT NULL AUTO_INCREMENT,
   - -  人员姓名
   `name` varchar( 10 ) NOT NULL,
   - -  email
   `email` varchar( 15 ) DEFAULT NULL,
   - -  手机号码
   `phone` char( 11 ) NOT NULL,
   - -  部门
   `department` varchar( 32 ) DEFAULT NULL,
   - -  职位
   `position` varchar( 30 ) DEFAULT NULL,
   - -  说明描述
   `caption` varchar( 255 ) DEFAULT NULL,
   PRIMARY KEY (` id `,`name`)
) ENGINE = InnoDB AUTO_INCREMENT = 6  DEFAULT CHARSET = utf8;

插入成员数据

1
2
3
4
5
INSERT INTO person_info(name,email,phone,department,position,caption) VALUES ( 'a' 'a@anshengme.com' '13800138000' 'XO股份有限公司公司-技术部-Python开发' 'Python API开发' '我是一名Python开发工程师,专注于PYthon API开发' );
INSERT INTO person_info(name,email,phone,department,position) VALUES ( 'b' 'b@anshengme.com' '13800138000' 'XO股份有限公司公司-技术部-JAVA开发' 'JAVA APP开发' );
INSERT INTO person_info(name,email,phone,department,position) VALUES ( 'c' 'c@anshengme.com' '13800138000' 'XO股份有限公司公司-技术部-前端' 'JavaScript' );
INSERT INTO person_info(name,email,phone,department,position) VALUES ( 'd' 'd@anshengme.com' '13800138000' 'XO股份有限公司公司-技术部-DBA' 'MySQL DBA' );
INSERT INTO person_info(name,email,phone,department,position) VALUES ( 'e' 'e@anshengme.com' '13800138000' 'XO股份有限公司公司-技术部-服务器组' 'Linux' );

查看插入的数据

1
2
3
4
5
6
7
8
9
10
11
mysql>  select  from  person_info;
+ ----+------+-----------------+-------------+---------------------------------------------------+------------------+---------------------------------------------------------------+
| id |  name  | email           | phone       | department                                        | position         | caption                                                       |
+ ----+------+-----------------+-------------+---------------------------------------------------+------------------+---------------------------------------------------------------+
|  1 | a    | a@anshengme.com | 13800138000 | XO股份有限公司公司-技术部-Python开发              | Python API开发   | 我 是一名Python开发工程师,专注于PYthon API开发                |
|  2 | b    | b@anshengme.com | 13800138000 | XO股份有限公司公司-技术部-JAVA开发                | JAVA APP开发     |  NULL                                                           |
|  3 | c    | c@anshengme.com | 13800138000 | XO股份有限公司公司-技术部-前端                    | JavaScript       |  NULL                                                           |
|  4 | d    | d@anshengme.com | 13800138000 | XO股份有限公司公司-技术部-DBA                     | MySQL DBA        |  NULL                                                           |
|  5 | e    | e@anshengme.com | 13800138000 | XO股份有限公司公司-技术部-服务器组                | Linux            |  NULL                                                           |
+ ----+------+-----------------+-------------+---------------------------------------------------+------------------+---------------------------------------------------------------+
rows  in  set  (0.00 sec)

so,我们只是插入了上面5条数据而已,那么如果有成千上万条的数据,department是不是都是重复的呢?因为么个人肯定都是属于一个部门的,还可能属于这个部门下面某个组的,而且上面的部门字段所占用的字符只有这个么几个,如果有个变态的老大,必须把部门名车个搞到很长很长,那么这样做是不是很占用空间呢?而且查询的时候也没有那么快。

所以,外键的作用就出来了,那么现在的表设计就改变了,变成什么样的呢?

person_info表被拆封成两个表,分为part部门表person_info人员信息表

part表有nidcaption列,nid为主键并自增,caption存放公司所有的部门等。

person_info依旧是人员信息表,拥有的字段和上面表中的设置是一样的,idname依旧是主键,id自增,唯一改变的就是part_nid列关联了part表中的nid列,表设计如下图:

wKioL1kZVlTgmuEwAABpbfbiDf8683.png

先删除之前创建的person_info

1
DROP TABLE person_info;

创建part职务表

1
2
3
4
5
CREATE TABLE part (
   nid  int ( 11 ) NOT NULL AUTO_INCREMENT,
   caption varchar( 32 ) NOT NULL,
   PRIMARY KEY (nid)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

插入部门数据

1
INSERT INTO part(caption) VALUES( "XO股份有限公司公司-技术部-JAVA开发" ),( "XO股份有限公司公司-技术部-前端" ),( "XO股份有限公司公司-技术部-DBA" ),( "XO股份有限公司公司-技术部-服务器组" ),( "XO股份有限公司公司-技术部-Python开发" );

查看插入的部门信息

1
2
3
4
5
6
7
8
9
10
11
mysql>  select  from  personnel.part;
+ -----+---------------------------------------------------+
| nid | caption                                           |
+ -----+---------------------------------------------------+
|   1 | XO股份有限公司公司-技术部-JAVA开发                |
|   2 | XO股份有限公司公司-技术部-前端                    |
|   3 | XO股份有限公司公司-技术部-DBA                     |
|   4 | XO股份有限公司公司-技术部-服务器组                |
|   5 | XO股份有限公司公司-技术部-Python开发              |
+ -----+---------------------------------------------------+
rows  in  set  (0.00 sec)

创建person_info人员信息表

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `person_info` (
   `nid`  int ( 11 ) NOT NULL AUTO_INCREMENT,
   `name` char( 10 ) NOT NULL,
   `email` varchar( 20 ) NOT NULL,
   `phone` char( 11 ) NOT NULL,
   `part_nid`  int ( 11 ) NOT NULL,
   `position` char( 20 ) NOT NULL,
   `caption` varchar( 255 ) DEFAULT NULL,
   PRIMARY KEY (`nid`,`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;

设置外键

person_info表中的part_nid列和part表中的nid列做一个外键关联,外键的名称为person_ibfk_1

1
alter table person_info add constraint person_ibfk_1 foreign key person_info(`part_nid`) REFERENCES part(`nid`);

删除外键

删除person_info表中的person_ibfk_1外键

1
alter table person_info drop foreign key person_ibfk_1;

往成员表中插入6条数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
INSERT INTO person_info (
     NAME,
     email,
     phone,
     part_nid,
     position
)
VALUES
     (
         "as" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     ),
     (
         "ansheng" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     ),
     (
         "a" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     ),
     (
         "v" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     ),
     (
         "b" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     ),
     (
         "w" ,
         "as@anshengme.com" ,
         13800138000 ,
         5 ,
         "Python"
     )

上面插入的数据都是合法的,那么如果我们插入不合法的数据会怎样呢?比如说插入一条在part表中不存在的部门会怎样?

1
2
3
4
mysql> use personnel;
Database changed
mysql> INSERT INTO person_info(name,email,phone,part_nid,position) VALUES( "pwd" , "pwd@anshengme.com" , 13800138000 , 10 , "Python" );
ERROR  1452  ( 23000 ): Cannot add  or  update a child row: a foreign key constraint fails (`personnel`.`person_info`, CONSTRAINT `person_ibfk_1` FOREIGN KEY (`part_nid`) REFERENCES `part` (`nid`))

so,是不是就报错了呢?没做,这就是外键的约束,如果说你插入的数据中,part_nid列中的数据在part表的nid列没有的话,那么是万万不可以的,

上述是一对多的关系,多对多和连表查询会在下一篇文章中介绍,其实很简单










本文转自 Edenwy  51CTO博客,原文链接:http://blog.51cto.com/edeny/1925880,如需转载请自行联系原作者
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
Python中使用MySQL模糊查询的方法
本文介绍了两种使用Python进行MySQL模糊查询的方法:一是使用`pymysql`库,二是使用`mysql-connector-python`库。通过这两种方法,可以连接MySQL数据库并执行模糊查询。具体步骤包括安装库、配置数据库连接参数、编写SQL查询语句以及处理查询结果。文中详细展示了代码示例,并提供了注意事项,如替换数据库连接信息、正确使用通配符和关闭数据库连接等。确保在实际应用中注意SQL注入风险,使用参数化查询以保障安全性。
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
497 15
Mysql学习笔记(四):Python与Mysql交互--实现增删改查
如何使用Python与MySQL数据库进行交互,实现增删改查等基本操作的教程。
107 1
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
114 4
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
从 MySQL 到时序数据库 TDengine:Zendure 如何实现高效储能数据管理?
TDengine 助力广州疆海科技有限公司高效完成储能业务的数据分析任务,轻松应对海量功率、电能及输入输出数据的实时统计与分析,并以接近 1 : 20 的数据文件压缩率大幅降低存储成本。此外,taosX 强大的 transform 功能帮助用户完成原始数据的清洗和结构优化,而其零代码迁移能力更实现了历史数据从 TDengine OSS 与 MySQL 到 TDengine 企业版的平滑迁移,全面提升了企业的数据管理效率。本文将详细解读这一实践案例。
32 0
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
165 82
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
MySQL生产环境迁移至YashanDB数据库深度体验
这篇文章是作者将 MySQL 生产环境迁移至 YashanDB 数据库的深度体验。介绍了 YashanDB 迁移平台 YMP 的产品相关信息、安装步骤、迁移中遇到的各种兼容问题及解决方案,最后总结了迁移体验,包括工具部署和操作特点,也指出功能有优化空间及暂不支持的部分,期待其不断优化。

热门文章

最新文章