视图是一种虚表视图建立在已有表的基础上,
视图赖以建立的这些表称为基表向视图提供数据内容的语句为 SELECT
语句,可以将视图理解为存储起来的 SELECT
语句视图向用户提供基表数据的另一种表现形式视图没有存储真正的数据,真正的数据还是存储在基表中程序员虽然操作的是视图,但最终视图还会转成操作基表一个基表可以有0个或多个视图

什么是视图【View】
(1)视图是一种虚表
(2)视图建立在已有表的基础上, 视图赖以建立的这些表称为基表
(3)向视图提供数据内容的语句为 SELECT 语句,可以将视图理解为存储起来的
SELECT 语句
(4)视图向用户提供基表数据的另一种表现形式
(5)视图没有存储真正的数据,真正的数据还是存储在基表中
(6)程序员虽然操作的是视图,但最终视图还会转成操作基表
(7)一个基表可以有0个或多个视图

目录

1.序

2.题库

3.

如果你不想让用户看到所有数据,只想让用户看到某些的数据时,此时可以使用视图当你需要减化SQL查询语句的编写时,可以使用视图,但不提高查询效率

什么情况下会用到视图
(1)如果你不想让用户看到所有数据(字段,记录),只想让用户看到某些的数据时,此时可以使用视图
(2)当你需要减化SQL查询语句的编写时,可以使用视图,但不提高查询效率

Oracle 数据库

数据库本质是用计算机存储数据的一种系统。它是位于 用户 和系统
之间的一种管理软件。

银行,电信,金属,证券军事等不便让用户知道所有数据的项目中

视图应用领域
(1)银行,电信,金属,证券军事等不便让用户知道所有数据的项目中

1.序

1.1 登录SQLPLUS

cmd
sqlplus [用户名]/[密码][@数据库] [参数]
sqlplus sys/orcl as sysdba  -- 登录 sys 用户,必须指定 sysdba 或 sysoper 身份
sqlplus system/orcl         -- 数据库管理员

1.2 创建一个自己的用户(比如 vip/vip)

create user vip identified by vip;     -- 注意,新创建的用户,什么权限都没有,需要授权后才能使用
grant create session to vip;           -- 授予登录的权限
grant connect to vip;                  -- 角色是很多权限的打包,connect 是一种角色,它包含了连接查看数据的一些基本权限
grant dba to vip;                      -- dba 是绝大多数权限的集合,它基本能做所有事情,所以很少单独授予用户。但在测试环境中,这样,很爽。

-- 上面的创建用户、授予权限两步操作,可以简化为下面一步:
grant dba to vip identified by vip;    -- 注意,使用分号结尾

1.3 切换到用户

sqlplus vip/vip  -- 在 cmd 下
conn vip/vip     -- 在 sqlplus 中

1.4 使用

create table aaa (id int);

1.5 激活内置的测试账号,这里面有几张示例库,可以用它们练习下查询

alter user scott account unlock;
conn scott/tiger

1.6 修改密码

alter user scott identified by [newpassword];

限制数据访问简化复杂查询提供数据的相互独立

视图的作用
(1)限制数据访问
(2)简化复杂查询
(3)提供数据的相互独立
(4)同样的数据,可以有不同的显示方式

2.题库

— 基于emp表所有列,创建视图emp_view_1,create view 视图名 as
select对一张或多张基表的查询

菲律宾太阳 1

2.1 题库一

  • 在芝加哥工作的人中,谁的工资最高
  • 查询每个部门下有多少员工
  • 查询除去 salesman 所有平均工资超过 1500 的部门
  • 查询在 new york 工作的所有员工的姓名,部门名称和工资信息
  • 查询姓名为 King 的员工的编号,名称跟部门
  • 查询各种工作的最低工资
  • 查询工龄大于10年的所有员工信息
  • 查询每个部门员工数量,平均工资和平均工作年限
  • 统计各部门每个工种的人数,平均工资。
  • 查询从事同一种工作但不属于同一部门的员工信息。
  • 查询所有员工工资都大于1000的部门的信息及员工信息
  • 查询入职日期早于其直接上级的所有员工信息。
  • 列出雇员中(除去mgr为空的人)工资第二高的人。
  • 列出1981年来公司所有员工的总收入(包括sal和comm)
