《关系数据库标准语言MySQL》
一. 关键词索引
关键词 | 语义 |
insert | 插入(增) |
delete | 删除(删) |
select | 查询(查) |
update | 更新/修改(改) |
二. 数据定义
操作对象 | 创建 | 删除 | 修改 |
模式 | create schema | drop schema | |
表 | create table | drop table | alter table |
视图 | create view | drop view | |
索引 | create index | drop index | alter index |
(一) 模式的定义与删除
Ⅰ. 定义模式
create schema<模式名>authorization<用户名>;
//例:为用户zhang创建一个模式test.
create schema test authorization zhang ;
Ⅱ. 删除模式
drop schema<模式名><cascade|restrict>; //例:删除模式test. drop schema test cascade //该语句删除了test模式,同时,该模式中已经定义的表也>被删除了
- 选择了
cascade
,表示在删除模式的同时把模式中所有的数据库对象全部删除;- 选择了
restrict
,只有在该模式中没有任何下属对象时才能执行删除语句;
(二) 基本表的定义,删除与修改
Ⅰ. 定义基本表
create table<表名>(<列名><数据类型>[列级完整性约束条件][,<列名><数据类型>[列级完整性约束条件]]
……
[,<表级完整性约束条件>]);
//例:建立一个“学生”表Student.
create table Student
/*学号*/(Sno char(9) primary key, /*列级完整性约束条件,Sno是主码*/
/*姓名*/Sname char(20) unique, /*Sname取唯一值*/
/*性别*/Ssex char(2),
/*年龄*/Sage smallint,
/*专业*/Sdept char(20));
//例:建立一个“课程”表Course.
create table Course
/*课程号*/(Cno char(4) primary key, /*列级完整性约束条件,Cno是主码*/
/*课程名*/Cname char(40) not null, /*列级完整性约束条件,Cname不能取空值*/
/*先行课*/Cpno char(4),
/*学分*/Ccredit smallint,
foreign key(Cpno) references Course(Cno) /*表级完整性约束条件,Cpno是外码,被参照表是Course,被参照列是Cno*/
);
//例:建立一个学生选课表SC.
create table SC
/*学号*/Sno char(9),
/*课程号*/Cno char(4),
/*成绩*/Grade smallint,
primary key(Sno, cno), /*主码由两个属性构成,必须作为表级完整性进行定义*/
foreign key(Sno)references Student(Sno), /*表级完整性约束条件,Sno是外码,被参照表是Student*/
foreign key(Cno)references Course(Cno) /*表级完整性约束条件,Cno是外码,被参照表是Course*/
);
Ⅱ. 数据类型
数据类型 | 含义 |
char(n), character(n) | 长度为n的定长字符串 |
varchar(n), charactervarying(n) | 最大长度为n的变长字符串 |
clob | 字符串大对象 |
blob | 二进制大对象 |
int, integer | 长整数(4字节) |
smallint | 短整数(2字节) |
bigint | 大整数(8字节) |
numeric(p, d) | 定点数, 由p位数字(不包括符号,小数点)组成,小数点后面有b位数字 |
decimal(p, d), dec(p, d) | 同numeric |
real | 取决于机器精度的单精度浮点数 |
double precision | 取决于机器精度的双精度浮点数 |
float(n) | 可选精度的浮点数,精度至少为n位数字 |
boolean | 逻辑布尔量 |
date | 日期,包括年,月,日,格式为YYYY-MM-DD |
time | 时间,包含一日的时,分,秒,格式为HH:MM:SS |
timestamp | 时间戳类型 |
interval | 时间间隔类型 |
Ⅲ. 模式与表
🔷当定义基本表时,有三种方法定义它所属的模式;
- 在表名中明显给出模式名:
create table "S-T".Student(……); /*Student所属的模式是S-T*/
- 在创建模式语句中同时创建表:
//例:为用户ZHANG创建了一个模式TEST,并且在其中>定义一个表TAB1 CREATE SCHEMA TEST AUTHORIZATION ZHANG CREATE TABLE TAB1 ( COL1 SMALLINT, COL2 INT, COL3 CHAR(20), COL4 NUMERIC(10,3), COL5 DECIMAL(5,2));
- 设置所属的模式,这样可以在创建表时表名中不必给出模式名;
Ⅳ. 修改基本表
🔷<表名>:是要修改的基本表;
alter table<列名> [add [column]<新列名><数据类型>[完整性约束]] [add<表级完整性约束>] [drop [column]<列名>[cascade | restrict]] [drop constraint<完整性约束名> [cascade | restrict]] [alter column<列名><数据类型>];
🔷add子句:用于增加新列、新的列级完整性约束条件和新的表级完整性约束条件;
- 向student表增加“入学时间”列,其数据类型为日期型;
alter table student add 入学时间 Date;
- 增加课程名必须取唯一值的约束条件;
alter table course add unique(cname);
🔷drop column子句:用于删除表中的列;
- 如果指定了cascade短语,则自动删除引用了该列的其他对象;
- 如果指定了restrict短语,则如果该列被其他对象引用,关系数据库管理系统将拒绝删除该列;
- 删除‘入学时间’列;
alter table student drop column 入学时间;
🔷drop constraint子句:用于删除指定的完整性约束条件;
🔷alter column子句:用于修改原有的列定义,包括修改列名和数据类型;
- 将年龄的数据类型由字符型改为整数;
alter table student alter column sage int;
Ⅴ. 删除基本表
drop table<列名> [restrict | cascade];
(三) 索引的建立与删除
Ⅰ. 建立索引
create [unique][cluster]index<索引名> on <表名>(<列名>[<次序>][, <列名>[<次序>]]……);
//例
create unique index Stusno on Student(Sno);
create unique index SCno on SC(Sno asc/*升序*/, Cno desc/*降序*/);
Ⅱ. 修改索引
alter index <旧索引名>rename to <新索引名>;
Ⅲ. 删除索引
drop index <索引名>;
三. 数据查询
select [all | distinct]<目标列表达式>[,<目标列表达式>]…… from <表名或视图名>[,<表名或视图名>……] | (<select语句>)[as]<别名> [where <条件表达式>] [group by <列名1>[having<条件表达式>]] [order by <列名2>[asc | desc]];
🔷select语句:根据Where子句的条件表达式从from子句指定的基本表,视图或派生表中找出满足条件的元组,再按照select子句中的目标列表达式选出元组中的属性值形成结果表;
🔷group by子句:如果有该子句,则将结果按<列名1>的值进行分组,该属性列值相等的元组为一组;如果group by子句带having短语,则只有满足指定条件的组才予以输出;
(一) 单表查询
Ⅰ. 选择表中的若干列
🔷查询指定列
1.查询全体学生的学号与姓名
select sno, sname
from student;
🔷查询全部列
2.查询全体学生的详细记录
select *
from student
🔷查询经过计算的值
3.查询全体学生的姓名及出生年份
select sname, 2022-sage
from student
Ⅱ. 选择表中的若干元组
🔷消除取值重复的行(用distinct子句)
1.查询选修了课程的学生学号
select sno
from sc;
有重复的学号
加distinct子句就会解决该问题
select distinct sno
from sc;
🔷查询满足条件的元组
查询满足指定条件的元组可以通过where子句实现。where子句常用的查询条件如下:
查询条件谓词比较=, >, <, >=, <=, !=, !>, !<, not+上述比较运算符确定范围between and, not between and确定集合in, not in字符匹配like, not like空填is null, is not null多重条件and, or, not
(一) 比较大小
1.查询所有年龄在20岁以下的学生的姓名及其年龄
select sname, sage
from student
where sage<20;
2.查询考试成绩不及格的学生的学号及成绩
select distinct sno , score
from sc
where score<60;
(二) 确定范围
3.查询年龄不在20~23岁之间的学生的姓名,系别和年龄
select sname, sdept, sage
from student
where sage not between 20 and 23;
(三) 确定集合
4.查询计算机科学系(CS),数学系(MA)和信息系(IS)学生的姓名和性别;
select sname, ssex
from student
where sdept in ('CS','MA','IS');
(四) 字符匹配
🔷like一般语法格式如下:
[not] like '<匹配串>' [escape'<换码字符>']
🔷其含义是查找指定的属性列值与<匹配串>相匹配的元组。<匹配串>可以是完整的字符串,也可以是含有通配符%和_。
🔷%
代表任意长度的字符串。如,a%b表示以a开头,以b结尾的任意长度的字符串;
🔷_
代表任意单个字符。如,a_b表示以a开头,以b结尾的长度为3 的任意字符串;
5.查询学号为201215121的学生的详细情况
select *
from student
where sno like '20172018';
6.查询所有姓刘的学生的姓名,学号和性别
select sname, sno,ssex
from student
where sname like '刘%';
7.查询姓“古”且全名为三个汉字的学生姓名
select sname
from student
where sname like '古__';
8.查询名字第二个字为“阳”的学生的姓名与学号
select sname, sno
from student
where sname like '_凤%';
(五) 涉及空值的查询
9.查询所有有成绩的学生的学号和课程号
select sno, cno,score
from sc
where score is not null;
(六) 多重条件查询
10.查询软件工程系年龄在20岁以下的学生姓名及年龄
select sname,sage
from student
where sdept ='软件工程' and sage <20;
Ⅲ. order by 子句
🔷用户可以用 order by 子句对查询结果按照一个或多个属性列的升序(asc)或降序(desc)排列,默认值为升序;
1.查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列
select sno, score
from sc
where cno = 'c3'
order by score desc;
Ⅳ. 聚集函数
函数 | 说明 |
count(*) | 统计元组个数 |
count([distinct / all] <列名>) | 统计一列中值的个数 |
sum([distinct / all] <列名>) | 计算一列值的总和(此列必须是数值型) |
avg([distinct / all] <列名>) | 计算一列值的平均值(此列必须是数值型) |
max([distinct / all] <列名>) | 求一列值中的最大值 |
min([distinct / all] <>列名) | 求一列值中的最小值 |
🔷如果指定 distinct 短语, 则表示计算时要取消重复值;若指定 all 短语 或 没指定,则表示不取消重复值;
- 查询学生总人数
select count(*)
from student;
- 查询选修了课程的学生人数
select count(distinct sno)
from sc;
- 计算选修了一号课程的学生平均成绩
select avg(score)
from sc
where cno = 'c1';
- 查询选修了1号课程的学生最高分数
select max(score)
from sc
where cno = 'c1'
- 查询学生20211525选修课程的总学分分数
select sum(ccredit)
from sc, course
where sno = '20211525' and sc.cno = course.cno;
注意:
where子句是不能用聚集函数作为条件表达式的;聚集函数只能用于select子句和group by 中的having子句;
Ⅴ. group by 子句
🔷group by 子句将查询结果按某一列或多列的值分组,值相等的为一组;
🔷分组后聚集函数将作用与每一个组,即每一组都有一个函数值;
🔷where子句与having短语的区别在于作用对象不同,where子句作用于基本表或视图,从中选择满足条件的元组,having短语作用于组,从中选择满足条件的组;
- 求各个课程号及相应的选课人数
select cno, count(sno)
from sc
group by cno;
- 查询选修了三门以上课程的学生学号
select sno
from sc
group by sno
having count(*)>3;
- 查询平均成绩大于等于90分的学生学号和平均成绩
select sno, avg(score)
from sc
group by sno
having avg(score)>90;
(二) 连接查询
🔷若一个表同时涉及两个以上的表,则称之为连接查询;
- 查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
select student.sno, sname
from sc, student
where cno = 'c2' and score > 90 and sc.sno = student.sno;
(三) 嵌套查询
🔷一个
select-from-where
语句称为一个查询块。将一个查询块嵌套在另一个查询块的where子句或having短语的条件中的查询称之为嵌套查询;
- 查询与“刘晨”同一个系学习的学生
select sno, sname, sclass
from student
where sclass in
(select sclass
from student
where sname = '刘晨');
- 查询选修了课程名为“信息系统”的学生学号和姓名
select sno, sname
from student
where sno in
(select sno
from sc
where cno in
(select cno
from course
where cname = '信息系统'));
- 找出每名学生超过自己选修课平均分的课程号
select sno, cno
from sc x
where score >=
(select avg(score)
from sc y
where y.sno = x.sno);
Ⅰ. 带有any(some)或all谓词的子查询
谓词 | 说明 |
>any | 大于子查询结果中的某个值 |
>all | 大于子查询结果中的所有值 |
<any | 小于子查询结果中的某个值 |
<all | 小于子查询结果中的所有值 |
>=any | 大于等于子查询结果中的某个值 |
>=all | 大于等于子查询结果中的所有值 |
<=any | 小于等于子查询结果中的某个值 |
<=all | 小于等于子查询结果中的所有值 |
=any | 等于子查询结果中的某个值 |
=all | 等于子查询结果中的所有值 |
!=any | 不等于子查询结果中的某个值 |
!=all | 不等于子查询结果中的所有值 |
- 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄
(四) 集合查询
四. 数据更新
(一) 插入数据
Ⅰ. 插入元组
🔷其功能是将新元组处插入指定表中;
🔷into子句中没有出现的属性列,新元组在这些列上将取空值,但是表定义时说明了not null 的属性不能取空值否则会报错;
🔷如果into子句中没有指明任何属性列名,则新插入的元组必须在每个属性列上均有值;insertinto<表名> [(<属性列1>)[,<属性列2>]…]values(<常量1>[,<常量2>]…);
- 将一个学生元组(学号:20202336,姓名:陈东,性别:男,所在系:软件工程,年龄:18岁)插入到student表中;
insert
into student(sno, sname, ssex, sage, sdept)
values ('20202336','陈东','男',18,'软件工程');
- 插入一条选课记录(‘20202336’, ‘c1’);
insert
into sc(sno, cno) values('20202336', 'c1');
Ⅱ. 插入子查询结果
🔷子查询可以嵌套在insert语句中用以生成要插入的批量数据;
insertinto<表名> [(<属性列1>)[,<属性列2>]…]子查询;
- 对每个系,求学生的平均年龄,并把结果存入数据库中;
// 首先在数据库中建立一个新表,一列为系名,另一列为相应学生的平均年龄。
create table Dept_age
(sdept char(15),
avg_age smallint);
// 然后对student表按系分组求平均年龄,再把系名和平均年龄存入新表中
insert
into Dept_age(sdept, avg_age)
select sdept, Avg(sage)
from student
group by sdept;
(二) 修改数据
🔷修改操作又称为更新操作,功能是修改指定表中满足where子句条件的元组;
🔷set子句给出<表达式>的值用于取代相应的属性列值。如果省略where子句,则表示要修改表中所有的元组。update <表名>set <列名>=<表达式> [,<列名>=<表达式>]…[where <条件>];
Ⅰ. 修改某一个元组的值
- 将学生20202336的年龄改成22岁;
update student
set sage = 22
where sno = '20202336';
Ⅱ. 修改多个元组的值
- 将所有的学生的年龄增加一岁;
update student
set sage = sage+1;
Ⅲ. 带子查询的修改语句
- 将软件工程系全体学生的成绩置60;
update sc
set score = 60
where sno in
(select sno
from student
where sdept = '软件工程');
(三) 删除数据
🔷delete语句的功能是从指定的表中删除满足where子句条件的所有元组;
🔷如果省略where子句,则表示删除表中全部元组,但表的定义仍在字典中;
🔷delete语句删除的是表中的数据,而不是关于表的定义;deletefrom <表名>[where <条件>];
Ⅰ. 删除某一个元组的值
- 删除学号为20202336的学生记录 ;
delete
from student
where sno = '20202336';
Ⅱ. 删除多个元组的值
- 删除所有学生的选课记录;
delete
from sc;
Ⅲ. 带子查询的删除语句
- 删除软件工程系所有学生的选课记录;
delete
from sc
where sno in
(select sno
from student
where sdept = '软件工程');
五. 空值的处理
1. 空值的产生
- 向sc表插入一个元组,学号是‘20202334’,课程号是‘1’,成绩为空;
insert into sc values('20202338', 'c1', null);
2. 空值的判断
🔷判断一个属性的值是否为空值,用 is null 或 is not null 来表示;
- 从sc表中找出漏填了数据的选课信息;
select *
from sc
where sno is null or cno is null or score is null;
3. 空值的约束条件
🔷属性定义中有 not null 约束条件的不能取空值;
🔷加了unique 限制的属性不能取空值;
🔷码属性不能取空值;
4. 空值的算术运算,比较运算和逻辑运算
- 找出选修1号课程的不及格的学生;
select sno
from sc
where score<60 and cno = 'c1';
- 找出选修1号课程的不及格的学生以及缺考的学生;
select sno
from sc
where cno = 'c1' and (score > 60 or score is null);
六. 视图
(一) 定义视图
Ⅰ. 建立视图
create view <视图名> [(<列名>[,<列名>]…)]as <子查询>[with check option];
🔷with check option 表示对视图进行update, insert 和 selete 操作时要保证更新,插入,删除的行满足视图定义中的谓词条件;
- 建立软件工程系学生 的视图;
create view IS_RuanJian
as
select sno, sname, sage
from student
where sdept = '软件工程';
Ⅱ. 删除视图
drop view <视图名> [casccade];
- 删除视图IS_RuanJIan;
drop view IS_RuanJian;
(二) 查询视图
- 在软件工程系学生的试图中找出年龄小于20岁发学生;
select sno , sage
from IS_RuanJian
where sage < 20;
(三) 更新视图
🔷更新视图是指通过视图来插入,删除和修改数据;
- 将软件工程系学生视图中学号为‘20202338’的学生姓名改为‘小买’;
update IS_RuanJian
set sname = '小买'
where sno='20202338';
- 向软件工程系学生试图中插入新的学生记录,其中学号为‘20202129’,姓名为‘超新’, 年龄为‘20’;
insert
into IS_RuanJian(sno, sname, sage)
values('20202129', '超新', 20);
《数据库安全性》
一. 数据库安全性控制
【对象类型==》数据库模式】的存取权限
对象 | 操作类型 |
模式 | create schema(创建模式) |
基本表 | create table(创建表), alter table(修改表) |
视图 | create view(创建视图) |
索引 | create index(创建索引) |
【对象类型==》数据】的存取权限
对象 | 操作类型 |
基本表和视图 | select(查询), insert(插入), update(更新), delete(删除), references(参考), all privileges(所有特权) |
属性列 | select, insert, update, references, all privileges |
(一) 授权:授予与收回
Ⅰ. 授予权限
grant <权限>[,<权限>]…on <对象类型> <对象名>[,<对象类型> <对象名>]…to <用户>[,<用户>]… [with grant option];
🔷将对指定操作对象的制定操作权限授予指定用户。
🔷发出该 grant 语句的可以是数据库管理员,也可以是数据库对象创建者,还可以是已经拥有该权限的用户。
🔷接受权限的用户可以是一个或多个具体用户,也可以是public,即全体用户。
🔷如果指定了 with grant option 子句,则获得某种权限的用户还可以把这种权限授予其他用户。
- 把 查询student表的权限授给用户B1;
grant select
on student
to B1;
- 把对sc表的查询权限授予所有用户;
grant select
on sc
to public;
Ⅱ. 收回权限
revoke <权限>[,<权限>]…on <对象类型> <对象名>[,<对象类型> <对象名>]…from <用户>[,<用户>]… [cascade | restrict];
🔷授予用户的权限可以由数据库管理员或其他授权者用 revoke 语句收回。
- 把用户U1查询学生学号的权限收回;
revoke select(sno)
on student
from B1;
- 收回所有用户对sc表的查询权限;
revoke select
on sc
from public;
🔷数据库管理员拥有对数据库中所有对象的所有权限,并可以根据实际情况将不同的权限授予不同的用户。
🔷用户对自己建立的基本表和视图拥有全部的操作权限,并且可以用grant语句把其中某些权限授予其他用户。
Ⅲ. 创建数据据库模式的权限
🔷grant 和 revoke 语句向用户授予或收回对数据的操作权限。
🔷对创建数据库模式一类的数据库对象的授权则有数据据库管理员在创建用户时实现。create user <username> [with][dba | resource | connect];
🔷只有系统的超级用户才有权创建一个新的数据库用户;
🔷新创建的数据库用户有三种权限:connect,resource 和 dba;
🔷create user 命令中如果没有指定创建的新用户的权限,默认该用户拥有connect权限。
🔷拥有connect权限的用户不能创建新用户,不能创建模式,也不能创建基本表,只能登录数据库。由数据库管理员或其他用户授予他权限,她才能进行权限范围内的其他操作。
🔷拥有resource权限的用户能创建基本表和视图,成为所创建对象的属主,但不能创建模式,不能创建新的用户。数据库对象的属主可以使用grant语句把该对象上的存取权限授与其他人。
🔷🔷拥有 dba 权限的用户是系统中的超级用户,可以创建新的用户,创建模式,创建基本表和视图等;dba拥有对所有数据据库对象的存取权限,还可以把这些权限授予一般用户。拥有权限 \ 可执行操作create user
创建用户create schema
创建模式create table
创建表登录数据库,执行数据查询和操纵bda可以可以可以可以resource不可以不可以可以可以connect不可以不可以不可以可以,但必须拥有相应的权限
《数据库完整性》
一. 实体完整性
(一) 定义实体完整性
🔷关系模型的实体完整性在create,table 中用 primary key 定义。
🔷对单属性构成的码有两种说明方法:
- 一种是定义为列级约束条件;
- 另一种是定义为表级约束条件;
🔷对多个属性构成的码只有一种方法,即定义为表级约束条件;
- 将student表中的sno属性定义为码;
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY, /*在列级定义主码*/
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20));
CREATE TABLE Student
(Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY(Sno)); /*在表级定义主码*/
- 将sc表中的sno, cno属性定义为码;
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Score smallint,
PRIMARY KEY(Sno, Cno)); /*只能在表级定义主码*/
(二) 实体完整性检查和违约处理
🔷定义了关系的主码后,每当用户对基本表插入一条记录或对主码列进行更新操作时,数据库管理系统将按照实体完整性规则自动进行检查;
- 检查主码值是否唯一,如果不唯一则拒绝插入或修改;
- 检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改;
二. 参照完整性
(一) 定义参照完整性
🔷关系模型的参照完整性在create,table 中用 foreign key 定义那些列为外码,用references 指明这些外码参照那些表的主码。
- 定义sc中的参照完整性;
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Score smallint,
PRIMARY KEY(Sno, Cno), /*在表级定义实体完整性*/
foreign key(sno) references student(sno), /*在表级定义参照完整性*/
foreign key(cno) references course(cno)); /*在表级定义参照完整性*/
(二) 参照完整性检查和违约处理
🔷