SQL¶
约 884 个字 355 行代码 35 张图片 预计阅读时间 9 分钟
- A query returns a single table
Essential¶
DDL¶
Create
create table student
(
id int,
name varchar(8) not null,
...
<完整性约束>
primary key(id),
foreign key(..) references department
);
Select
SELECT * FROM Websites
WHERE xx>15
AND (country = 'US' or 'CN')
;
// 去重复
SELECT DISTINCT country FROM Websites;
// 自然连接 考虑的是不同关系中都出现的属性,取这些相同属性都相等的tuple;
select A
from r1 natural join R2 using <attributes>
// 排序
order by salary desc, name asc
- The operands of the logical connectives can be expressions involving the comparison operators <, <=, >, >=, =, and <>.
order by (conlumns) ASC|DESC
Insert INTO
INSERT INTO table_name (column1,column2,column3,...)
VALUES (value1,value2,value3,...);
INSERT INTO table_name
VALUES (value1,value2,value3,...);
insert into table1 select * from table1
insert into instructor
select ID, name, dept_name, 18000
from student
where dept_name = 'Music' and total_cred > 144;
Update
where 限制很重要!!
UPDATE Table
SET name = "666",Country = 'CN'
WHERE id = 4;
DML¶
Delete
delete from Table 删除所有属性
where ...
// 在执行任何删除之前对所有元组完成处理很重要,否则执行过程中可能会发生变化
delete from instructor
where salary < (select avg (salary)
from instructor);
Drop
drop table r; 删除
Alter
alter 操作针对的是attribute
https://www.runoob.com/mysql/mysql-alter.html
alter table r add att Domain
alter table r drop att
alter table drop foreign key <约束名>;
alter table takes add constraint tb_id foreign key(id) references student(id);
操作¶
Limit
限制选中的数目
limit number;
附加的操作¶
更名¶
- 用于区分同一个关系的笛卡尔积
select distinct T.name
from instructor as T, instructor as S
where T.salary > S.salary and S.dept_name = ""
string¶
使用 LIKE
字符来完成模式匹配
- % 匹配任意字符串 "%dar%"
- _ 匹配任意一个字符 " _ " 三个字符
用escape
来定义转义字符
where building like '%ab\%cd%' escape '\'
// 包含ab%cd
集合 | Set Operation¶
// 自动去重
A union B
A union all B
A intersect B
A except B
null¶
- 算术表达 结果为空
- 比较 unknown
select count (distinct ID)
from teaches
where semester = 'Spring' and year = 2018;
聚集函数¶
avg min max sum count
group by
having
select dept_name, avg (salary) as avg_salary
from instructor
group by dept_name;
select count (*)
from course;
select dept_name, avg (salary) as avg_salary
from instructor
group by dept_name
having avg (salary) > 42000;
Nested | 嵌套子查询¶
select distinct course_id
from section
where semester = 'Fall' and year= 2017 and
course_id in (select course_id
from section
where semester = 'Spring' and year= 2018);
some
all
exists
select name
from instructor
where salary > some (select salary
from instructor
where dept name = 'Biology')
select distinct
S.ID,
S.name
from
student as S
where
not exists (
(
select
course_id
from
course
where
dept_name = 'Biology'
)
except
(
select
T.course_id
from
takes as T
where
S.ID = T.ID
)
);
unique
not unique
SQL 中unique用于约束
select T.course_id
from course as T
where unique ( select R.course_id
from section as R
where T.course_id= R.course_id
and R.year = 2017);
select id,name,course_code,score,year
from
student natural join takes as C
where (id,course_code) in
(
select distinct id, course_code
from takes as T
where C.id = T.id
);
from
# Error : Every derived table must have its own alias
select id,name,course_code,score,year
from
(
select id,name,course_code,score,year
from student natural join takes
where id = '0001'
# ' as course ' here is bound to be added
) as course
where score >= 90;
with
with max_budget (value) as
(select max(budget)
from department)
select department.name
from department, max_budget
where department.budget = max_budget.value;
Scalar
Scalar (标量) subquery is one which is used where a single value is expected
case
case
when pred then result
when pred then result
else result
end
update student S
set score = case
when ... t.hen
else 0
end
Intermediate¶
Join¶
natural join
只保留一组相同的元素; 使用 on condition 的join操作将会存在两个重复的condition属性
natural left/right/full outer join
using (attribute)
on condition
例如
using course_id
on takes.course_id = student.course_id
Views¶
- 一种虚关系
create view v as <query>
create view departments_total_salary (dept_name, total_salary) as
select dept_name , sum salary
from instructor
group by dept_name
- Recursive case 的expand?
Materialized Views | 物化视图¶
- 物理存储 :不需要在每次调用时重新进行查询操作(虚关系需要)
- If relations used in the query are updated, the materialized view(视图维护) result becomes out of date
- Need to maintain the view, by updating the view whenever the underlying relations are updated.
视图更新¶
- 更新一个视图必须要给出对实际关系的修改
Most SQL implementations allow updates only on simple views
- The from clause has only one database relation.
- The select clause contains only attribute names of the relation, and does not have any expressions, aggregates, or distinct specification.
- Any attribute not listed in the select clause can be set to null
- The query does not have a group by or having clause.
Transaction | 事务¶
Atomic transaction
事务是由查询和(或)更新语句的序列组成。SQL语句规定当一条语句开始时,一个事务开始执行,下面的语句会终止一个事务
commit work
: 提交事务rollback work
: 回滚事务
在SQL的实现中,很多情况下都默认一条语句自成一个事务,一旦执行完成就会提交
Integrity Constraints¶
Constraints on a Single Relation
- not null
- primary key
- **unique ** ? a super key
- check (P), where P is a predicate
check & assertion¶
- 谓词检测
create table section
(
course_id varchar (8),
sec_id varchar (8),
semester varchar (6),
year numeric (4,0),
building varchar (15),
room_number varchar (7),
time slot id varchar (4),
primary key (course_id, sec_id, semester, year),
check (semester in ('Fall', 'Winter', 'Spring', 'Summer'))
)
- assertion的维护代价比较高
create assertion <assertion-name> check <predicate>;
// 插入修改tuple时要check,time_slot改变时也要check
check (time_slot_id in (select time_slot_id from time_slot) )
create assertion credits_earned_constraint check (
not exists (
select
ID
from
student
where
tot cred <> (
select
coalesce(sum(credits), 0)
from
takes natural
join course
where
student.ID = takes.ID
and grade is not null
and grade <> 'F'
)
)
);
referential intergrity | 参照完整性¶
不同于外码约束,参照完整性约束并不要求目标属性是某个关系的主码。但是,foreign key 要求至少是候补码
foreign key () references _
on delete set NULL
// 级联
on delete cascade
on update cascade
增加与删除¶
ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>
FOREIGN KEY(<列名1>) REFERENCES <主表名> (<列名2>);
# 注意,外键名是用户定义的,
alter table takes add constraint tb_id foreign key(id) references student(id);
Data Type & Schema¶
Data¶
Time
默认值
create table student
(
ID varchar(5),
tot_cred numeric(3,0) default 0
)
Index¶
create index <name> on <relation name> (attribute);
create table student(
ID varchar (5),
name varchar (20) not null,
dept_name varchar (20),
tot_cred numeric (3, 0),
default 0,
primary key (ID)
);
create index studentID_index on student(ID)
// 删除索引
drop index student_id on student;
The query:
select *
from student
where ID = '1001'
can be executed by using the index to find the required record, without
looking at all records of studen
Large Object | 大对象类型¶
bookreview clob (2KB)
image blob (10MB)
movie blob (2GB)
- When a query returns a large object, a pointer (定位器) is returned rather than the large object itself.
User-defined Type¶
这里介绍的是distinct Type
create type Dollars as numeric (12,2) final
create domain DDollars as numeric (12,2) not null
constraint Dollars_test check ...;
create table department
(
dept_name varchar (20)
building varchar (15)
budget Dollars
);
cast 数值转换
cast(department.budget to numeric(12,2))
对于强类型检查,必须这样处理
Domain¶
Authorization¶
grant / revoke <privileges list>
on <关系/视图>
to <user list>
grant update(dept)
on department
to Alan
- a
user id
public
, which allows all valid users the privilege granted- A
role
Role¶
- 创建一个 role,这个role可以授予给其他role/user,也可以接受授权(给我的感觉像是一个Tag)
create role instructor
grant class to instructor
视图的授权¶
- 视图的创建者不需要视图上的所有权限
模式的授权¶
权限转移¶
with grant option
grant select on depart to Aimit with grant option
权限收回¶
- 默认情况下,权限的收回是级联的
revoke select on department from Amit , Satoshi cascade
revoke select on department from Amit , Satoshi restrict
Advanced¶
程序语言¶
ODBC¶
JDBC¶
- try 将异常抛出 到 catch
Prepared Statement
SQL Injection
Metadata Features
Transaction Control in JDBC
SQLJ¶
Embedded¶
# 连接到数据库
EXEC SQL connect to server user user-name using password;
# 宿主变量用 : 加以区分
# They are preceded by a colon (:) to distinguish from SQL variables (e.g., :credit_amount )
# must be declared within DECLARE section,
EXEC-SQL BEGIN DECLARE SECTION
int credit-amount ;
EXEC-SQL END DECLARE SECTION;
EXEC SQL
# 用c作为标识
declare c cursor for
select ID, name
from student
where tot_cred > :credit_amount
END_EXEC
EXEC SQL open c ;
函数和过程 | function and procedures¶
触发器 | Trigger¶
- **Event : **
delete 、 insert 、update(
create trigger <trigger name> after <Event> of <relation> on <attribute>
) - before 触发 维护完整性约束;有助于外键的插入
- after 触发
TIPS:
IN MySQL, 下面的语句是不存在的,要使用关键字
old
new
来表征referencing new row as nrow; referencing old row as orow;
create trigger <trigger name> after <Event> on <relation>
referencing new row as nrow;
referencing old row as orow;
# 指定为行级触发,对于每一行触发的tuple都执行下述行为
for each row
when ( condition )
begin atmotic
end;
# 对学分的更新
create trigger credits_earned
after
update
of takes on (grade) referencing new row as nrow referencing old row as orow for each row
when nrow.grade <> 'F'
and nrow.grade is not null
and (
orow.grade = 'F'
or orow.grade is null
) begin atomic
update
student
set
tot_cred = tot_cred + (
select
credits
from
course
where
course.course_id = nrow.course_id
)
where
student.id = nrow.id;
end;
何时不应使用触发器¶
Function¶
create function dept_count (dept_name varchar(20))
returns integer
begin
declare d_count integer;
select count (* ) into d_count
from instructor
where instructor.dept_name = dept_name
return d_count;
end
# The function dept_count can be used to find the department names and budget of all departments with more that 12 instructors.
select dept_name, budget
from department
where dept_count (dept_name ) > 12
- 注意下面的 return 和 returns
Procedure¶
例题¶
Trigger¶
- 插入多行的一种用法
insert into select from
create trigger insert_depositor
after insert on depositor
referencing new row as nrow
for each row
begin
insert into
select branch_name, customer_name
from depositor, account
where nrow.account_number = account.account_number
end;
create trigger insert_customer
after insert on customer
referencing new row as nrow
for each row
begin
insert into
select branch_name, customer_name
from depositor, account
where nrow.account_number = depositor.account_number
end;