create view emp_view_1asselect * from emp;

菲律宾太阳 2

2.2 题库二

  • 查询工资为 2500 到 4000 的人的数量(用不同方式查询)

    select count(*) from emp where sal >= 2500 and sal <= 4000;
    -- vs.
    select count(*) from emp where sal between 2500 and 4000;
    
  • 查询部门编号为 10 和 30 的所有人(用不同方式查询)

  • 查询部门编号为 10 和 30 中名字中不含有 ‘C’ 的所有人
  • 查询部门编号为 10 和 30 中名字首字母之外不含有 ‘C’ 的所有人
  • 查询部门编号为 10 和 30 中所有的经理以及名字首字母之外不含有 ‘C’
    的所有人
  • 查询纽约和芝加哥地区所有的经理以及名字首字母之外不含有 ‘C’ 的所有人
  • 查询纽约和芝加哥地区所有的经理以及顶头上司名字的首字母之外不含有 ‘C’
    的所有人
  • 查询每个人的工资等级

    -- 初始化数据
    create table salgrade as select * from scott.salgrade;
    
    -- 分别查看数据
    select * from emp;
    select * from salgrade;
    
    -- 杂交
    select * from emp, salgrade;
    
    -- 过滤掉不合适的
    select ename, grade from emp e, salgrade s where e.sal between s.losal and s.hisal;
    
  • 查询每个部门的平均工资的等级

    -- 分析题目
    -- 1. 需要先查询出每个部门的平均工资
    -- 2. 根据 salgrade 表中的数据,获取每个部门平均工资的等级
    
    -- 这是所有的人
    select * from emp;
    -- 按照部门分组
    select deptno, avg(sal) from emp group by deptno;
    -- 结果:
    -- | DEPTNO |   AVG(SAL)    |
    -- |     30  | 1566.66667  |
    -- |     20 |  2258.33333  |
    -- |     10 |  2916.66667  |
    
    -- 跟 salgrade 表,杂交,总共 15 条结果
    select * from
      (select deptno, avg(sal) sal from emp group by deptno) t,
      salgrade s;
    
    -- 过滤掉工资范围不合适的数据
    select * from
      (select deptno, avg(sal) sal from emp group by deptno) t,
      salgrade s
    where
      t.sal between s.losal and s.hisal;
    -- 结果就是这样,就对了
    -- | DEPTNO |  SAL        |  GRADE |  LOSAL |  HISAL  |
    -- |     10 |  2916.66667 |      4 |   2001 |   3000  |
    -- |     20 |  2258.33333 |      4 |   2001 |   3000  |
    -- |     30 |  1566.66667 |      3 |   1401 |   2000  |
    
    -- 需要将部门名称显示出来,再杂交->过滤一次就可以了
    select * from
      (select deptno, avg(sal) sal from emp group by deptno) t,
      salgrade s,
      dept d
    where
      t.deptno = d.deptno and
      t.sal between s.losal and s.hisal;


    -- 最后的最后,设置显示字段
    select dname, grade from
      (select deptno, avg(sal) sal from emp group by deptno) t,
      salgrade s,
      dept d
    where
      t.deptno = d.deptno and
      t.sal between s.losal and s.hisal;
    -- 最终结果,完美
    --| DNAME      |  GRADE  |
    --| ACCOUNTING |      4  |
    --| RESEARCH   |      4  |
    --| SALES      |      3  |

— 默认情况下,普通用户无权创建视图,得让sysdba为你分配creare view的权限

