AHugeApe

导航

数据库系统概念(1)

数据库系统概念(1)


应用程序想要访问数据库, 一般有两种方式:

  1. 通过应用程序接口, 将DDL(data-defination language )和DML(data-manipulation language)发送给数据库, 再取回结果, 如ODBC, JDBC.
  2. 通过拓展宿主语言的语法, 通常是以某一个特殊字符作为调用的开始, 通过于编译器, 转变为宿主语言的过程调用.(或许本身自带数据库的实现和driver)

总而言之, 还是通过某些调用接口将特定格式的语言传到数据库, 进行解释执行.


关系模型的术语:
关系(relation)指代表, 元组(tuple)用来指代行, 属性(attribute)指代的是表中的列.

元组就是无序的一系列值的集合, 而关系是元组集合, 所以关系中的元组的出现也应该是无序的. 而对于每一个在关系中的属性都应该具有一个允许取值的集合,称之为域(domain). 一般域是不可再分的原子特性.


关系模式和关系实例
数据库模式(database schema)类似程序设计语言中的变量, 数据库实例(database instance)是给定时刻数据库中数据的一个快照, 类似变量的值.


基本select语法

在查询的集合中去除重复元组:

select distinct name from student;

select语句可以包含加减乘除等算术运算符, 对象是关系的属性

select ID, name, grade*1.1 from student;

where子句中允许使用and, or, not等逻辑连词, 连接运算对象, 包含比较运算符等.

多查询示例

select name, instructor, dep_name, building
from instructor, department
where instructor.dep_name = department.dep_name;

其中, instructor和department中都有一个属性dep_name且应该对应.

数学层面对某个查询的解释:
首先是根据from子句, 得到需要从哪些关系得到元组的集合, 这里是得到不同关系的笛卡尔积, 每一项跟每一项相乘.
然后在根据where子句的限制条件, 得到符合条件的元组集合(所有属性集合).
最后再根据select从选出的元组集合中得到需要的部分属性集合.


附加的基本运算:

++别名++
可以使用as作为属性名的别名, 例子:

select name as student_name from student;

也可以用在自己跟自己做笛卡尔积上面,

select distinct T.name
from instructor as T, instructor as S
where T.salary > S.salary and S.dept_name = 'Biology';

比如这是选择在所有教师中选择比生物系老师工资更高的教师名称.

++字符串运算++
字符串的表示, 一般使用一对单引号标示字符串, 但是如果单引号是字符串的组成部分, 则需要用两个单引号连用表示.

不同数据库对大小写敏感不同.

可以使用like做模式匹配, 通过两个特殊字符来描述模式:

  • 百分号(%): 匹配任意字符
  • 下划线(_): 匹配任意一个字符

举例:

'Intro%' 匹配任何以"Intro"开头的字符串
'___' 匹配只含三个字符的字符串
'___%' 匹配至少含三个字符的字符串

同时, 为了使模式中能够包含特殊模式的字符(就是%和_), sql需要使用escape关键字来定义转义字符.

举例:

like 'ab\%cd%' escape '\' 匹配所有以"ab%cd"开头的字符串
like 'ab\\cd%' escape '\' 匹配所有以"ab\cd"开头的字符串

++排序++
使用order by + 属性名来排序, 后面可以跟desc表示降序排列, asc(默认)升序排列.

举例:

select * from instructor
order by salary desc, name asc;

外键

外键是描述两个关系之间的某个属性的引用关系, 首先定义A,B两个关系, 其中都有一个属性,如student_id, 但是在A中该属性是主键, 那么B中是对A中主键的引用, 称之为外键.
A中的属性叫做被参考属性, B中的属性称之为参考属性, 两者有共同的域.


连接

++自然连接++
自然连接是指在A,B两个关系中, 拥有同名的属性如ID, 这时如果把A,B关系中ID相同的元组联系起来形成新的元组, 称之为自然连接.

如果A, B两个关系中的属性名有共同值, 但有多个并且我们想指定按照某一个属性相同来连接, 可以使用join...using...方式
例如:

select name, title
from teachers join cource using (cource_id);

这里teachers中也有cource_id属性, 但是可能两者之间自然连接有更多可能, 这里仅选择cource_id相同的情况.

++通用连接++
on连接允许通用条件的连接, 而不论两个关系之间的属性名是否相同.
例子: student, takes是两个关系

select * from student join takes on student.ID = takes.ID;
等价于
select * from student, takes where student.ID = takes.ID;

这个查询和自然查询不同之处在于, 使用on的查询, ID属性出现两次, 一次是student中的, 一次是takes中的, 尽管他们的值是相同的.

++外连接++
属性值相匹配的连接一般称之为内连接, 而外连接(outer join)不仅包含属性值相同的情况, 还包含不匹配的情况, 因此这里就有三种外连接的形式.

  • 左外连接(left outer join) 只保留出现在左外连接运算之前(左边)的关系中的元组
  • 右外连接(right outer join) 只保留出现在右外连接运算之前(右边)的关系中的元组
  • 全外连接(full outer join) 保留出现在两个关系中的元组

举例说明外连接是如何操作的:
首先, 和内连接一样计算得到内连接的结果;
然后, 对于在内连接左侧关系中任意一个与右侧关系中任何元组都不匹配的元组t, 向连接结果中插入一个元组r, 其中r的取值为:
r从左侧元组取的属性的值由t提供,
r中其他属性的值被赋为空值.

特殊的, 总要知道多跟少吗?, 比如这里student和takes相比, student更多所以不管是在左外连接的时候是

select * from student natural left outer join takes;

而在右外连接时却是

select * from takes natural right outer join student;

但是如果是:

select * from takes natural left outer join student;
select * from students natural right outer join takes;

则一样查不到所有的数据, 跟属性名不同的元组一样查不出, 所以想知道完整的结果, 要先知道左表和右表哪个全(指在某一个属性值上的多样性丰富).然后根据全的来join.

所以简称就是左表全,左外连; 右表全, 右外连.

on和where在外连接上面的不同:
不同的点在于on是作为外连接声明的一部分, 而where不是. 所以如下举例:

select * from student left outer join takes on student.ID = takes.ID;

select * from student left outer join takes on true
where student.ID = takes.ID;

前者会出现因为不匹配产生的额外的元组, 而后者在where子句的比较中会被排除.

posted on 2018-03-23 16:23  普陀听禅  阅读(211)  评论(0编辑  收藏  举报