iOracle实战笔记(第五天)
导读
今天的主要内容:维护数据的完整性、索引、管理Oracle的权限和角色。
一、维护数据库的数据的完整性
数据完整性用于确保数据库数据遵从一定的商业规则和逻辑规则。在Oracle中,数据完整性可以使用约束、触发器、应用程序(过程和函数)三种方法来实现。在这三种实现方法中约束最易于维护,且性能最好,所以一般使用约束来作为数据维护的是首选。下面内容也主要是对约束的讲解。
1、约束(Constraint)
约束用于确保数据库满足特定的商业规则。Oracle中约束包括五种:not null(非空)、unique(唯一)、primary key(主键)、foreign key(外键)、check(检查)。
- not null:非空约束,当该列定义了not null约束是,那么该列数据不允许为空。
- unique:数据唯一约束,当定义了unique约束,该列值不能重复,但允许为空。
- primary key:主键约束,用于唯一标识表行的数据,该列值不能为空且不能重复。ps:一张表只能有一个主键。
- foreign key:外键约束,用于定义主表和从表字啊进的关系,外键约束要定义在从表上,而主表必须具有主键约束或unique约束。要求外键列数据必须存在于主表主键列或unique列或为null。
- check :用于强制行数据必须满足的条件。比如sal列定义了check约束,并要求sal列在1000~2000之间,如果插入数据时不满足会报错。
2、商店销售系统表设计案例
现有一个商店的数据库,记录客户机器购物情况,由三个表组成:
- 商品表goods(商品号goodsId,商品名 goodsName,单价 unitprice,商品类别category,供应商provider);
- 客户表customer(客户号customerId,姓名name,住在address,电邮email,性别sex,身份证cardId);
- 购买表purchase(客户号customerId,商品号goodsId,购买数量nums);
请用sql语句完成下列需求:
- 建表,在定义中要求声明: (1)每个表的主外键; (2) 客户的姓名不能为空值; (3) 单价必须大于0,购买数量必须在1到30之间; (4) 电邮不能够重复; (5).客户的性别必须是男或者女,默认是男。
--商品表
create table goods(goodsId char(8) primary key ,--商品号,主键
goodsName varchar2(30) ,--商品名
unitprice number(8,2) check(unitprice > 0),--单价(0,999999.99]
categry varchar2(10) ,--商品类别
provider varchar2(30) --供应商
);
--客户表
create table customer(customerId char(8) primary key ,--客户号,主键
name varchar2(20) not null,--姓名(非空)
adress varchar(50),--住址
email varchar(20) unique,--邮箱(唯一)
sex char(2) default '男' check(sex in('男','女')) ,--性别(默认男)
cardId char(18)--身份证
);
--购买表
create table purchase(
customerId char(8) references customer(customerId),--客户号,外键
goodsId char(8) references goods(goodsId),--商品号,外键
nums number(2) check(nums between 1 and 30)--购买数量,[1,30]
); - 有时候我们在建表时会忘记一些约束,那么我们可以在建表后使用alter table 命令来为表增加约束。ps:在增加not null约束时需要使用modify,而其他四个增加约束要使用add。下面我们继续完善应有的约束:
1)购买表的主键设置为customerId和goodsId;--增加联合主键约束的语法:
alter table tablename add constraint unionkeyname primary key (column1,column2);
--购买表的主键设置为customerId和goodsId
alter table purchase add constraint unionkeyname primary key (customerId,goodsId);2)增加商品名not null约束;
alter table goods modify goodsName not null;
3)增加身份证唯一约束;
--constraint是约束的意思,cardUnique是自定义约束的名字
alter table customer add constraint cardUnique unique(cardId);4)增加约束让客户的住址只能是‘海淀’、‘朝阳’、‘东城’、‘西城’、‘通州’、‘昌平’。
alter table customer add constraint addressCheck check(adress in('海淀','朝阳','东城','西城','通州','昌平'));
3、删除约束
当不需要某个约束时,使用drop constraint命令来进行删除。
alter table 表名 drop constraint 约束名;
--比如删除上面的地址约束
alter table customer drop constraint addressCheck;
注意:在删除约束时,可能会发生逻辑上的错误导致无法删除,比如:alter table 表名 drop primary key;如果这个时候该主键作为主表主键而从表的的外键还存在的情况下不允许删除,这是可以带上cascade进行级联删除,表示将从表的外键也一起删除。
4、显示约束信息
- 通过使用数据字典视图user_constraints可以显示当前用户的所有约束信息。
--查询表goods的一些约束信息
select constraint_name,constraint_type,status,validated from user_constraints where table_name='goods'; - 显示约束列:通过使用数据字典视图user_cons_columns可以显示约束所对应的列表信息。
--查询约束名为addressCheck的一些列信息
select column_name,position from user_cons_columns where constraint_name='addressCheck'; - 使用软件工具pl/sql就能简单地查看约束信息。
5、列级定义&表级定义
列级定义是指定义列的同时定义约束。比如要求一的做法:创建表的同时定义约束。
表级定义是指再定义所有列后再定义约束。比如要求二的做法:在创建表后再增加约束。
不同点:列级约束在定义时不用主动给约束命名,Oracle会自动命名;表级定义则需要自定义约束名称,这样也方便管理。
二、索引(index)
索引是对数据库表中一列或多列的值进行排序的一种结构。索引用于加速数据存储的数据对象,合理的使用索引可以大大降低I/O次数,从而提高数据访问性能。通过建立索引可以极大地提高在数据库中获取所需信息的速度,同时还能提高服务器处理相关搜索请求的效率,同时维护索引也需要较多的时间和精力,所以索引的建立应当选择在经常查询的列。
1、常用索引
- 单列索引
单例索引是基于单个列所建立的索引,比如:--语法
create index 索引名 on 表名(列名)
--创建ename列的索引
create index enameIndex on emp(ename); - 复合索引
复合索引是基于两列或多列的索引。在同一张表上可以有多个索引,但是要求列的组合必须不同,比如:--这也是不同组合的索引,这两个索引区别在于前者先查询ename,后者先查询job
create index emp_index1 on emp(ename,job);
create index emp_index2 on emp(job,ename);
2、索引建立原则
- 在大表上建立才有意义;
- 在where字句或是连接条件上经常引用的列上建立索引;
- 在一个表中建立索引的层次不要超过4层。
3、索引缺点分析
索引有一些先天不足:
- 占空间:建立索引,系统要占用大约是表1.2倍的硬盘和内存空间来保存索引。
- 维护麻烦:更新数据时,系统必须要有额外的时间来同时对索引进行更新,以维持数据和索引的一致性。实践表明,不恰当的索引不但于事无补反而降低系统性能。因为大量的索引在进行插入、修改和删除操作时比没有索引要花费更多的系统时间。
4、显示索引信息
- 显示表的所有索引:通过使用数据字典视图dba_indexes 和 user_indexes,可以分别显示数据库的所有索引信息和用户的所有索引信息。
--查询emp表的索引名和索引类型
select index_name,index_type from user_indexes where table_name='emp'; - 显示索引列:通过使用数据字典视图user_ind_columns可以显示索引对应的列信息。
--查询索引名为enameIndex对应列的表名和字段名
select table_name,column_name from user_ind_columns where index_name='enameIndex'; - 使用ql/sql developer工具查看。
三、管理Oracle的权限和角色
在前几天的内容中已经说过,当用户刚刚创建时是没有任何权限的,不能执行任何操作。所以我们需要授予用户相应的权限或者角色,才能执行相应的操作。其中Oracle中的权限可以分为系统权限和对象权限。
1、系统权限
系统权限是指执行特定类型sql命令的权利,它用于控制用户可以执行的一个或是一组数据库操作。比如当用户具有create table权限时,可以在其方案中建表,当用户具有create any table权限时,可以在任何方案中建表。目前oracle提供了两百多种系统权限,常用的有:
- create session: 连接数据库。
- create view :建视图。
- create procedure: 建过程、函数、包。
- create cluster :建簇。
- create table :建表。
- create public synonym :建同义词。
- create trigger :建触发器。
2、显示系统权限
目前Oracle提供了两百多种系统权限(随版本发行一般都会新增权限),我们可以通过使用数据字典视图system_privilege_map,来显示所有系统权限。
select * from system_privilege_map order by name;
3、授予系统权限
一般情况,授予系统权限是有dba完成的,如果用其它用户来授予系统权限,则要求用户必需具有grant any privilege的系统权限。在授予系统权限时,可以带有with admin option选项,这样,被授予权限的用户或是角色还可以将该系统权限授予其它的用户或是角色。举个例子:
- 创建两个用户ken,tom(初始阶段他们没有任何权限,如果登陆就会出错误的信息)
create user ken identified by ken;
create user tom identified by tom; - 给用户ken和tom授权(grant to)
--带有with admin option表示ken能赋予该权限给其他用户
grant create session to ken with admin option;
grant create table to ken with admin option;
--tom不带
grant create session to tom;
grant create table to tom;
4、回收系统权限
一般情况下,回收系统权限也是dba来完成的,如果其它的用户来回收系统权限,要求该用户必需具有相应系统权限及转授系统权限的选项(with admin option)。回收系统权限使用revoke from来完成,当回收了系统权限后,用户就不能执行相应的操作了,另外请注意:系统权限不会级联回收权限,但对象权限会级联收回。
--回收ken建表的系统权限(如果ken给其他用户授权了建表权限,那么不会被级联收回)
revoke create session from ken
5、对象权限
对象权限指访问其它方案对象的权利,用户可以直接访问自己方案的对象,但是如果要访问别的方案的对象,则必需具有对象的权限,比如smith用户要访问scott.emp表。则必需在scott.emp表上具有对象的权限。常用的权限有:
- alter 修改
- delete 删除
- select 查询
- insert 添加
- update 修改
- index 索引
- references 引用
6、显示对象权限
通过使用数据字典视图dba_tab_privs可以显示用户或角色具有的对象权限。
7、授予对象权限
在oracle9i前,授予对象权限是由对象的所有者来完成的,如果用其它的用户来操作,则需要用户具有相应的(with grant option)权限,从oracle9i开始,sys,system可以将任何对象上的对象权限授予其它用户,授予对象权限是用grant to命令来完成的。
--语法(with grant option不能赋予给角色)
grant 对象权限 on 数据库对象 to 用户名 [with grant option] [,角色名]
比如:
--使用dba将查询scott.emp表的权限授予给monkey用户
grant select on scott.emp to monkey; --使用dba将所有数据操作scott.emp表的权限授予给monkey用户
grant all on scott.emp to monkey; --如果black用户修改scott.emp表的结构,则必需授予alter对象权限
grant alter on scott.emp to black; --如果用户想要执行其它方案的包/过程/函数,则需有execute权限。
grant execute on dbms_transaction to ken; --如果想在别的方案的表上建立索引,则必需具有index对象权限
grant index on dbms_transaction to ken;
8、回收对象权限
在oracle9i中,收回对象的权限可以由对象的所有者来完成,也可以用dba用户(sys,system)来完成。注意:系统权限不会级联回收权限,但对象权限会级联收回。
revoke 对象权限 on 数据库对象 from 用户名[,角色名];
9、角色
角色就是相关权限的命令集合,使用角色的主要目的就是为了简化权限的管理。角色分为预定义角色和自定义角色。预定义角色是指oracle所提供的角色,每种角色都用于执行一些特定的管理任务,下面我们介绍常用的预定义角色CONNECT 、RESOURCE、DBA。
- connect角色具有一般应用开发人员需要的大部分权限。
- resource角色具有应用开发人员所需要的其它权限,比如建立存储过程、触发器等。这里需要注意的是resource角色隐含了unlimited tablespace系统权限。
- dba角色具有所有的系统权限,及with admin option选项,默认的dba用户为sys和system他们可以将任何系统权限授予其它用户,但是要注意的是dba角色不具备sysdba和sysoper的特权(启动和关闭数据库。
--语法(角色名一般为大写)
grant 角色1,角色2... to 用户名;
10、自定义角色
顾名思义就是自己定义的角色,根据自己的需要来定义,一般是dba或具有create role的系统权限的用户来定义。在建立角色时可以指定验证方式(不验证或数据库验证)。
- 不验证的方式建立角色
如果角色是公用的,那么一般采用不验证的方式建立。create role 角色名 not identified;
- 验证数据库的方式建立角色
采用这样的方式时,角色名、口令存放在数据库中。当激活该角色时,必需提供口令。在建立这种角色时,需要为其提供口令。create role 角色名 identified by 口令;
- 角色授权
当建立角色时,角色没有任何权限,为了使得角色完成特定任务,必需为其授予相应的系统权限和对象权限。
给角色授予权限和给用户授权没有太多区别,但是要注意,系统权限的unlimited tablespace和对象权限的with grant option选项是不能授予角色的。grant 对象权限 on 数据库对象 to 自定义角色名;
- 案例
--1、创建自定义角色
conn system/manager9527;--连接数据库
create role crud_scott not identified;--创建自定义角色 --2、给自定义角色crud_scott授权
grant create session to crud_scott;
grant select on scott.emp to crud_scott;
grant insert on scott.emp to crud_scott;
grant update on scott.emp to crud_scott; 3、通过将授权过的角色crud_scott给用户a进行授权
grant crud_scott to a;
11、显示角色信息
通过使用数据字典视图:
- dba_roles(数据库的所有角色信息)
select * from dba_roles;
- role_sys_privs(角色系统权限信息)
select privilege,admin_option from role_sys_privs where role='角色名';
- role_tab_privs(角色对象权限信息)
select * from dba_tab_privs where grantee='角色名';
- user_role_privs(用户具有的角色信息)
select granted_role,default_role from user_role_privs;
12、删除自定义角色
drop role 角色名;
13、精细访问控制(简单了解)
是指用户可以使用函数、策略实现更加细微的案例访问控制。如果使用精细访问控制,则当在客户端发出sql语句(select,insert,update,delete)时,oracle会自动在sql语句后追加谓语(where子句),并执行新的sql语句。通过这样的控制,可以使得不同的数据库用户在访问相同的表时,返回不同的数据信息。使用函数或策略是为了更好的保护数据安全性,为不同权限的用户提供不同的安全级别,可有效的保障信息安全。
iOracle实战笔记(第五天)的更多相关文章
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记十五之铭文升级版
铭文一级:[木有笔记] 铭文二级: 第12章 Spark Streaming项目实战 行为日志分析: 1.访问量的统计 2.网站黏性 3.推荐 Python实时产生数据 访问URL->IP信息- ...
- GAN实战笔记——第五章训练与普遍挑战:为成功而GAN
训练与普遍挑战:为成功而GAN 一.评估 回顾一下第1章中伪造达・芬奇画作的类比.假设一个伪造者(生成器)正在试图模仿达・芬奇,想使这幅伪造的画被展览接收.伪造者要与艺术评论家(判别器)竞争,后者试图 ...
- Spring Boot实战笔记(五)-- Spring高级话题(Spring Aware)
一.Spring Aware Spring 依赖注入的最大亮点就是你所有的 Bean 对 Spring容器的存在是没有意识的.即你可以将你的容器替换成其他的容器,如Google Guice,这时 Be ...
- Java多线程编程实战指南(核心篇)读书笔记(五)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- 《Web安全攻防 渗透测试实战指南 》 学习笔记 (五)
Web安全攻防 渗透测试实战指南 学习笔记 (五) 第四章 Web安全原理解析 (一) (一)SQL注入的原理 1.web应用程序对用户输入数据的合法性没有判断. 2.参数用户可控:前端传给 ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(五)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(五)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo5 中间件实现 ...
- mysql颠覆实战笔记(五)--商品系统设计(二):定时更新商品总点击量
继续回到沈老师的MYSQL颠覆实战,首先回顾下上一节课的内容,请大家会看下上节课写的存储过程. 打开prod_clicklog表, 我们只要把日期(不含时分秒)的部分存在数据库中, 如果同一日期有相同 ...
- mysql颠覆实战笔记(四)--商品系统设计(一):商品主表设计
版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸 ...
- mysql颠覆实战笔记(七)--白话理解事务
今天我们学习web开发级mysql颠覆实战课程第9课没MYSQL事务(一):白话理解事务.前面有两节课第7讲:商品系统设计(四):商品属性设计之自定义属性,第8讲:商品系统设计(五):一维属性的商品价 ...
随机推荐
- js基础查漏补缺(更新)
js基础查漏补缺: 1. NaN != NaN: 复制数组可以用slice: 数组的sort.reverse等方法都会改变自身: Map是一组键值对的结构,Set是key的集合: Array.Map. ...
- python 多进程开发与多线程开发
转自: http://tchuairen.blog.51cto.com/3848118/1720965 博文作者参考的博文: 博文1 博文2 我们先来了解什么是进程? 程序并不能单独运行,只有将程 ...
- mac pycharm快捷键整理
转自:http://www.jianshu.com/p/be0bdc02f7da (感谢整理,另外,简书似乎很不错,排版很nice.) Pycharm 快捷键 shift cmd + 展开所有 shi ...
- com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector APPARENT DEADLOCK
最近在IDEA中启动Tomcat经常会碰到这个错误,起初.一直没在意,现在碰到的次数多了,就去查看下这个问题,现描述如下: =2018-01-08 14:27:30,216 WARN [com.mch ...
- 部署Tomcat服务时,解决Cannot invoke Tomcat Manager 异常
最近,在使用Jenkins对工程一键部署的时候,出现调用Tomcat Manager 异常,对其解决方案特记于次. 异常信息 可能存在的异常:(1)Cannot invoke Tomcat manag ...
- wifipineapple插件:codeInject的使用
如果在中间人攻击的时候, 能在用户的网页中插入任意代码, 可以说已经完成一半了 wifipineapple有个codeInject插件, 可以让连上这个网络所有设备浏览网页的时候, 在网页中插入任意h ...
- (GO_GTD_2)基于OpenCV和QT,建立Android图像处理程序
一.综述 如何采集图片?在windows环境下,我们可以使用dshow,在linux下,也有ffmpeg等基础类库,再不济,opencv自带的videocapture也是提供了基础的支撑.那么 ...
- Django-- 多数据库联用
django项目中使用多个数据库的方法, 多个数据库的联用 以及多数据库时数据导入导出的方法. 直接给出一种简单的方法吧,想了解更多的到官方教程,点击此处 给每个app都可以单独的设置一个数据库 se ...
- 分布式架构ActiveMQ的安装与使用(单节点)
具体内容请参考样例代码和视频教程: http://www.roncoo.com/course/view/85d6008fe77c4199b0cdd2885eaeee53 IP:192.168.4. ...
- CTF---Web入门第五题 貌似有点难
貌似有点难分值:20 来源: 西普学院 难度:难 参与人数:7249人 Get Flag:2519人 答题人数:2690人 解题通过率:94% 不多说,去看题目吧. 解题链接: http://ctf5 ...