基于emp表所有列,创建视图emp_view_1,create view 视图名 as
select对一张或多张基表的查询
create view emp_view_1
as
select * from emp;

2.3 题库三

  • 查询每个组最高工资的那些人
  • 有下面一个表,写一条 sql 语句计算男女之差

    gender number
    46
    10
  • 给 emp 中的人加工资,请写出相关语句:

    条件 加多少
    1000元以下 50%
    2000元以下 30%
    3000元以下 20%
    其他 5%
  • 给 emp 中的人加工资,如上。但 1981/5/1 之后来的所有人,只加 2%,
    请写出语句。

  • 计算你们从入学到现在过了多少个周末
  • 计算你们从现在到毕业还有多少天,还有多少个周末
  • 计算你们在学校的时间内,每天花费多少钱

sysdba身份,授权scott用户create
view权限grant create view to scott;

默认情况下,普通用户无权创建视图,得让sysdba为你分配creare view的权限

查询各种工作中的最低工资

   看到最低、最大、平均之类的题目,首先想到的是分组函数的使用。

   也就是 group by, having。

select job, min(sal) from emp group by job;

sysdba身份,撤销scott用户create
view权限revoke create view from scott;

以sysdba身份,授权scott用户create view权限
grant create view to scott;

在芝加哥工作的人中,谁的工资最高

[题目] 从 scott 用户的 emp/dept 表中,找到 “来自芝加哥最有钱的那个人”

首先,我们需要理清思路。

这里总共有两个条件:

  1. 这个人来自芝加哥
  2. 这个人是最有钱的,而且是芝加哥最有钱的

我们可以看出,第二个条件是依赖第一个条件的。

所以,分两步查询:

  1. 找出所有来自芝加哥的人
  2. 从这些人中,找到最有钱的那个。这一步,可以通过 max 函数或者 order by
    方式实现。


基于emp表指定列,创建视图emp_view_2,该视图包含编号/姓名/工资/年薪/年收入

以sysdba身份,撤销scott用户create view权限
revoke create view from scott;

下面是语句示例:

---- 第一步:找到来自芝加哥的所有人。下面两种写法等价:

select e.* from emp e
  join dept d on (e.deptno=d.deptno)
  where d.loc='CHICAGO';

select e.* from emp e, dept d
  where d.deptno = e.deptno
        and d.loc='CHICAGO';


---- 第二步,基于上面结果,筛选出最有钱的那个

-- 可以通过 max 函数
select e.* from emp e, dept d
  where e.deptno = d.deptno
        and d.loc='CHICAGO'
        and sal = 
            (select max(sal) from emp e, dept d
              where e.deptno = d.deptno
                    and d.loc='CHICAGO');

-- 可以通过 order by 方式
select ename from
  (select e.*, d.* from emp e, dept d
    where e.deptno = d.deptno
          and d.loc='CHICAGO'
    order by sal desc)
where rownum = 1;

注意,实现的方式,不止上面的那些。但总体 思路 是一样的。

所以,思路永远是最重要的。

create view emp_view_2asselect empno "编号",ename "姓名",sal "工资",sal*12 "年薪",sal*12+NVL "年收入"from emp;

基于emp表指定列,创建视图emp_view_2,该视图包含编号/姓名/工资/年薪/年收入(查询中使用列别名)
create view emp_view_2
as
select empno “编号”,ename “姓名”,sal “工资”,sal*12
“年薪”,sal*12+NVL(comm,0) “年收入”
from emp;

查询所有员工工资都大于1000的部门的信息及员工信息

最核心的问题: 查询出符合条件的部门编号。


基于emp表指定列,创建视图emp_view_3(a,b,c,d,e),包含编号/姓名/工资/年薪/年收入

基于emp表指定列,创建视图emp_view_3(a,b,c,d,e),包含编号/姓名/工资/年薪/年收入(视图中使用列名)
create view emp_view_3(a,b,c,d,e)
as
select empno “编号”,ename “姓名”,sal “工资”,sal*12
“年薪”,sal*12+NVL(comm,0) “年收入”
from emp;

