常用SQL第二部分

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kswkly/article/details/79848596

首先我们创建两个表以供后面使用,分别是学生信息表student和学生选课信息表takes,如下:
create table student(
id varchar(10),
name varchar(15),
department varchar(20),
primary key(id));
create table takes(
id varchar(10),
course_id varchar(5),
course_name varchar(10),
primary key(id,course_id)
);
连接表达式
natureal join表示从两个表中选择这样的元组:他们在具有相同属性名上的取值相同。例如我们查询计算机系的学生所选的课程:
select s.id course_name from student as s natural join takes where s.department = ‘计算机’
SQL也可以指定任意的连接条件,on条件允许在参与连接的关系上设置通用的谓词,例如查询所有学生所选的课:
select * from student join takes on student.id = takes.id
自然查询虽然功能很强,但是也有不可避免的缺点,他所查出的必须是两个关系中都有的且同名属性相同的元组,但是那些只有一个关系中有的元组就被丢弃了。这样就会造成一些问题,例如我们想查询所有学生的选课信息,但是如果某些学生没有选课,用自然连接的方式就会把这些学生丢弃,这是我们所不希望看到的,为此我们引入了外连接。
1、左外连接(left outer join):只保留出现在左外连接运算之前(左边)的关系中的元组
2、右外连接(right outer join):只保留出现在右外连接之后(右边)的关系中的元组
3、全外连接(full outer join):保留出现在两个关系中的元组
例如:
select * from student natural left outer join takes
视图
有时候出于安全考虑我们可能不想让某些人看到或者操作数据库中的全部数据,比如说学生可以知道老师的姓名、学院等信息,但是没有权利看到老师的工资信息。为了满足这种需求SQL允许通过查询来定义“虚关系”,虚关系并不预先计算或者存储,而是使用的时候才进行计算。任何像这种不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图。我们用create view来定义视图,格式如下:
create view v as (查询表达式)
例如:create view basic as select name,department from student
一些特定的数据库允许存储视图关系,且保证如果用于定义视图的实际关系改变,视图也跟着修改。这样的视图被称为物化视图。注意:我们一般不允许对视图关系进行修改,虽然有些也可以,但是强烈不建议。
单关系上的约束
在创建表时除了主码约束以外,还有其它约束,例如:not null,unique,check(谓词),外码。为了方便说明,我们创建一个表,如下:
create table student(
id varchar(10) not null,
name varchar(20),
sex varchar(2),
department varchar(20),
unique(id),
primary key(id),
foreign key(department)references department,
check(sex in(‘男’,‘女’))
);
涉及到外码就会牵扯到一个概念,叫做参照完整性或者子集依赖:关系r1,r2的属性集分别是R1和R2,主码分别是K1和K2,如果要求对r2中任意元组t2,均存在r1中元组t1,使得t1.K1 = t2.b,我们称R2子集中的b为参照关系r1中K1的外码。默认情况下SQL中外码参照的是其他关系的主码。这样就存在了一个问题:当被参照关系发生删除或者更新时就违反了参照完整性,为了解决这个问题我们可以在foreign key子句中指明:如果被参照关系上的删除或者更新动作违反了约束,那么系统就必须采取一些步骤通过修改参照关系中的元组来恢复完整性约束,如下:
create table student(
foreign key(department)reference department
on delete cascade
on update cascade,

断言
一个断言就是一个谓词,用来检测数据库是否满足某些条件,域约束和参照完整性约束是断言的一种特殊形式。断言格式如下:
create assertion name check predicate
比如,我们想要对student关系中的每一个学生他的total_cred总分等于他所修课程的学分总和:
create assertion credit check
(not exits (
select id from student where total_cred<>
(select sum(credits) from takes where student.id = takes.id)

其中student中记录的是学生基本信息,takes记录的是学生选课信息和分数。由于SQL不提供for all x,P(x)的结构(p是谓词),我们要用not exits x such that not P(x)来实现。
SQL的数据类型
日期和时间
data:日历日期,年月日,例如:2018-04-04
time:时钟时间,时分秒,例如:09:28:34
timestamp:date和time的组合2018-04-05 10:35:21
其中time和timestamp的秒部分可以是小数。
我们可以用cast str as t的形式把一个字符串转化为类型t,t是date、time或者timestamp的一种。例如:cast ‘2018-04-06’ as data
我们也可以用extract (field from d)从data或time中提取单独的区域,区域可以使year、month、day、hour、minute、second。例如:extract (year from ‘2018-04-06’)
我们可以用current_data返回当前日期,或者用current_time或者localtime来返回当前时间,或者用current_timestamp或localtimestamp返回本地日期和时间。
我们还可以对日期和时间进行加减计算,例如,x,y都是data类型的,那么x-y就是天数间隔
默认值
SQL允许指定属性的默认值,例如:
create table student(
……
credit numeric(3,0)default 0,
…..

大对象类型
SQL允许你在数据库中存储一些图片、视频等非常大的数据,它将这些大对象分为两类:字符数据(clob)和二进制数据(blob),例如,我们可以声明属性:
book clob(10K)
image blob(10MB)
movie blob(3GB)
其实数据库并没有把这些大对象真正的存入其中,而只是存了一个这些大对象的索引而已。
自定义类型
SQL允许用户自定义数据类型,分为两类:独特类型和结构化数据类型。
我们可以使用create type来创建新类型,如下:
create type dollor as numerical(10,2)final
create type pound as numerical(10,2)final
意思就是我们创建了一个名为“dollor”和“pound”的数据类型,共有10位,其中有两位小数。虽然这两个数据类型的本质是一样的,但是当我们尝试将一个pound类型的数据赋予给一个dollor类型的数据时会导致一个编译时错误,这是因为我们所创建的是强类型。为了解决这个问题人们引入了“域”这个概念,示例如下:
create domain dollor as numerica(10,2)not null
域和类型之间的区别:
1、域可以声明约束
2、域不是强类型的,所以一个域类型的值可以赋给另一个域类型。
授权
SQL的标准有select、insert、delete和update权限。我们可以用grant关键字来进行授权,如下:
grant <权限名称> on <关系或者视图> to <用户或角色>
同样我们也可以用revoke关键字来收回权限,如下:
revoke<权限名称> on <关系或者视图> from <用户或角色>
角色
考虑一个问题:我们要将某些权限赋给某一类人,如果一个一个的写grant语句进行授权就会十分麻烦。一个更好的解决方案是:指明这类人的权限,然后标出这类所在的数据库。系统用着两条信息给这类人自动授权。于是就引入了角色这个概念。在数据库中创建一个角色集合,可以给角色授予权限。每个数据库用户被赋予一组他有权扮演的角色。例如:
create role teacher
然后给角色赋予权限
grant select on student to teacher
角色可以授权给用户或者其他角色
grant teacher to 某某
create role dean
grant teacher to dean
视图授权
如果我们只想让某人仅有权查询一个关系中的部分数据该怎么办呢?这时候视图就又显示处它的作用了。你可以先创建一个视图,然后让用户去查询这个视图。当然前提是你要赋予这个用户查询的权利。
权限的转移
如果我们希望给一个用户授予某些权利,并且运行他把这些权力再赋给别人,我们可以用with grant option来实现,例如:
grant select on teacher to 某某 with grant option
权限收回
如果我们将权限赋给了a,a又将权限赋给了b,现在我们将a的权限收回,那么b的权限也会被一起收回,这就是级联收回。级联是默认的行为。当然我们也可以用restrict来防止级联收回,如下:
revoke select on teacher from a restrict
下面的revoke仅仅收回grant option,并不收回select权利:
revoke grant option for select on teacher from a

猜你喜欢

转载自blog.csdn.net/kswkly/article/details/79848596