首页 > 代码库 > 《数据库系统概念》学习笔记2

《数据库系统概念》学习笔记2

                                     第二章       关系模型
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  语句用于结合合计函数,根据一个或多个列对结果集进行分组。
         此处解释很精辟http://www.w3school.com.cn/sql/sql_groupby.asp
 
   
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来定义