第一种思路

 1.查询出所有的部门编号

select * from emp;

 2.查询出所有工资少于 1000 的人,
我们要把它所在的部门,从上面的结果中排除掉。

select deptno from emp where sal < 1000;

 3.将上面查询出的不符合条件的部门排除掉

select distinct deptno from emp
 where deptno not in 
  (select deptno from emp where sal < 1000);

 4.修改上面语句,增加最终的条件,查询所有的其他信息

select d.dname, e.* from emp e join dept d on(e.deptno = d.deptno)
  where e.deptno not in
    (select deptno from emp where sal < 1000)
create view emp_view_3(a,b,c,d,e)asselect empno "编号",ename "姓名",sal "工资",sal*12 "年薪",sal*12+NVL "年收入"from emp;

查询emp_view_3创建视图的结构
desc emp_view_3;

第二种思路

使用分组函数(group by / having)

分组函数主要用来统计分析。

一个完整的查询语句如下,其中 group by 和 having 是用来分组和筛选分组。

select [字段] from [表名]
  where [条件]
  group by [分组字段]
  having [对分组结果进行筛选]
  order by [字段]

示例:

select deptno,     -- 分组字段
       count(*),   -- 人数
       sum(sal),   -- 工资总和
       avg(sal),   -- 平均工资
       max(sal),   -- 最高工资
       min(sal)    -- 最低工资
  from emp group by deptno         -- 按照部门分组,进行统计
           having avg(sal) > 2000; -- 只显示平均工资大于 2000 的分组

— 查询emp_view_3创建视图的结构

修改emp_view_3(id,name,salary,annual,income)视图,create or replace
view 视图名 as 子查询
create or replace view emp_view_3(id,name,salary,annual,income)
as
select empno “编号”,ename “姓名”,sal “工资”,sal*12
“年薪”,sal*12+NVL(comm,0) “年收入”
from emp;

那我们的题目的解决思路就是:

1.按照部门分组

select deptno from emp group by deptno;

2.筛选,排除最低工资小于 1000 的部门。 即:得到符合条件的部门的编号。

select deptno from emp group by deptno having min(sal) > 1000;

3.完善最终语句,得到最终结果。

select * from emp e, dept d
  where e.deptno = d.deptno
        and e.deptno in (select deptno from emp group by deptno having min(sal) > 1000);

desc emp_view_3;

查询emp表,求出各部门的最低工资,最高工资,平均工资
select min(sal),max(sal),round(avg(sal),0),deptno
from emp
group by deptno;

查询当月总共有多少个周五

— 修改emp_view_3(id,name,salary,annual,income)视图

创建视图emp_view_4,视图中包含各部门的最低工资,最高工资,平均工资
create or replace view emp_view_4
as
select deptno “部门号”,min(sal) “最低工资”,max(sal)
“最高工资”,round(avg(sal),0) “平均工资”
from emp
group by deptno;

首先,第一步,得到本月所有日期的结果集,两种方式:

  1. 使用已有表的 rownum 构建
  2. 使用 oracle 的 connect by level 语句(结构化查询)

得到有 n 条记录的虚表:

select rownum from dba_objects where rownum < 32;
select level from dual connect by level < 32;

将虚表转化为我们需要的日期表:

select trunc(sysdate, 'MON') + rownum - 1 from dba_objects where rownum < 32;
select trunc(sysdate, 'MON') + level - 1 from dual connect by level < 32;
create or replace view 视图名 as 子查询create or replace view emp_view_3(id,name,salary,annual,income)asselect empno "编号",ename "姓名",sal "工资",sal*12 "年薪",sal*12+NVL "年收入"from emp;

