Python 学习笔记-第23讲:数据库三范式及高级查询语句

1. 数据库三范式 (Normal Form)

第一范式(1NF):列的原子性,即列不能够再分成其他几列。

1NF的定义为:符合1NF的关系中的每个属性都不可再分。

第二范式(2NF):

一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

第三范式(3NF):

首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。

https://blog.csdn.net/qingking520/article/details/52937728

https://www.zhihu.com/question/24696366

 

2. ER 图:实体关系图 (Entity Relationship Diagram)

是指提供了表示实体型、属性和联系的方法,用来描述现实世界的概念模型。

ER图中包含了实体(即数据对象)、关系和属性等3种基本成分,通常用矩形框代表实体,用连接相关实体的菱形框表示关系,用椭圆形或圆角矩形表示实体(或关系)的属性,并用直线把实体(或关系)与其属性连接起来。

实体型(Entity):具有相同属性的实体具有相同的特征和性质,用实体名及其属性名集合来抽象和刻画同类实体;在E-R图中用矩形表示,矩形框内写明实体名;

属性(Attribute):实体所具有的某一特性,一个实体可由若干个属性来刻画。在E-R图中用椭圆形表示,并用无向边将其与相应的实体连接起来;

联系(Relationship): 数据对象彼此之间相互连接的方式称为联系,也称为关系。联系可分为以下 3 种类型:

(1) 一对一联系 (1 ∶ 1)

(2) 一对多联系 (1 ∶ N)

(3) 多对多联系 (M ∶ N)

Python 学习笔记-第23讲:数据库三范式及高级查询语句_第1张图片

 

 

转换为等价的关系模式结构如下:

 

借书人(借书证号,姓名,单位)

 

图书(书号,书名,数量,位置,出版社名)

 

出版社(出版社名,电报编号,电话,邮编,地址)

 

借阅(借书证号,书号,借书日期,还书日期)

参考链接:

https://blog.csdn.net/limuzi13/article/details/50390810

 

 

3. 算法:二分查找

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果xa[n/2],则只要在数组a的右半部搜索x.

00111011

二进制表示,从高位到低位依次设置为1或0,从而实现将数的范围缩小一半。

算法要求

1.必须采用顺序存储结构。

2.必须按关键字大小有序排列。

比较次数

计算公式:

当顺序表有n个关键字时:

查找失败时,至少比较a次关键字;查找成功时,最多比较关键字次数是b。

注意:a,b,n均为正整数

代码示例:

def bin_search(data_list, val):    
    low = 0                         # 最小数下标    
    high = len(data_list) - 1       # 最大数下标    
    while low <= high:        
        mid = (low + high) // 2     # 中间数下标        
        if data_list[mid] == val:   # 如果中间数下标等于val, 返回            
            return mid        
        elif data_list[mid] > val:  # 如果val在中间数左边, 移动high下标            
            high = mid - 1        
        else:                       # 如果val在中间数右边, 移动low下标            
            low = mid + 1    
    return # val不存在, 返回None
ret = bin_search(list(range(1, 10)), 3)
print(ret)

 

参考链接:https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/10628618

二、MySQL 语句(续)

    1. 分组查询

SELECT …… FROM  <表名>  WHERE  ……GROUP BY ……

SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩 FROM `result` GROUP BY `subjectNo`;

SELECT列表中只能包含:

1.被分组的列

2.为每个分组返回一个值的表达式,如聚合函数

多列分组

SELECT `gradeId` AS 年级编号,`sex` AS 性别,COUNT(*) AS 人数

 FROM `student`

GROUP BY `gradeId`,`sex`

ORDER BY `gradeId`;

分别统计每个年级男、女生人数

 

2. 分组筛选

SELECT …… FROM  <表名> WHERE …… GROUP BY …… HAVING……

SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩

FROM `result` GROUP BY `subjectNo`

HAVING AVG(`studentResult`) >=60;

 

WHERE与HAVING对比

WHERE子句

用来筛选 FROM 子句中指定的操作所产生的行

GROUP BY子句

用来分组 WHERE 子句的输出

HAVING子句

用来从分组的结果中筛选行

 

3. 多表连接查询

内连接(INNER JOIN)

外连接

左外连接   (LEFT JOIN)

右外连接   (RIGHT JOIN)

Cross Join (不常用)

 

内连接使用比较运算符根据每个表的通用列中的值匹配两个表中的行

SELECT   ……  FROM   表1 INNER JOIN  表2 ON   ……

等价于

SELECT  ……  FROM   表1,表2 WHERE ……

 

三表内连接

SELECT S.studentName AS 姓名,SU.subjectName AS 课程,R.studentResult AS 成绩

FROM student AS S

INNER JOIN `result` AS R ON  (S.`studentNo` = R.`studentNo`)

INNER JOIN `subject` AS SU ON (SU.subjectNo=R.subjectNo);

等价于

SELECT S.SName AS 姓名, CS.CourseName AS 课程, C.Score AS 成绩

FROM Students AS S ,Score AS C , Course AS CS

WHERE (S.SCode = C.StudentID) AND  (CS.CourseID = C.CourseID)

 

左外连接

左外联接是以左表为基础的,左表的记录将会全部表示出来,而右表只会显示符合搜索条件的记录。右表记录不足的地方均为NULL

右外连接

右外连接的原理与左外连接相同,右表逐条去匹配记录;否则NULL填充

4. 视图(view)

视图是一张虚拟表

表示一张表的部分数据或多张表的综合数据

其结构和数据是建立在对表的查询基础上

视图中不存放数据

数据存放在视图所引用的原始表中

一个原始表,根据不同用户的不同需求,可以创建不同的视图

 

视图的用途

筛选表中的行

防止未经许可的用户访问敏感数据

降低数据库的复杂程度

将多个物理数据库抽象为一个逻辑数据库

 

使用SQL语句创建视图

CREATE VIEW view_name    AS