一个实例->多个数据库
一个数据库->多个模式
一个模式->多个表、识图、索引
1.SQL简介
SQL无论是在传统的关系型产品,还是当今大数据时代的分析型系统中都被普遍采用。
SQL三种类型的表
关系数据库中的关系数据对应SQL中的表:一个SQL表由行集构成,每一行是数据项的序列。
SQL中有三种类型的表:基本表(物理上用文件存储其定义和数据,是实表)、视图(存储定义,在使用视图时按定义和依赖的基本表内容产生数据,是虚表)和导出表(执行查询时产生的表)。
SQL三级体系结构
SQL的功能
SQL 尽管被称为查询语言,但它实际上包含DBMS的全部功能,核心部分包括以下4部分:
1)数据定义语言(DDL),用于定义、删除、修改SQL模式、基本表、视图、删除索引等;
2)数据操纵语言(DML),用于查询和更新(增、删、改)数据;
3)数据控制(DCL),管理用户、访问权限、完整性和事务;
4)嵌入式SQL使用规则。
SQL的特点
(1)一体化:SQL语言集4大功能于一体
—数据查询功能语言(SELECT语句),其功能非常强大
—数据操纵语言DML(INSERT, UPDATE, DELETE语句)
—数据定义语言DDL(如CREATE, DROP语句)
—数据控制语言(如COMMIT, ROLLBACK, GRANT, REVOKE等语句)
(2)语法简单,功能强大
(3)不是程序开发语言,是程序开发中的一部分,用于操纵数据。两种使用方式 :
1.交互方式
2.嵌入式方式
(4)非过程化语言,以元组集合作为操作对象
(5)国际标准语言,便于移植;
(6)抽象程度高,类似于人的思维习惯,容易理解和掌握
2.SQL的数据定义
一个**SQL模式(Schema)**也就是所谓的"数据库"。
创建数据库:
create database 数据库名[…]
撤消数据库
drop database 数据库名
打开数据库
use 数据库名
SQL的主要数据类型有:
(1)数字型
integer:整数 (4Byte)
smallint:整数类型 (2Byte)
numeric(p, d):定点数,小数点左边p位,右边q位
real:浮点数
double precision:双精度浮点数
float(n):浮点数,精度至少为n位
(2)字符串型
char(n):固定长度的字符串
varchar(n):可变长字符串
(3)位串型
bit(n):定长,
bit varying(n) 变长二进制位串
(4)时间型
date:日期(年、月、日)
time:时间(小时、分、秒)
3.基本表的操作
创建数据库后,即可在其中创建基本表。对表结构的操作有创建、修改和撤消三种操作。
基本表的创建(CREATE)
create table 表名
(
<列名> <数据类型> [列级完整性约束] , //定义各个列时,指明数据类型和长度
......
[表级完整性约束] //没有逗号
//完整性约束包括列级完整新约束和表级完成整形约束。
);
创建表实例:
创建表
修改基本表定义(ALTER操作)
ALTER 可以修改基本表(包含ADD、DROP、CHANGE、MODIFY等改变方式)
ALTER TABLE 表名 改变方式
格式:
alter table 表名
[add 子句] 增加新列
[drop 子句] 删除列
[modify 子句] 修改列属性定义
示例
alter table S
add column DEPT char[30]
撤消(删除)基本表定义(drop)
撤消基本表后,基本表的定义、表中数据、索引、以及由此表导出的视图的定义都被删除。
格式
drop table 表名
示例
drop table DEPT
4.SQL的数据更新
SQL的数据更新包括数据的插入、删除和修改3种操作。
插入操作(insert)
SQL 中的 insert into 语句用于向表中插入新记录
1.无需指定要插入数据的列名,只需提供被插入的值即可
insert into table_name values (value1, value2 ,...);
这种语句要求插入的数据要按照创建表时字段的顺序排列数据
2.需要指定列名及被插入的值
insert into table_name( column1, column2,...) values(value1, value2 ,...);
这种语句形式不要求 column1 、column2 与表结构创建的顺序一致,但要求 column 与 value 要一一对应(键值对应)
3.在插入批量数据时
INSERT INTO table_name( column1, column2,...) VALUES(v101,v102),(v201,v202),(v301,v302),(v401,v402);
删除操作(delete)
从表中删除符合条件的元组,如果没有where语句,则删除所有元组。
delete from 表名 [where 条件表达式]
修改操作(modify)
modify操作为alter操作下的一个模块,用于修改列的属性。
alter table 表名 modify 列名 数据类型;
查询操作(select)
select 列名1, 列名2,...,列名n
from 表名1,表名2,...,表名n
where 条件
WHERE 条件:
where子句语法成分
比较运算符: >=、=、<>(不等于)
逻辑运算符:and,or,not
集合成员资格运算符:In,not in,between
条件谓词:exists,all,some,unique
聚集函数:
平均值:avg
最小值:min
最大值:max
总和:sum
记数:count
F 中运算对象可以是另一个select语句结果。
集合运算
select语句的查询结果可以进行集合操作,命令有:
集合交:intersect
集合差:except
集合并:union
如果将几个表看成集合,
匹配问题就是集合运算中的交集。
不匹配问题就是集合运算中的差。
匹配问题+不匹配问题就是集合运算中的并集。
集合运算要求两个select语句是同构的,即列的个数和数据类型必须一致
union的结果集为两个查询结果的并集,是去掉重复值的
union all的结果集为两个查询结果的并集,是包含重复值的
intersect的结果集为两个查询结果的交集,不包含重复值
minus的结果集为属于第一个查询的结果集,但不属于第二个查询的结果集即从第一个查询的结果集中减去他们的交集,不包含重复值
UNION使用示例:
假设有三张表:
采用UNION操作后:
SELECT a.id AS id,
a.name AS NAME,
a.type AS TYPE,
NULL AS age,
NULL AS sex
FROM A a
UNION
SELECT b.id AS id,NULL AS NAME,NULL AS TYPE, b.age AS age,NULL AS sex FROM B b
UNION
SELECT c.id AS id,NULL AS NAME,NULL AS TYPE, c.age AS age ,c.sex AS sex FROM C c
得到的结果集:
in和exists
in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的。如果查询的两个表大小相当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in;
例如,对于A表(大表),B表(小表):
大查小:
select * from A where cc in(select cc from B) -->效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) -->效率高,用到了B表上cc列的索引。
相反的小查大:
select * from B where cc in(select cc from A) -->效率高,用到了B表上cc列的索引
select * from B where exists(select cc from A where cc=B.cc) -->效率低,用到了A表上cc列的索引。
not in和not exists
尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)
如果查询语句使用了not in(先搞子查询,括号里面的),那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。
双重not exist运用
有三张表:
要求:检索所学课程包含学生S3所选课程的学生学号
select S# from S //选出该学生的学号
where not exists //不存在一门课
(select * from SC X
where S#=‘S3’ and not exists //学号为'S3'的学生选了,但是该学生没有选
(select * from SC
where S# = S.S# and C#=X.C#))
量词,some all 和 any
All:只有当其所有数据都满足条件时,条件才成立。
Any:只要有一条数据满足条件,条件就成立。
Some:其中存在一些数据满足条件,作用和Any大致相同,常规的使用中看作功能一致即可。
检索不学C2课程的学生姓名与年龄:
select SNAME,AGE
from S
where S#<>all ( select S# from SC
where C#=‘C2’)
select * from table
where id=Any(select id from table2 where name='larry')
近似等价于
select * from table
where id=Some(select id from table2 where name='larry')
而考虑到in的用法时,any和in可以相互转换:
select * from table
where id in (select id from table2 where name='larry')
4.索引的管理
索引是基本表表中记录的相关列值(索引关键字)与记录地址的对应(索引项)表。
索引属于物理存储路径的概念。
索引的创建
创建索引的格式:
create [unique]index <索引名>on <基本表>(列名表)
例:
对TMP_QSJ_TABLE8表中的PID列创建索引IDX_PID:
CREATE INDEX IDX_PID ON TMP_QSJ_TABLE8(PID);
唯一索引
索引表中各索引关键字上的取值互不相同,若有多行上的值相同,则只取一个。
create unique index ind_sno on S(S#)
索引项的顺序
索引值可以按(默认)升序(ASC)排列,也可以按降序(DESC)排列。
索引关键字可以包含多字段,各字段可有不同的排序。
create unique index ind_sc on SC(S# asc,C# desc)
主键索引
建表设置unique时,自动建立非聚簇唯一索引,设置primary key时,建立聚簇索引(基本表中记录顺序与索引关键字的顺序一致)。
索引在查询时自动起作用。
删除索引
建立索引是为了提高查询速度,但随着索引的增多,数据更新时,系统会花费许多时间来维护索引。因此,应删除不必要的索引。
删除索引的语句是DROP INDEX,其语法格式为:
DROP INDEX 数据表名.索引名
删除基本表SC的索引ind_sc。
DROP INDEX SC. ind_sc