创建视图emp_view_5,视图中包含员工编号,姓名,工资,部门名,工资等级
create or replace view emp_view_5
as
select e.empno “编号”,e.ename “姓名”,e.sal “工资”,d.dname
“部门名”,s.grade “工资等级”
from emp e,dept d,salgrade s
where (e.deptno=d.deptno) and (e.sal between s.losal and s.hisal);

其次,在上面结果集的基础上进行筛选:

-- 1.
select *
  from (select trunc(sysdate, 'MON') + rownum - 1 d
          from dba_objects
         where rownum < 32)
 where to_char(d, 'day') = '星期五'
   and d <= last_day(sysdate);

-- 2.
select *
  from (select trunc(sysdate, 'MON') + level - 1 d
          from dual
        connect by level < 32)
 where to_char(d, 'day') = '星期五'
   and d <= last_day(sysdate);

当然,你也可以将 last_day 这一段放到里面:

select *
  from (select trunc(sysdate, 'MON') + level - 1 d
          from dual
        connect by level <= extract(day from last_day(sysdate)))
 where to_char(d, 'd') = 6;

— 查询emp表,求出各部门的最低工资,最高工资,平均工资

删除视图emp_view_1中的7788号员工的记录,使用delete操作,会影响基表吗
delete from emp_view_1 where empno=7788;写法正确,会影响基表

3.管理系统

select min,max,round,0),deptnofrom empgroup by deptno;

修改emp_view_1为只读视图【with read
only】,再执行上述delete操作,还行吗?
create or replace view emp_view_1
as
select * from emp
with read only;
不能进行delete操作了

3.1 学生管理系统

菲律宾太阳,根据我们学校的实际情况,请帮助设计一个学生管理系统。

比如, 学生,老师,班级,课程。按照你自己的设计,酌情增加。

基本步骤:

  1. 先用 e-r 图,将实体的关系表述出来。

    这样的图能帮助我们理清思路,并能帮助团队间的有效交流。

    一定在图画好之后再去着手数据库表的创建。要秉承先设计后实现的思路。

    你可以用一些知名的工具(如 visio)去画,也可以手动在纸上画。

  2. 根据设计好的图,写出相应的建表语句。

  3. 也可以进一步根据实体关系和表,创建相应的 Java 实体类。进一步可以
    DAO,进一步可以 Service【可选】
  4. 最后,将图跟语句一起上交。这个过程着重思考下项目从设计到编码是怎么一个过程。

    需求分析 -> *概要设计* -> 详细实现。 
    

— 创建视图emp_view_4,视图中包含各部门的最低工资,最高工资,平均工资

删除视图中的【某条】记录会影响基表吗?
会影响基表

3.2 博客管理系统

首先,设计一个博客表(blog), 至少有下面字段

  • id
  • author
  • title
  • content(要求是 clob 类型)
  • image(要求是 blob 类型)
  • create_time

用 Java 完成基本的 =CRUD=,并掌握使用 PL/SQL 操作 blob/clob 的技巧。

create or replace view emp_view_4asselect deptno "部门号",min "最低工资",max "最高工资",round,0) "平均工资"from empgroup by deptno;

将【整个】视图删除,会影响表吗?
不会影响基表

4.体系结构

Oracle 采取的是 Client/Server 架构。

菲律宾太阳 3

 客户端(client)操作数据库的请求发送后,服务端的监听器(TNSListener)接收到请求,并将其转发给相应的数据库实例(Instance),再由实例(Instance)去操纵数据库(Database)。
返回操作结果,是一个相反的过程。下面是个简陋的图示:

菲律宾太阳 4


创建视图emp_view_5,视图中包含员工编号,姓名,工资,部门名,工资等级

删除视图,会进入回收站吗?
不会进入回收站

Client

create or replace view emp_view_5asselect e.empno "编号",e.ename "姓名",e.sal "工资",d.dname "部门名",s.grade "工资等级"from emp e,dept d,salgrade swhere (e.deptno=d.deptno) and (e.sal between s.losal and s.hisal);

删除基表会影响视图吗?
会影响视图

