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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

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,如需转载请自行联系原作者
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
26天前
|
缓存 NoSQL 关系型数据库
在Python Web开发过程中:数据库与缓存,MySQL和NoSQL数据库的主要差异是什么?
MySQL是关系型DB,依赖预定义的表格结构,适合结构化数据和复杂查询,但扩展性有限。NoSQL提供灵活的非结构化数据存储(如JSON),无统一查询语言,但能横向扩展,适用于大规模、高并发场景。选择取决于应用需求和扩展策略。
114 1
|
1月前
|
XML 关系型数据库 MySQL
python将word(doc或docx)的内容导入mysql数据库
用python先把doc文件转换成docx文件(这一步也可以不要后续会说明),然后读取docx的文件并另存为htm格式的文件(上一步可以直接把doc文件另存为htm),python根据bs4获取p标签里的内容,如果段落中有图片则保存图片。(图片在word文档中的位置可以很好的还原到生成的数据库内容) 我见网上有把docx压缩后解压获取图片的,然后根据在根据xml来读取图片的位置,我觉得比较繁琐。用docx模块读取段落的时候还需要是不是判断段落中有分页等,然而转成htm之后就不用判断那么多直接判断段落里的样式或者图片等就可以了。
22 1
|
1月前
|
SQL 关系型数据库 MySQL
Python怎么操作Mysql数据库
Python怎么操作Mysql数据库
51 0
|
1月前
|
SQL 关系型数据库 MySQL
python在mysql中插入或者更新null空值
这段代码是Python操作MySQL数据库的示例。它执行SQL查询从表`a_kuakao_school`中选取`id`,`university_id`和`grade`,当`university_id`大于0时按升序排列。然后遍历结果,根据`row[4]`的值决定`grade`是否为`NULL`。若不为空,`grade`被格式化为字符串;否则,设为`NULL`。接着构造UPDATE语句更新`university`表中对应`id`的`grade`值,并提交事务。重要的是,字符串`NULL`不应加引号,否则更新会失败。
20 2
|
4天前
|
SQL 关系型数据库 MySQL
Python与MySQL数据库交互:面试实战
【4月更文挑战第16天】本文介绍了Python与MySQL交互的面试重点,包括使用`mysql-connector-python`或`pymysql`连接数据库、执行SQL查询、异常处理、防止SQL注入、事务管理和ORM框架。易错点包括忘记关闭连接、忽视异常处理、硬编码SQL、忽略事务及过度依赖低效查询。通过理解这些问题和提供策略,可提升面试表现。
25 6
|
13天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
1月前
|
Python
老男孩&路飞学城Python全栈
老男孩&路飞学城的Python全栈开发重点班由ALEX老师主讲,核心教学内容,100多天课程,近100G资料,含基础到实战。一线技术专家亲授,以案例教学引导学生逐步进入项目实战。
20 1
老男孩&路飞学城Python全栈
|
1月前
|
存储 关系型数据库 MySQL
Python导入Excel数据到MySQL数据库
Python导入Excel数据到MySQL数据库
90 0
|
1月前
|
SQL 关系型数据库 MySQL
python如何操作mysql数据库
python如何操作mysql数据库
24 0
|
8月前
|
SQL 关系型数据库 MySQL
[Python]使用Python操作MySQL数据库(pymysql)
[Python]使用Python操作MySQL数据库(pymysql)