第二章
关系模型
a.关系代数基本运算有:选择、投影、并、集合差、笛卡尔积、和更名
b.附加的关系代数运算:集合交、自然连接、除运算、赋值运算、
c.扩展的关系代数运算:广义投影,聚集函数,外连接
d.数据库的修改:删除,插入,更新
小结
A.关系数据模型建立在表的集合的基础之上。数据库系统的用户可以对这些表进行查询,可以插入新元组、删除元组以及更新(修改)元组。
B.关系代数定义了一套在表上运算,且输出结果也是表的代数运算。这些运算可以混合使用以得到表达所希望查询的表达式。关系代数定义了关系查询语言中使用的基本运算
C.关系代数运算可分为:基本运算、附加运算、扩展运算
D.数据库可以通过插入、删除或更新元组来修改。我们用包含赋值运算符的关系代数来表达这些修改
E.关系代数是简洁的、形式化的语言,不适合那些偶尔使用数据库系统的用户。因此,商用数据库采用有更多“语法修饰”的语言------SQL
第三章
SQL
a.SQL语言有以 下几个部分:数据定义语言,交互式数据操纵语言,完整性,视图定义,事务控制
嵌入式SQL和动态SQL,授权
b.SQL表达式基本结构包括三个字句
select子句:对应关系代数中的投影运算,用来列出查询结果中所要的属性
from子句: 对应关系代数中的笛卡尔积,它列出表达式求值中需扫描的关系
where子句:对应关系代数中的选择谓词,它包括一个作用在from子句中关系的属性上的谓词
c. select ”找出loan关系中所有支行的名字“
select
branch_name
from
loan
*若要删除重复,则select后加入关键词distinct
d. where
”找出所有再Perryridge支行贷款并且贷款额超过1200美元的贷款的贷款号“
select
loan_number
from
loan
where
branch_name = ‘Perryridge‘ and amount>1200
*还提供between比较运算符来说明一个值是小于或等于某个值、同时大于或等于另一个值
e. from
”找出从银行贷款的所有用户的名字、贷款号、贷款数目“
select customer_name,borrower.loan_number,amount
from borrower,loan
where borrower.loan_number=loan.loan_number
f. as更名运算
”我们想用名字loan_id代替属性名loan_number,我们可以像下面这样重写上面的查询
select customer_name,borrower.loan_number as
loan_id,amount
from borrower,loan
where borrower.loan_number=loan.loan_number
g. like字符串运算 “找出街道地址中包含子串‘Main‘的所有客户名“
select customer_name
from customer
where customer_street like ‘%Main%‘
*其中有转义字符‘\’类似java
h. order by 排列元组的显示次序
”按字母顺序列出Perryridge支行中有贷款的客户“
select distinct customer_name
from borrower,loan
where borrower.loan_number=loan.loan_number and
branch_name =
‘Perryridge‘
order by customer_name
*order by默认为升序,可加desc表示降序,asc表示升序,如”order by amount
desc,loan_number asc"
i.集合运算:union、intersect、except分别对应关系代数中的交、并、差
union “找出在银行有账户、有贷款或两者都有的所有客户
(select customer_name
from
depositor)
union
(select customer_name
from borrower)
* 与select字句不同,union运算自动去除重复,若要保留重复,可用union all代替union
intersect ”找出在银行同时有账户和贷款的客户“
(select
distinct customer_name
from depositor)
intersect
(select distinct customer_name
from borrower)
*同union一样,也是自动去除重复
except ”找出在银行中有账户但无贷款的客户“
(select distinct
customer_name
from
depositor)
except
(select
customer_name
from
borrower)
*自动去除重复
j.聚集函数:平均值:avg,最小值:min,最大值:max,总和:sum,计数:count。
*sum和avg的输入必须是数字集,而其他运算符还可以作用在非数字数据类型
”找出Perryridge支行账户余额平均值“
select avg(balance)
from account
where
branch_name=‘Perryridge‘
“找出每个支行储户数”
select
branch_name,count(distinct customer_name)
from
depositor,account
where
depositor.account_number = account.account_number
* group
by 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
k.having子句中的的谓词在形成分组后才起作用(即group by起作用后才起作用),因此可以使用聚集函数
select branch_name,avg(balance)
from account
group by branch_name
having avg(balance)>1200
l.可以用count计算一个关系中的元组数。SQL中该函数的写法是count(*)。因此,要找出customer关系中的元组数,可写成:
select count(*)
from customer
*SQL不允许在用count(*)时使用distinct
为了说明having子句和where子句出现在同一个查询时的用法,我们考虑查询“找出住在Harrison且在银行中至少有三个账户的客户的平均余额”
select depositor.customer_name,avg(balance)
from depositor,account,customer
where depositor.account_number = account.account_number and
depositor,customer_name =
customer.customer_name and
customer_city = ‘Harrison‘
group by depositor.customer_name
having count(distinct depositor.account_number)>=3
m.null 空值 “找出loan关系中amount为空值的贷款号”
select loan_number
from loan
where amount is null
*谓词is not
null用来检测非空值。如果算数运算的输入有一个是空,则该算数表达式的结果是空。如果有空值参与比较运算,SQL将比较运算的结果看成unknown(既不是is
null,也不是is not null)
SQL还允许我们用is unknown子句或is not
unknown子句来判断比较结果是不是unknown,而不是判断true or false
n.嵌套子查询,子查询是嵌套在另一个查询中的select-from-where表达式。一般子查询的使用时为了对集合的成员资格、集合的比较以及集合的基数进行检查
连接词in测试元组是否是集合中成员,not in 则相反
“找出在银行中同时有账户和贷款的客户”
select distinct customer_name
from borrower
where customer_name in (select customer_name
from depositor)
*in和not in运算符也能用于枚举集合
“找出在银行中有贷款的客户,并且它的名字既不是”smith",也不是“jones”
select distinct
customer_name
from borrower
where customer_name not in
(‘Smith‘,‘Jones‘)
o.短语“至少比某一个大”在SQL中用>some表示
select branch_name
from branch
where assets>some (select
assets
from
branch
where
branch_city = ‘Brooklyn‘)
p.exists 测试是否为空关系,非空时返回true
“找出在银行既有账户又有贷款的客户”
select customer_name
from borrower
where exists (select*
from depositor
where depositor.customer_name=borrower.customer_name)
q. unique 查看子查询中有没重复的元组。没有则返回true
“找出所有在Perryridge支行中只有一个账户的客户”
select
T.customer_name
from
depositor as T
where unique
(select R.customer_name
from
account,depositor as R
where
T.customer_name = R.customer_name and
R.account_number = account.account_number and
account.branch_name = ‘Perryridge‘)
r.派生关系,as
“查询产生的关系包含各支行的名字和相应的平均账户余额”
(select branch_name
,avg(balance)
from account
group by branch_name)
as
branch_avg(branch_name,avg_balance)
s. with 子句
with子句提供定义临时视图的方法,这个定义只对with子句出现在的那条查询有效
t.视图:任何不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图。
create view all_customer as
(select
branch_name,customer_name
from
depositor,accunt
where
depositor.account_number=account.account_number)
union
(select
branch_name,customer_name
from
borrower,loan
where
borrower.loan_number=loan.loan_number)
一旦我们定义了一个视图,我们就可以用视图名指代该视图生成的虚关系
select
customer_name
from
all_customer
where
branch_name = ‘Perryridge‘
*只要没更新操作在视图上的执行,视图名可以出现在关系名可以出现的任何地方
u.数据库的修改
删除: 格式 delete from r
where P
删除Perryridge支行的所有账户
delete
from account
where
branch_name=‘Perryridge‘
删除所有数额在1300美元到1500美元之间的贷款
delete from
loan
where amount
between 1300 and 1500
删除所有位于Brooklyn的支行的所有账户
delete from
account
where
branch_name in(select branch_name
from branch
where branch_city = ‘Brooklyn‘
插入:insert into account
select
loan_number,branch_name,200
from
loan
where
branch_name = ‘Perryridge‘
"向depositor关系中添加元组“
insert into
depositor
select customer_name ,loan_number
from borrower,loan
where borrower.loan_number = loan.loan_number and
branch_name =
‘Perryridge‘
更新: ”对余额超过10000美元的账户付6%的利息,其余账户付5%”
update
account
set balance = balance * 1.06
where balance>10000
update
account
set balance = balance * 1.05
where
balance<=10000
*这两条update语句的顺序非常重要。假如改变这两条语句的顺序,略少于1W美元的存款将获得11.3%的利息。
小结:
A.商业数据库系统并不使用第二章所介绍的简洁的、形式化的关系代数。本章我们学习广泛应用的SQL语言
,是建立在关系代数基础上并提供了许多便利语法的语言
B.SQL的数据定义语言用于建立具有特定模式的关系。SQL DLL支持若干数据类型,包括date和time等类型。
C.SQL包括各种用于查询数据库的语言结构。所有的关系代数运算,包括扩展的关系代数运算都可以用SQL表达。SQL还允许对查询结果按某些特定属性进行排序
D.SQL通过一般的真值取值(即true和false)外增加真值”unknown“来处理关系中含有空值的查询
E.SQL允许在where子句中嵌套子查询。外层查询可以在子查询的结果上执行多种操作
F.视图关系可以定义为包含查询结果的关系
G.临时视图用with来定义