Sqlplus

这是一个轻量级的功能强大的客户端, 是 dba 必须掌握的工具。

用 sqlplus 连接数据库的语法为:

# Usage:
#   sqlplus 用户名/密码@主机名:端口号/实例名
# 参数个数不是固定的

sqlplus                         # 会要求你输入用户名密码,默认连接本地 ORACLE_SID 变量指定的数据库
sqlplus vip                     # 会要求你输入密码
sqlplus vip/vip                 # 连接本地 ORACLE_SID 变量指定的数据库

sqlplus sys/hello as sysdba     # sys 用户必须用 sysdba 或 sysoper 的身份登录

sqlplus vip@192.168.0.111/orcl  # 连接 192.168.0.111 机器上的 orcl 数据库,用户名为 vip
sqlplus vip@192db               # 连接 别名 为 192db 的数据库

我们可以配置 sqlplus 的一些行为,两个命令:

  1. show. 用来显示配置参数
  2. set. 用来设置配置参数

比如:

show all               -- 显示所有配置参数
show lines             -- 显示 lines 的配置信息
show errors            -- 显示错误
set lines[ize] 333     -- 将行宽设置为 333
set pages[ize] 444     -- 将每页的记录数设置为 444
set echo off/on        -- 导入外部文件,是否要显示原始 sql 语句
set feedback on/off    -- 是否显示“查询到xx数据”等信息
set timing on/off      -- 是否显示语句的执行时间
set autocommit on/off  -- 是否启用自动提交
set autotrace on/off   -- 是否输出执行计划
set serveroutput on/off-- 是否显示来自服务端的信息
column aaa format a22  -- 将列 'aaa' 的宽度限制为 22 个字幕'a'的大小。column 命令很强大,语句也复杂,此处不提。

在 sqlplus 中有缓冲区的概念:

缓冲区是用来记录上一次执行的命令语句的空间。

我们可以通过一些列简单命令,对上一次输入的语句进行一些控制:

  • 增 append/insert
  • 删 delete
  • 改 change
  • 查 list
  • 执行修改后的语句 run 或者 /

例子:

list         -- 显示完整的缓存区
list 3       -- 显示并定位到第三行
list 3 5     -- 显示第三行到第五行的内容
list last    -- 定位到最后一行

list 3
del               -- 删除第三行

list 3
append  order by sal  -- 定位到第三行,然后追加 order by sal
insert order by sal   -- 开启新的一行,插入 order by sal

还有其他一些命令:

get D:aaa.sql        -- 将文件加载到缓冲区,但不执行
start D:aaa.sql      -- 将文件加载到缓冲区,并且执行
@D:aaa.sql           -- 是上面一条语句的简写形式
save D:bbb.sql       -- 将缓冲区的内容保存到文件中
edit                  -- 调用外部编辑器,编辑缓冲区
clear screen          -- 清空缓冲区

show user             -- 显示当前用户
show parameters       -- 显示 oracle 的配置参数
show parameters nls   -- 显示 oracle 中所有跟语言配置相关的一些参数
describe emp          -- 显示 emp 表的结构信息


删除视图emp_view_1中的7788号员工的记录,使用delete操作,会影响基表吗

闪回基表后,视图有影响吗?
视图又可以正常工作了

JDBC

用 Java 连接数据库,需要用到 jdbc 驱动,它们可以在下面目录中找到:

主目录product12.1.0dbhome_1jdbclib*.jar

比如 ojdbc7_g.jar7 表示适用于 JDK 版本
1.7, g 表示自带更多调试信息。

delete from emp_view_1 where empno=7788;写法正确,会影响基表,基表也会删除。

————————————————————————————-同义词

TNSListener

TNSListener,是用来监听来自客户端的请求,并将其转发给相对应的服务端实例的一种后台服务。

它是沟通客户端与服务端的一个桥梁。

比如,下面用 sqlplus 客户端将会连接 localhost 上的 orcl 数据库:

