本学习笔记主要参考的是王珊老师的《数据库系统概论》第三章,主要目的是复习温故,笔记中提到知识不够全面,若想较为全面的了解SQL语句,可以翻阅王珊老师的书或者《SQL必知必会》等。本人水平有限,若发现错误还请大家指正。
目录
1 模式的定义与删除
1.1 定义模型
1.2 删除模式
2 基本表的定义、删除与修改
2.1 定义基本表
2.2 数据类型
2.3 模式与表
2.4 修改基本表
2.5 删除基本表
3 索引的建立与删除
4 数据查询
4.1 单表查询
4.2 连接查询
4.2.1 等值与非等值连接查询
4.2.2 自身连接
4.2.3 外连接
4.2.4 多表连接
4.3 嵌套查询
4.4 集合查询
5 数据更新
5.1 插入数据
5.2 修改数据
5.3 删除数据
6 空值的处理
7 视图
7.1 定义视图
7.1.1 建立视图
7.1.2 删除视图
7.2 查询视图
7.3 更新视图
create schema <模式名> authorization <用户名>
若没有指定 模式名,模式名隐含为 用户名 ;
一个模型可以看作是几个数据库对象(基本表、视图、索引)的集合;
create schema中可以接受create table, create view, 和grant字句。也就是说用户可以在创建模式的同时在这个模式定义中进一步创建基本表、视图、定义授权。 例如: create schema <模式名> authorization <用户名> [<表定义子句>|<视图定义子句>|<授权定义子句>];
示例:
create schema TEST authorization ZHANG
create table Table1(
col1 smallint,
col2 int,
col3 char(20),
col4 numeric(10, 3),
col5 decimal(5,2));
drop schema <模式名>
cascade, restrict两者必选其一,其区别是cascade(级联)表示在删除模式的同时删除模型下定义的所有数据库对象;restrict(限制)表示的是如果该模式下定义了数据库对象,那么改删除操作被禁止。
注:SQL中没有修改模式的语句,如果想修改定义好的schema,需要将其先删除,然后重新定义。
经过上面的定义模式后,就建立了一个数据库命名空间,一个框架。然后,我们就可以在该空间中定义需要的数据库基本对象。
create table <表名> (
<列名><数据类型>[列级完整性约束条件],
[<列名><数据类型>[列级完整性约束条件]],
......,
[<表级完整性约束条件>]);
建表的同时通常还可以定义与该表相关的完整性约束条件,这些完整性约束条件用来规范用户对数据的操作。如果完整性约束条件涉及该表的多个属性,必须定义在表级上。否则,既可以定义在列级、也可以定义在表级。一般完整约束条件包括:primary, unique, not null, foreign key (列名) references 表名(列名)等。
示例:
create table Student(
Sno char(9) primary key,
Sname char(20) unique,
Ssex char(2),
Sage smallint,
Sdept char(20)
);
常用的有
char(n), varchar(n), int, smallint, numeric(p,d)/decimal(p,d), float(n), boolean, date, time, timestamp, interval
一个基本表属于一个模式,一个模式包含多个基本表。当定义一个表时,可以有三种方法定义其所属的模式。
法一:在表名中明显的给出模式名:
create table "S-T".Student(...);
法二:在创建模式语句中同时创建表;
法三:设置所属的模式,这样在创建表时表名中不必给出模式名:
use 模式名 go;
alter table <表名>
[add [column] <新列名> <数据类型> [完整性约束]]
[add <表级完整性约束>]
[drop [column] <列名> [cascade|restrict]] *cascade自动删除引用了该列的其他对象,比如视图
[drop [constraint] <完整性约束名> [restrict|cascade]]
[alter column <列名> <数据类型>];
drop table <表名> [restrict|cascade]
当表的数据量比较大时,查询操作会比较耗时。建立索引时加快查询速度的有效手段。数据库索引类似于图书后面的索引,能快速定位到需要查询的内容。
select [all | distinct] <目标列表达式> [, <目标列表达式>] ...
from <表名或者视图名> [, <表名或者视图名>] | (select 语句)[as] <别名>
[where <条件表达式>]
[group by <列名1> [having <条件表达式>]]
[order by <列名2> [asc|desc]];
查询经过计算的值
select子句中的 <目标列表达式> 不仅可以是表中的属性列,也可以是表达式:
select Sname, 2014-Sage
from Student;
不仅可以是算法表达式,也可以是字符串常量、函数等:
select Sname, "Year of Birth", 2014-Sage, Lower(Sdept)
from Student
可以为查询结果的列标题指定别名:
select col1 Name1, col2 Name2,[col3 Name3],...
from table1
消除取值重复的行:
select distinct Sno
from Student
没有distinct,则默认为all
字符匹配:
like "<匹配串>" [escape "<换码字符>"]
注:数据库字符集为ASCII时,一个汉字需要两个_;当字符集为GBK时,只需要一个_.
如果用户要查询的字符串本身就含有通配符%或者_,这是就要使用escape '<换码字符>' 短语对通配符进行转义了。比如:
查询DB_Design课程的课程号和学分:
select Cno, Ccredit
from Course
where Cname like 'DB\_Design' escape '\';
'\'表示的是换码字符。这样匹配串中紧跟在"\"后面的字符"_"不再具有通配符的含义,转义为普通的"_"字符。
涉及空值的查询:
where Grade is NULL;
这儿的is不能用等号(=)代替。
聚集函数:
当聚集函数遇到空值时,除了count(*)外,其余的都跳过空值而只处理非空值。注意:where子句中是不能用聚集函数作为条件表达式的,聚集函数只能用于select子句和group by中的having子句。
wherer子句和having短语的区别在于作用对象不一样,where子句作用于基本表或者视图,从中选择满足条件的元祖。Having短语作用于组,从中选择满足条件的组。
若一个查询同时涉及两个以上的表,则称之为连接查询。包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询、复合条件连接查询等。
[<表名1>.]<列名1><比较运算符>[<表名2>.]<列名2>
还可以使用下面的形式:
[<表名1.>]<列名1> between [<表名2>.]<列名2> and [<表名2>.]<列名3>
当连接符为=时,称为等值连接。使用其他运算符称为非等值连接。
若在等值连接中,把目标列中重复的属性列去掉则为自然连接。
一条SQL语句可以同时完成选择和连接查询,这时where子句是由连接谓词和选择谓词组成的复合条件。
即一个表与自身连接。
在通常的连接操作中,只有满足连接条件的元组才能作为结果输出。有时仍然想以某个表为主体,这是就需要使用外连接。
示例:
select Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade
from Student left outer join SC on (Student.Sno = SC.Sno)
左外连接列出左边关系中的所有元祖,右外连接列出右边关系中所有的元祖。
关系数据库在执行多表连接时,通常是先进行两个表的连接操作,再将其连接结果与第三个表进行连接。
需要注意的是,子查询的select语句中不能使用order by子句,该子句只能对最终查询结果排序。
子查询条件不依赖于父查询,称为不相关子查询。如果子查询的查询条件依赖于父查询,这类子查询称为相关子查询。
子查询返回单值时可以使用比较运算符,但是返回多值时,要用any或者all谓词修饰符。
带有exist谓词的子查询不返回任何数据,只产生逻辑真值或者逻辑假值。
并union, 交intersect, 差except
注:参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
使用union时,系统会自动去掉重复元组。如果要保留重复元组,使用union all操作符。
select Sno, Cno
from SC, (select Sno, Avg(Grade) from SC group by Sno) as Avg_sc(avg_sno, avg_grade)
where SC.Sno = Avg_sc.avg_sno and SC.Grade >= Avg_sc.avg_grade
如果子查询中没有聚集函数,派生表可以不指定属性列,子查询select子句后面的列名为其默认属性。通过from子句生成派生表时,as关键字可以省略,但必须为派生关系指定一个别名。
添加、修改、删除
insert
into <表名> [(<属性列1>[, <属性列2>]...)]
values (<常量1>[, <常量2>]...)
into子句中没有出现的属性列,新元组再这些列上将取空值。
into子句中没有指明任何属性列名,则新插入的元组必须在每个属性列上均有值。
插入子查询的结果:
insert
into <表名> [(<属性列1>[, <属性列2>...])]
子查询;
update <表名>
set <列名>=<表达式>[,<列名>=<表达式>]...
[where <条件>];
删除语句的一般格式为:
delete
from <表名>
[where <条件>];
如果省略where子句,则表示删除表中的所有元组,但表的定义还在字典中(只不过变成了空表)。
空值的约束条件:属性定义中有not null约束条件的不能取空值。加了unique限制的属性不能取空值,码属性不能取空值。
(unique和primary key的联系和区别:都使得该属性的取值不能重复,但unique约束可以有多个,而primary key约束只能有一个)
视图是从一个或者多个基本表(视图)导出的表。它与基本表不同,是一个虚表。数据库中只存放视图的定义,不存放视图对应的数据,其数据仍然存放在原来的基本表中。视图就像一个窗口一样。
create view <视图名> [(<列名>[,<列名>]...)]
as <子查询>
[with check option];
with check option表示对视图进行update, insert, delete操作时要保证更新、插入或者删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)。
组成视图的属性列名或者全部省略或者全部指定,没有第三种选择。
示例:
create view IS_Student
as
select Sno, Sname, Sage
from Student
where Sdept='IS'
drop view <视图名> [cascade];
同对基本表的操作
同对基本表的操作