第1章 概述
目录
第2章 数据库系统体系结构
目录
第3章 关系系统
Type S# Possrep (char);
Type NAME Possrep (char);
Type weight Possren (rational)类型的两种操作符:第4章 SQL
目录
select A1,A2,...,An
from r1,r2,...,rm
where PAis代表属性值,ris代表关系,P是个谓词select S#
from S
where city='London' AND status>20比较结果可以通过使用逻辑连接词and,or和not联合起来,也可以应用于数学表达式的结果select S#
from S
where status between 20 and 30
select *
from EMP,DEPT
where emp.D#=dept.D#Rename操作
select sname name, s# Snumber, status
from S元组变量
select sx.sname,spx.P#
from S sx, SP Spx
where sx.S#=spx.s#元组变量通过在from语句中使用别名来定义字符串操作:SQL包含了在字符串上进行比较的字符串匹配操作,模式利用两个特殊符号来定义:
select sname
from s
where city like '%Main%'SQL中还支持一系列字符操作,如连接(“||”)、大小写转换、查找字符串长度、提取子串等select distinct sname
from S
where city='London'
order by sname对每个属性,我们指定用desc来表示递减的顺序,用asc来表示递增的顺序,默认为递增顺序,如:order by sname desc(select city from S)
union
(select city from P)查找所有即拥有供应商又拥有零件的城市:(select city from S)
intersect
(select city from P)查找所有拥有供应商但没有零件的城市:(select city from S)
except
(select city from P)聚集函数:这些函数用于一个关系的某一列的多重集合的值,并返回一个值
select count(*)
from S查找供应零件的供应商的数量:select count(distinct s#)
from SP查找供应商s1所供应的QTY的平均值:select avg(QTY)
from SPJ
where s#='s1'查找每个供应商所供应的QTY的平均值:select s#,avg(QTY)
from SPJ
Group by s#;查找每个供应商所供应的零件数量:select sname,count(distinct p#)
from S,SP
where S.s#=SP.s#
group by sname注意:在select语句中未使用聚集函数的属性必须添加在group列表中select s#, avg(QTY)
from SP
group by s#
having avg(QTY)>600注意:having语句中的谓词用在group之后,而where语句中的谓词用在group之前where中不能使用聚集函数,而having中必须使用聚集函数:
select d#,avg(SAL)
from EMP
where age < 40
group by d#
having avg(SAL)>600
select E#
from EMP
where office# is null任何包含null的比较返回未知,如5<null或null<>null或null=null包含未知值的逻辑运算结果:
select distinct Ename
from EMP
where d# in
(select d# from DEPT
where Dname='sale')集合比较,例如:查找所有工资大于某位经理工资的雇员名称:select Ename
from EMP
where sal > some
(select sal
from EMP
where E# in (select mgr
from DEPT))查找所有工资大于所有经理工资的雇员名称:select Ename
from EMP
where sal > all
(select sal from EMP
where E# in (select mgr
from DEPT))集合比较的定义:select distinct Sx.sname
from S Sx
where not exists (
(select pname
from P
where city='London')
except
(select Px.pname
from SP Tx, P Px
where Tx.p# = Px.p# and
Sx.S# = Tx.s#)) 注意:这个查询不能使用=all和它的变量select T.Ename
from EMP T
where unique(
select R.Dname
from DEPT R
where T.e#=R.MGR)查找所有满足其至少有两个雇员的工资大于$500的条件的部门名称:select distinct T.Dname
from DEPT T
where not unique(
select R.Ename
from EMP R
where T.d#=R.d# and
R.SAL >= 5000)Joined关系
select Ename,SAL,D#,Dname,Location
from EMP,DEPT
where EMP.d#=DEPT.D#
And Dname='sales';查找在相同城市的所有供应商和零件:Select s#,sname,p#,city,status
From S,P
Where S.city=P.city查找所有工资超过其经理工资的雇员:(Join 自身)Select e.Ename,e.SAL,m.Ename,m.SAL
From EMP e, EMP m
Where e.MGR = m.E#
AND e.SAL > m.SAL;相同的两种查询:
select distinct Ename
from EMP
where d# in
(select d# from DEPT
where Dname='sale')
select distinct Ename
from EMP,DEPT
where EMP.D#=DEPT.D#
AND Dname='sale')查找所有在每个部门拥有最低工资的雇员:(错误!!!Where SAL in在Min(Sal)子查询中可能会得到错误结果)Select Ename,d#,SAL From EMP
Where SAL in (Select min(SAL)
From EMP
Group By d#);正确结果如下:Select Ename,d#,SAL From EMP
Where (d#,SAL)
in (Select d#,min(SAL)
From EMP
Group By d#);查找所有零件号码和它的总数量:Select p#,sum(QTY) totqty
From SP
Group By p#;或者
Select p#,(Select sum(QTY)
From SP
Where SP.p#=P.p#) totqty
From P;
4.修改—删除
delete from S
where city='London';删除所有供应零件p2的供应商:delete from S
where s# in ( select s#
from SP
where p#='p2');注意:这里会有一些涉及约束的问题,会在Chapter8介绍delete from EMP
where SAL < (select avg (SAL)
from EMP);问题:当我们从EMP中删除元组时,平均工资也随之改变修改—插入
insert into S
values('s6','wang ping',20,
'shanghai');或者
insert into S(status,city,s#,sname)
values (20,'shanghai','s6','wang ping');向S中添加一个新的元组,并将其城市设为空:insert into S
values ('s7','Li hong',30,null);给所有合肥支行的贷款账户添加一笔$200的账款,其中Account(Account#,Branch-name,Amount):insert into account
select loan-number,branch-name,200
from loan
where branch-name = 'Hefei';select from where语句在它的任何结果被插入到关系之前需要被充分评估,否则类似于update EMP
set SAL=SAL*1.06
where SAL > 4000;
update EMP
set SAL=SAL*1.05
where SAL <=4000;5.嵌入SQL
EXEC SQL BEGIN DECLARE SECTION;
Char SQLSTATE[6];
Char P# [6];
int Weight;
EXEC SQL END DECLARE SECTION;
P#='P2';
EXEC SQL Select P.weight INTO :weight
FROM P WHERE P.P#=:p#;
if SQLSTATE='00000'
Then...
Else...;更多语句:Cursor语句、Open语句、Fetch语句、Close语句在主语言中,查找所有供应的数目大于amount变量的供应商名称和其所在的城市:
EXEC SQL
declare c cursor for
select sname,city
from S,SP
where S.s#=SP.s#
and SP.QTY > :amount;open语句使得查询语句开始执行:EXEC SQL open c;declare c cursor for
select *
from EMP
where city='Parise'
for update;更新:update EMP
set SAL=SAL+100
where current of c;
char* sqlprog = "update EMP
set SAL = SAL*1.05
where d# = ?";EXEC SQL prepare dynprog
from :sqlprog;
char account[10] = "A-101";
EXEC SQL execute dynprog
using :account;
ODBC:Open DataBase Connectivity标准,应用程序用来连接数据库服务器的标准,是个API,用来打开与数据库的连接、发送查询和更新、返回结果
int ODBCexample()
{
RETCODE error;
HENV env; /* environment */
HDBC conn; /* database connection */
SQLAllocEnv(&env);
SQLAllocConnect(env,&conn);
SQLConnect(conn,"aura.bell-labs.com",SQL_NTS,"avi",SQL_NTS,"avipasswd",SQL_NTS);
{...Do actual work...}
SQLDisconnect(conn);
SQLFreeConnect(conn);
SQLFreeEnv(env);
}
SQL函数
第5章 数据完整性
目录
完整性约束通过确保对数据库的授权更改不会导致数据一致性的丢失,以防止数据库意外损坏
2.四种约束
类型约束
是完整性约束的最基本形式
测试插入在数据库中的值,并测试查询以确保比较具有意义
例如:
TYPE weight POSSREP(RATIONAL)
CONSTRAINT the_weight(weight)>0.0;
TYPE point POSSREP cartesian(X Rational, Y Rational)
CONSTRAINT ABS(the_X(point))<=100.0 AND
ABS(the_Y(point))<=100.0;
属性约束
VAR S BASE RELATION(s# s#,
sname name,
status integer,
city char)......;
关系变量约束
- 独立关系变量上的约束
- 指定元组是一个指定的关系变量
- 关系变量约束总是立即被检查
例如:
- Constraint sc1
is_empty(S WHERE city='London'
AND status != 20)- Constraint sc2
is_empty(P WHERE color=color(‘red’)
AND city != 'London');- Constraint sc3 count(S) = count(S(s#));- Constraint sc4
if NOT(is_empty(P)) then
count(P WHERE color = color('red'))>0
end if
数据库约束
- 两种或以上不同关系变量的相互联系
- 二元不同关系变量如何相关
- 约束检查推迟到事务结束
例如:
- Constraint dbc1 is_empty((S JOIN SP)
WHERE status<20 AND qty>qty(500));- Constraint dbc2 count(SP (s#))<=count(S (s#));- Constraint dbc3 count(SP (p#))=count(P (p#));
3.黄金定律
- 关系变量谓词
- 任何时候试图在问题关系变量上的更新都会被系统检查
- 唯一性
- 不可还原性
e.g. S(s#) is a key, S(s#,age) is a super key
主码和替换码
- 选择其中一个码作为主码
- 其他被称为候选码
- 主码不能为空
外码
- R2是一个关系变量,R2的外码是R2中的一个集合FK,满足
- 存在一个关系变量R1具有候选码CK
- 在任何时候,R2中的FK中的每个值与在R1的当前值的某些元组的CK值相等
术语:
- 参照限制
- 参照元组
- 参照关系变量
- 被参照关系变量
- 自参照、参照环
参照完整性
- 数据库不能包含任何未匹配的外键值
- 定义:
FOREGIN KEY{<item commalist>}
REGERENCES
<relvar name> (<item commalist>)ON DELETE
CASCADE/RESTRICT/NO ACTION
ON UPDATE
CASCADE/RESTRICT/NO ACTION- 触发程序:自动调用在发生特定事件或触发条件的程序5,SQL的支持
- SQL_92中的check语句允许域被约束
- constraint value-test check(value>=4.00)
- 子句constraint value-test是可选的,用于指示某个更新违反的约束
- 可以在域检查中包含复杂的条件
constraint cName-type-test
check(value in
('Shanghai','Beijing'))
check(cityname in
(select cityname from S))
更多例子:
balance integer check(banlance>=10)
gender char(1) check(gender in ('F','M'))
cnum char(4) check(cnum in
(select cnum
from course))
键约束
- create table语句包含的primary key语句包含属性的主键值
- create table语句包含的unique key语句包含属性构成的候选码
- create table语句包含的foreign key语句包含属性构成的外码以及外码的参照值
create table customer
(customer-name char(20),
customer-street char(30),
customer-city char(30),
primary key(customer-name))
create table branch
(branch-name char(15) primary key,
branch-city char(30),
assets integer);参照完整性
create table account
(account-number char(10) primary key,
branch-name char(15),
balance integer,
foreign key (branch-name)
references branch (branch-name)
)create table depositor
( customer-name char(20),
account-number char(10),
primary key (customer-name, account-number),
foreign key (account-number)
references account (account-number),
foreign key (customer-name)
references customer (customer-name)
)
create table EMP
...
foreign key(D#)
references DEPT(D#)
on delete cascade
on update cascade
...)on delete cascade语句
- 如果删除DEPT中的元组导致参照完整性的破坏,EMP中的级联删除,会删除参照DEPT中的被删除的元组
- cascading updates也相似
create table account
(account-number char(10) primary key,
branch-name char(15),
balance integer,
foreign key (branch-name)
references branch (branch-name)
) ON DELETE CASCADE create table depositor
(customer-name char(20),
account-number char(10),
primary key (customer-name,account-number),
foreign key (account-number)
references account (account-number)
ON DELETE CASCADE,
foreign key (customer-name)
references customer (customer-name)
ON DELETE CASCADE)如果有一个依赖于多重关系的外键链,对每个依赖指定的级联删除,删除或更新可以从链的一端传播到整个链如果一个级联删除导致约束被破坏,且其不能通过进一步的级联操作处理,系统终止事务。结果,所有因事务引起的变化以及其级联操作被撤销了
参照完整性只在事务的最后被检查
替代级联:
not null:如果一个外键的任何属性是null,元组定义为满足外键约束
Create Table EMPLOYEE(empno number(4) Primary key,
ename varchar2(10)
constraint check(ename=upper(ename)),
job varchar2(14),
mgr number(4) constraint emp-mgr
references employee(empno),
hiredate date defaut sysdate,
sal number(7,2) not null,
deptno number(2) not null,
constraint emp-dept foreign key (deptno)
references department(deptno)
ON DELETE SET NULL
ON UPDATE SET DEFAULT);Create Table SP(s# s# not null,
p# p# not null,
qty qty not null,
primary key (s#, p#),
foreign key (s#) references S
on delete cascade
on update cascade,
foreign key (p#) references P
on delete cascade
on update cascade,
check (qty>0 and qty <5001));Create Table S(s# number(5) primary key,
sname char(8) unique,
status number(2),
city char(20));Create Table Marrige
(husband name not null,
wife name not null,
mdate date default sysdate,
primary key (husband,wife));在create语句后添加约束:Create Table EMPLOYEE(empno number(4) Primary key,
ename varchar2(10)
constraint check (ename=upper(ename)),
job varchar2(14),
mgr number(4) constraint emp-mgr
references employee(empno),
hiredate date default sysdate,
sal number(7.2) not null,
deptno number(2) not null,
constraint emp-dept foreign key (deptno)
references department(deptno)
ON DELETE SET NULL
ON UPDATE SET DEFAULT);6.断言
格式:
create assertion <assertion-name>
check <predicate>当一个断言生成时,系统测试它的有效性,并且每次可能违背断言的更新发生时会进行重新测试这个测试可能会引入很大的负担,因此断言应该小心使用
例如:
1. Create assertion ic1
check ((select min(status) from S)>4);
2. Create assertion ic2 check
( not exists (select * from P
where NOT (wight>0.0)));
3. Create assertion ic3 check
( not exists (select * from P
where color = 'red'
AND city <>'London'));
4. Create assertion ic4 check
(not exists (select * from P,SP
where P.p# = SP.p#
AND (weight*qty) > 20000.0));
5. Create assertion ic5 check
(not exists (select * from S,SP
where status <20
AND S.s# = SP.p#
AND qty > 500));
每个部门的工资总和必须小于d1部门的所有工资总和:create assertion sum-constraint check
(not exists (select * from EMP e2
where (select sum(sal)
from EMP e1 where e1.d# = e2.d#
>=(select (sum(sal)
from EMP where d# = 'd1')));每一笔贷款都有至少一个借款人,且借款人保持账户最低余额为1000美元: create assertion balance-constraint check
(not exists (
select * from loan
where not exists (
select * from borrower,depositor,acount
where loan.loan-number = borrower.loan-number
and borrower.customer-name=depositor.customer-name
and depositor.ccount-number=account.account-number
and account.balance >= 1000)));注意:每次进行有可能违背断言的更新时都会进行断言测试设计一个触发机制,我们必须:
- 设置账户余额为0
- 建立在透支额度的贷款
- 给这个贷款账户一个贷款数额,使其等同于透支的数额
执行触发器的条件是对账户关系的更新导致负的账户余额
create trigger overdraft-trigger after update on account
referencing new row as nrow
for each row
when nrow.balance<0
begin atomic
insert into borrower
(select customer-name,account-number
from depositor
where nrow.account-number=depositor.account-number);
insert into loan values (nrow.account-number,
nrow.branch-name, -nrow.balance);
update account set balance=0
where account.account-number=nrow.account-number
end触发事件和动作- 触发事件可以插入、删除和更新
- 触发更新可以被限制到特定的属性
e.g create trigger overdraft-trigger after
update of balance on account
可以被引用的更新之前和之后的属性值:
语句级触发器
- 使用 referencing old table 或 referencing new table来引用包含被影响行的临时表
- 当使用SQL语句来更新大量rows时更有效
我们有时需要外部世界的行动,如对仓库中数量变少的物品进行重新排序,或在数据库更新触发时打开报警灯
假设一个仓库有如下的表:
inventory(item,amount)
minlevel(item,level)
reorder(item,amount)
orders(item,amount)create trigger reorder-trigger after update of amount on inventory
referencing old row as orow, new row as nrow
for each row
when nrow.amount <= (select level from minlevel
where minlevel.item = lrow.item)
and orow.amount > (select level from minlevel
where minlevel.item = orow.item)
begin
insert into orders (select item, amount
from reorder where reorder.item = orow.item)
end Triggers in SQL Server Syntax:create trigger overdraft-trigger on account
for update
as if nrow.balance < 0
begin
insert into borrower
(select customer-name,account-number
from depositor,inserted
where inserted.account-number =
depositor.account-number)
insert into loan values
(inserted.account-number,inserted.branch-name,
-inserted.balance)
update account set balance = 0
from account,inserted
where account.account-number = inserted.account-number
endDeferred Check推迟检查
INITIALLY DEFERRED
INITIALLY IMMEDIATE
在每trans开始时定义其状态
NOT DEFERRABLE
switched on and off
SET CONSTRAINTS
<constraint name commalist> <option>;
E.g.
SET CONSTRAINT ic3 DEFERRED;
COMMIT forces a SET IMMEDIATE for all DEFFERABLE constraints
7655



被折叠的 条评论
为什么被折叠?