sqlplus vip/vip@localhost/orcl

请求会发送到 localhost 主机的 1521 号端口, 作为监听的 TNSListener
收到这个请求后,再把请求转发给对应的 orcl 数据库实例。

所以必须开启监听服务,并且配置正确,才能连接操作数据库。

注:如果用 sqlplus vip/vip 的方式连接数据库,即没有指定连接的机器,那么默认连接的是本机数据库
这种连接是不需要监听服务的,因为为了增加连接速度,这样的本地连接 oracle 会使用一个专用的进程直接连接实例

我们可以使用 Oracle 提供的 lsnrctl 命令操纵监听服务的开启或关闭:

lsnrctl status    # 查看状态
lsnrctl stop      # 停止监听服务
lsnrctl start     # 开启监听服务
lsnrctl reload    # 重启监听服务
lsnrctl services  # 查看监听的连接情况

我们可以使用 Oracle 的 Net Manager 工具来配置自己的监听器。

实质上,用 Net Manager 配置跟直接修改下面文件的作用是一样的:

主目录product12.1.0dbhome_1networkadminlistener.ora

我们在 Net Manager 中对 listener 的配置对应的是这一段代码:

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    )
    ...
  )

只要修改其中的 host/port 等,重启监听服务即可。

— 修改emp_view_1为只读视图【with read
only】,再执行上述delete操作,还行吗?

什么是同义词【Synonym】
(1)对一些比较长名字的对象(表,视图,索引,序列,。。。)做减化,用别名替代

Server

Oracle 服务端分为两部分:

  1. Instance 实例
  2. Database 数据库
create or replace view emp_view_1asselect * from empwith read only;

同义词的作用
(1)缩短对象名字的长度
(2)方便访问其它用户的对象

实例(Instance)

实例,
又称为数据库引擎,由 SGA(System Global Area, 系统全局区) 和 一系列后台进程 组成。
它需要启动才会生成,用来加载并管理一个数据库。

不能进行delete操作了

创建与salgrade表对应的同义词,create synonym 同义词 for
表名/视图/其它对象
create synonym e for salgrade;
create synonym ev5 for emp_view_5;

服务启动的大致过程:

  1. [读取] 读取系统的 ORACLE_SID
    环境变量,确定要启动的实例名字,比如为 xxoo
  2. [加载]
    从 $ORABASE/admin/xxoo 和 $ORA_HOME/database/SPFILEXXOO.ora 等位置加载相关配置文件。配置文件的名字是根据
    sid 来定义的。
  3. [启动]
    从配置文件中,读取相关信息,比如数据库名字、数据库控制文件位置、SGA
    等信息,并根据这些,初始化数据库加载需要的 内存空间(SGA) 和 相关进程 。
  4. [装载]
    根据配置文件中读取的数据库信息,找到各种数据文件位置,并装载数据库。
  5. [启动] 进行数据校验等,如果没有问题,启动数据库。

可以通过查看启动过程协助理解:

-- 首先,登录 sys 用户,只有管理员才有完全操纵数据库的权力
-- shutdown 用来关闭。如果不带参数,默认为 normal
---- immediate 表示立即关闭,如果有未处理完操作,回滚并断开
---- normal 表示等待所有连接断开才关闭数据库
---- 其他参数,略
shutdown immediate;

-- 启动数据库,分解为三个动作:
---- 启动实例
---- 利用启动的实例去挂载数据库
---- 校验并打开数据库
-- 只有完全打开,才能进行完全的数据操作
-- 也可以指定参数,启动到某个阶段。这是在维护数据库中使用的命令。
startup             -- 如果不加参数,
startup nomount     -- 启动到 nomount 阶段
startup mount       -- 启动到 mount 阶段

-- 当然,也可以这样分步启动:
startup nomount
alter database mount
alter database open

发表评论

电子邮件地址不会被公开。 必填项已用*标注