11月28日——培训第8天

又是一路顺风,早早的就到了,大家的意思是以后晚点起,没必要每天
都这么早,当时总是担心堵车会很严重,但是没想到一点都不严重,还能
这么早到,可是问题是,如果要是晚起的话等车的问题会不会很严重呢?
要知道307有时候可是会20分钟不来车啊……

本来商量好是今天回去搬宿舍的,因为昨天认为隔壁308的人已经搬走了
,今天一看才知道,原来那最后一个人是打算12月6日才走人,看来一时半
会儿我们也甭着急了……

------------------------------------------------------------------
上午课程开始:

首先是兰献斌讲解昨天的alter table中的set unused来令一条记录不显示
的问题,unused确实不能反向操作,这在参考手册的839页有详细的说明,
而且不难理解,可以到时好好看看。

然后是刘栋的有关事务锁的讲解
1.DML锁
2 DDK锁
3 内部锁(oracle内部使用的锁)

dml锁分为共享锁、独占锁和共享更新锁,
lock table emp in exclusive mode;

如果执行了上面语句后,
再在另一个窗口中执行lock table emp in share mode nowait
的话,由于不能加共享锁故不会等待,直接返回资源正忙的信息
如果不加nowait的话则会等待另一个命令行窗口释放独占锁。

共享更新锁:
select * from emp where empno = 999 for update;
这样满足条件的在emp表中的记录就被锁定了,这就锁定了empno是999的行,
这时候其他行是可以修改的,但是满足上述语句的那些行是不可以更新的。
也就是行级的锁定。

刘栋的资料发给了我们,其实网上这些东西有关锁的太多了,大多数都是原理
性的东东,参考手册中也向我们提供了锁的使用例子。

在17章节的lock table里面有详细的介绍
------------------------
呵呵,田老师的目的已经很清楚了,虽然把一些问题布置给我们名义上好像
是锻炼我们的讲解知识点能力以及解决问题的能力,其实实质上是为了自己的
写教材方便啊,众所周知,以自己的能力写一本书要想写好是很困难的,正所谓
众人拾柴火焰高,把oracle的细节问题分发给学员,让他们每一个人专攻一个
小细节,然后把这些小细节写的很明白,然后老师再集齐这些细节,这样写起
教材来多方便啊……呵呵,这可真是巧妙的利用了资源啊,某培训机构这里果然
不一般,在别的地方有没有类似的现象我不清楚,但是至少张孝祥以前用学员
写书引发矛盾的事情可能也是类似的情况吧,虽然没有指名让我作,而是兰
献斌和刘栋,但是总觉得有种被利用的感觉,看来作为第二期学员的我们,仍然
还是试验品呢。
-------------------------
下面是视图的讲解,视图就是一张虚表,复杂视图不可以进行dml操作,但是
简单视图可以进行dml操作。

create view(列名……) as subquery
   [with check option 约束]
   [with read only 约束]
subquery可以包含复杂的select语法。

with check option 的作用:检查你插入的新记录是否符合子查询的条件,
其实也就是保证你插入的记录可以用子查询查出来,当然只有符合子查询
的条件才可以被查出来……

以hr登陆,
create view emp_v
  as select * from employees where department_id=50;

这样视图就建立起来了
可以用desc emp_v;查看视图。

insert into emp_v values(909,'a','a','2',sysdate,'IT_PROG',5000,
                         0.09,100,80);
注意上面的department_id是80而不是创建子查询中的条件中的50,这样一来
虽然插入成功了,但是由于department_id不是50而是80,

如果执行 select * from emp_v where employee_id=909;的话,是查不出任何
结果的。

如果执行 select employee_id from employees where employee_id=909
的话,就可以查出结果了,所以呢,很明显,所谓的向视图里面插入记录
其实并不是真的插入视图里面去了,而是插入视图背后的真正的表employees
中,所以呢,在视图中由于插入的记录的department_id不是50,所以呢,
自然在视图中显示不出来了。


drop view emp_v;删除视图。

create view emp_v(employee_id,first_name,department_id)
as select employee_id,first_name,department_id from employees
   where department_id = 50 with check option;

视图创建后,
执行insert into emp_v values(908,'a',80);

提示‘无法将NULL插入("hr","employees","last_name")’,
因为插入的实质是插到employees表中而不是视图中,employees表中有些字段
是必须为非空的,比如job_id就不能为空,但是insert语句中没有插入
这个字段,所以肯定是不行的。

所以视图必须包含所有不能为空的字段:
create view emp_v(id,name,email,hire_date,job,department_id)
as select employee_id,last_name,email,hire_date,job_id,department_id from employees where department_id=50 with check option

insert into emp_v values(908,'a','b',sysdate,'IT_PROG',80);
由于80违反了视图中的department_id=50的条件,所以由于with check option
的限制,这条记录就插不进去了。

所以在视图中with check option 是应该加的

至于后面的constraint是用来给with check option加名字的。

如果要更改视图的话使用replace view ,删除的话使用drop view
-----------------------------------------------

create view v1 as select * from users;
如果没有users表的话那么肯定视图创建不出来,但是如果这么写:

create force view v1 as select * from users;
oralce会警告你编译错误。

但是如果其后建立users表:
create table users(id int);

这时会发现前面建立的视图有效了,其实force的作用就是如果没有表的话
先强行建立视图。
-------------------------------------------------
如果视图中有组函数、伪列,你不能删除这个视图中的行。

例:

create view dept_desc as
 select department_id,job_id,avg(salary) as avgsal
from employees group by
 department_id,job_id;

创建好视图后,

执行select * from dept_desc;

这时候如果执行delete from dept_desc where department_id=110;
因为有了组函数和分组,所以不能删除,因为一旦删除就会反映到底层真实
表,因为这么一删除的话,无法准确对到employee表中的某一行,因为视图
给分组了,一删除的话就是一组都删除了,根本无法对应到底层数据表
employees 中的一行,同理,distinct和伪列也是不行的,

除非你更新的这条记录确实能够对应到底层真实数据表的唯一一条记录才可以
进行视图的更新,否则绝对是没戏的。

而且注意视图中必须包含真实表中的所有非空列,如果不是的话,无法插入
视图,因为插入视图的过程是往真实表中的插入,而往真实表中的插入必然
涉及到非空列。

所以说复杂的视图由于牵掣到很多的表,所以对其中某一条记录的更新无法准确
定位到具体的那些表中的唯一的记录,所以对复杂视图是不允许进行DML操作的。

注意如果在视图的最后加入with read only的话那么该视图肯定就无法进行
对视图的更新操作了
如:

create view dept_desc as
 select department_id,job_id,avg(salary) as avgsal
from employees group by
 department_id,job_id
 with read only ;

内联视图

其实就是在视图语法中的from后面加上一个子查询就ok了。
----------------------------------------------------------
上午第一节课结束,现在是课间休息时间。

----------------------------------------------------------
休息结束,下面介绍序列sequence:

如果要查employees表中id的最大值
select max(employee_id) from employees;

但是如果要保证主键插入的唯一性的话,如果使用max(employee_id) + 1
的方式是不能避免不重复的,因为可能会遇到并发操作的问题,两个人同时
插入都加了1,结果插入的employee_id重复了

另外一种方式是让主键设为自增列:在oracle中是无法用sql语句实现子增的,
只能通过触发器来实现!

还有一种方式就是序列了:
例:创建一个序列来自动生成序列号
   create sequence 序列名
   increment by n
   start with n
   maxvalue n | nomaxvalue
   minvalue n | nominvalue
   cycle | nocycle
   cache n | nocache;  默认缓存20个。

举例说明:

   create sequence seq_a
   start with 1               默认从1开始
   maxvalue 11
   increment by 10 ;
这个序列从1到11,每次递增值为10

创建序列后,从中往出取值,取值要用到两个伪列,一个叫做nextval
另外一个叫做currval

select seq_a.currval from dual; 
执行失败,任何一个序列的第一次执行必须是nextval不能是currval。

select seq_a.nextval from dual;
第一次执行上述语句是1,第二次执行就是11了。

如果要设置循环的话,cache值必须小于cycle值,注意cache的值必须大于1

alter sequence seq_a
maxvalue 21
cycle
cache 2

更改了序列后
执行select seq_a.nextval from dual;后
显示的是21,在执行相同的语句后,就是1了
,再执行的话是11,再执行就是21,因为设置了循环
所以会从1到21循环的来,每一次都加10。

如果要查看序列的话

输入desc seq就可以

然后,select sequence_name from seq ,可以找到序列名。

这时要往employees表中插入主键的话,不要往主键里面插入记录中没有
出现的值,虽然可以插进去,但这是很危险的,以后会和序列冲突的!!
insert into employees(employee_id,last_name,email,hire_date,
         job_id) values(employees_seq.nextval,'aaa','ccc',
                       sysdate,2,'IT_PROG');
采用主键序列的nextval方式肯定可以保证主键的值不重复而且符合序列,
这时可用
select employees_seq.currval from dual;
可以查出当前的主键序列值,假如是207的话。

注意:插入即便失败了,序列值也会跟着增加的。

假设下面一个人进行了插入主键值为208的操作,但是没有用nextval,再下面
一个人规矩的按照nextval方法插入的话就会出现违反主键唯一性约束的情况。

其实就是直接指明主键插入的话不会更改序列值,除非使用
employees_seq.nextval,
注意插入时如果使用了employees_seq.nextval,不管插入成功与否,
序列都会增加,而且序列值不会受事务回滚的影响!!

事务对sequence是无法恢复的,所以就会出现跳值的现象,就如同子增的跳值
是一样的,实质都一样,子增的实质也是序列,也是不管插入与否,都会子增。

实际数据库中也是无法避免跳数现象的,主键插入就是用nextval方法去作。

注意序列的nextval是完全可以避免并发冲突的,因为里面有并发机制在里面,
不会出现两个人同时nextval,但是取出了相同值的情况。

事务回滚、系统崩溃、两个或多个表共用一个sequence时,会发生序列跳
数的情况。

----------------------------------------------------------------
索引:

索引作用:提升查询效率,oracle中有两类索引:

1 B树索引(平衡排序树):平衡树就是每一个左子树和右子树的
深度之差的绝对值<1
         
排序树:左子树的值<=根节点,右子树的值>根节点
 
又平衡又排序的树查询效率高。 所谓平衡树就是几乎所有的节点在同一层次上。

而且注意:B树的一个节点可以包含几个值,但是同时也要满足平衡树和
          排序树的要求

2 位图索引

所谓建立索引就是给某一个列建立索引,令其按照B树的方式来排列。
B树是十分复杂的,不只平衡树加排序树那么简单……

可问题是我给哪个列加索引呢?如果有的列从来不会出现在where查询条件中,
那么我给它设索引还有什么意义呢?没有什么意义的,因为基本上不会用这个
列去查询,建立索引会消耗硬盘资源,而且每插入一个新的记录,索引都必须
重新调整,因为索引对应的列发生了改变

所以如果数据库非常庞大的话,只对经常出现在where条件里面的等值比较
或大于比较或小于比较的列设立字段非常重要,B树主要用于等值比较的查询,
如果要查某个字段不等于某个值的话,那么B树基本帮不上什么忙。

所以对于经常出现的非等值比较的字段就别加字段了。

而且对于列里面字段重复率很高的列也没必要建立索引,比如性别列,里面要么
是男、要么是女,没有其他的字段,这就没意义了。

而且对于会频繁进行插入、删除DML操作的列也不要建立索引了,不然每一次
都重新建立索引,太麻烦了。

还有一种情况就是我一选取就选出一大堆而不是具体的某一两条记录时,也
没必要建立索引了,这种情况体现不出B树的优势。

所以实质上呢,建立索引的目的就是为了方便B树在查询中的应用,如果建立
一个索引但是查询起来却体现不出B树优势的话那还不如不建呢。                
-------------------------------------------------------------------
今天真是挺特别的,一般来说,上午和下午都只有一次课间休息的,今天上午
竟然有两个课间休息,课间问了一下老师有关位图索引的事情,结果老师也不
太清楚,让我和邢啸屹去查一下,然后给他讲明白,汗……又可以为oracle
的书稿提供材料了吧……

位图索引适合查找一块数据,至于在内存中是怎么个结构,怎么个存储方法
,以及具体内部的原理,我和邢啸屹得回去查清楚。

B树和B+树在数据库中是很重要的基础理论。

得记住这件事情啊,别忘了啊…………这周三回去好好查查。
--------------------------------------------------------------------
休息结束:

索引语法:
create index emp_index_email on employees(email);
这就针对email字段建立了索引。

select index_name from user_indexes where table_name='EMPLOYEES';
这就可以查出employees表中的所有索引了,当然包括刚才新在employees表
中的某个字段上建立的索引。

能否给两列同时建立索引呢??

create index emp_idex_email on employees(first_name,last_name);

也可以给表达式建立索引,注意对表达式upper(department_name)来说,
如果对department_name建立了索引

where upper(department_name)='sales';那么上面说说的
索引对这种条件的查询是没有作用的,只有建立upper(department_name)
的索引上述条件的查询才会提升效率,也就是必须严格按照
查询条件等号左边的全部去建立索引

什么时候建立索引??
一个字段里面包含大量的值或一个字段包含多个空值或多个字段经常出现在where
查询中,或者是表非常的大而且查询返回的通常都小于总记录的4%.

表太小,列不经常出现在where中,表更新太频繁等情况不适合建立索引
-----------------------------------------------------------------
用户和权限:

建立用户:先以sysdba的身份进入
create user test identified by test;

当创建了用户后还得创建权限,不然没有办法连接数据库。

DCL涉及权限的问题

grant create session to test;

授权成功后仅仅能连接到数据库,不能够建表……
还得授予权限才可以……

grant create table to test;

这样就可以用test用户建表了
但是没有在表空间中创建表的权利……
create table test
(
 id int primary key
);
所以上述建表命令仍然不能在test用户中使用,因为该用户没有被分配表空间。
在oem的存储中可以看到表空间,system表空间被占用的相当的多,所以一般
不把新用户的空间分配到system上面,而是分配到users表空间上面。

用sysdba执行下列语句:
alter user test quota 2m on users;
给test用户2M的空间,该空间在表空间users上。

desc dba_data_files;可以看到dba数据文件的表的详细内容。


select tablespace_name from dba_data_files;
可以看到每一个表空间。


create tablespace 语句用来在命令行中创建表空间,具体命令说明可以参照
             参考手册的15章节里面的相关内容。

在终于赋予了三个权限后,再次用test登陆后,就可以建表了……

删除用户使用语句drop user test 即可。


注意:alter user test default tablespace users;
这句话用于给test用户设置默认表空间users。
这样不用赋予2m的空间也是可以使用的。


接下来插入也可以了……

但是这样一个一个赋予权限实在是太麻烦了,于是引出了一个新的概念:
--------------------------------------------------------------

角色:角色是权限的集合,所以赋予一个角色后可以拥有该角色对应的
      所有权限。
经常用的两个角色:connect 和 resource ;

以sysdba身份登陆,
输入grant connect,resource to test;

DCL也是不用显式提交事务的,一句DCL和DDL一样就是一个事务,
它们不需要像DML一样需要显式的commit提交
 

grant select on employees to sue,rich
对sue和rich用户授予在employees表中的查询权限

revoke select on departments from scott; 从scott身上收回对部门表
                                      的查询权限。

-----------------------------------------------------------------

oracle的第一部分就讲完了,下面是jdbc和hibernate了
以后会回来讲oracle的触发器和存储过程,但是oracle的管理方面
就是在以后讲解了,管理方面和开发离得比较远,因此和这次培训
关系也不大,估计可能不会讲了吧……下午是签署协议,不会讲课了。

老师发了一份儿题目一共20道题目,还是英文的。
-----------------------------------------------------------------

不知为什么现在中午回来一段时间之后总是很困,这段时间什么都不想干,
疲劳感很严重,会一直延续到下午上课,有的时候还会影响下午的上课状态,
晚上一般11点半睡觉,早上7点起,是不是太早了呢?按理说7个小时就够了,
但是按照这里的上课来说看样子是远远不够啊,身体状态比想象的还要差,
如果这样下去的话软件开发是否作的动可能都是个问题……我现在就有点担心
以后是不是得被迫转行呢,如果转行作什么呢,不知道……再说吧。

难得的下午没有课,现在已经2点40多了,倦怠之意又上来了,有点无事可作
的样子,现在方老师正在逐个核对每个人的证件并收复印件,我旁边的邢啸屹
证件太猛了,日语级、linux管理、系统管理什么的……这叫一个……证件这
东西到底是什么呢?总觉得别人的证件多很让人羡慕呢,也许是我太不成熟了
吧,想问题可能老是那么传统片面,也许现在的社会好像也不是太重证件?
也许……

呵呵,想这么多干什么呢,也没什么用嘛。

也有一个礼拜了,把这段时间的感受稍微说一下好了。我们第二期的课程还是
和第一期一样,在北大东门那里的理教楼2层的IBM机房,就是在一期的机房,
现在一期的学员已经搬到了我们对面的那个机房,那里空间相对我们这里狭小
许多,但是机器的数目和我们这里一样,所以显的格外的拥挤和燥热,虽然
是冬天,但是这机器的热量也是不容小觑的啊。一期现在的课程基本上结束了,
张孝祥老师一直在盯着一期班的进度,时刻都不敢放松,现在还无暇顾及我们
的事情。这让我有些担心,他以后还会顾及我们么……毕竟他有太多的事情需要
忙碌了。一个月之后一期的学员就毕业了,他们的就业、以及他们的成绩,
会是我们的一个很重要的参考,到时一定能够了解到许多许多吧,到时我再
把这些信息整理进日记……

第一天来的时候是开学典礼,我记得很清楚,当时本来是10点在北大东门集合,
但是我由于想看一下早上是否堵车结果7点10分就动身去了北大,结果赶上了一辆
很挤的307,差点被挤扁,虽然还是比较早的到了学校,大概8点30分把,但是那
疲劳感真是让我记忆犹新啊……早来并非没有好处,因为一开始的机位并没有
安排下来,我由于来的早顺其自然的坐在了最前面的第一排靠右的位置,而且
挨着过道,当时只是随便那么一坐,没有多想,没想到后来真的就是按照开学
典礼时大家随意坐的位置而固定安排机位了。

坐在前面好处确实不少,老师说的能听的很清楚,黑板上的板书也清楚,老师
即便声音比较小也没关系,而且坐在前面问什么问题也很容易,不像后面需要
用很大的音量,毕竟嘛,坐的越远和老师的距离不论是从物理上还是心理上都
会相对的远一些,也就不那么愿意主动发问了,大家都是中国人,谁不清楚
谁啊,呵呵,大家或多或少都有那么一些共性的,毕竟都是应试教育奴化下
的产物,怎么也会带那么一点劣根性,这是不可避免的。

开学典礼大家的自我介绍已经渐渐的淡忘了,其中有两个人给我留下印象比较
深,其中一个是杨仕明,30多岁的文科老师,另外一个是马雷,北航的研究生,
两人的语言表达能力都很强,说起话来给人感觉很不一般,虽然风格不同,但是
都很impressive。一期学员中主要是王涛给我们说了好多,感觉他的语言表达
能力不是太强,而且明显的感性强于理性的样子,有一腔的对张老师的感激之
情但是有点不知道如何表达,人很是憨厚,而且看的出学的很扎实。

开学典礼的事情我有些记不清楚了,好像当天的日记也记得比较清楚吧,记得
那是我第一次随着别人的讲话在自己建立的txt文档上一个劲的敲键盘,本来以为
自己会很不适应这种方式,没想到在开学典礼的当天这种记录方法对我来说好像
并不是想象中的那么困难,以后的每天大概都是一边听着老师的讲解,一边这么
敲打着txt过来的,可能其中会有不少的笔误,但是应该还是能够看懂使用的,
毕竟是自己的东西嘛……

后面的具体课程在日记中都有详细的阐述,主要说说硬件配置方面,刚来的时候
netmeeting很不好用,经常出现那种大家好多人都拨不上的尴尬局面,但是老师
一直迟迟不愿意重装,系统已经被一期的那些学员搞的千疮百孔了,他们往上面
装好多稀奇古怪的东西又不整理,而且里面病毒一大堆,严重影响了系统的性能
,根本无法正常的使用,重装系统这件事情在老师无法解决网络问题的时候终于
被定了下来,统一重装,这下子所有的问题都一扫而光,netmeeting也顺畅了。
自己的病毒库也在金毅的帮助下升级成了最新的卡巴斯基版本,应该没什么问题
了吧,我可是从来不瞎装软件的。

再来得说说网络的问题,我们机房是用的机房里面一台机器的代理ip上的网,由
那台机器再代理北大的校园网,网很不稳定,时快时慢,而且还总是掉线,查点
资料什么的相当的不方便,这种状况将一直维持到我们培训结束,除非宿舍安
上宽带那就另当别论。

再说说老师的上课,上课嘛好像是有些单调了,这一个礼拜一直都是oracle的命
令行语句,DCL、DDL、DML、QL等,还有一些oracle的杂七杂八的东西,让人
很是郁闷,再加上是第一个礼拜,不太适应这种方式吧,闹得也不是感觉太好,
有些人有点打退堂鼓了,本来和我们住一起的刘羽就是,他觉得这些东西自己学
也可以,好像没什么必要花这么多钱听他在这里照本宣科,于是就离开了,我们
寝室的另一人童晓军也是类似的想法,他本身在外面作php开发有一年左右,需要
真正学到自己需要的东西,也就是对基于项目的要求比较高,现在对这里的培训
也有了一些意见,只是还不知道他的准确打算……

现在下结论有些为时尚早了,因为某培训机构这里的培训是由多位老师共同完成的
,好像在我们这一期来讲,谁都不太可能一直唱独角戏,一期班是一直张老师带
过来的,但是我们这一期恐怕不太可能有太多的像一期班同学那样和张孝祥接触
的机会了,至于项目这一块好像主要是读取源代码占了一定的比例,这是不是
很好还有待于我们亲身去体验。

纵观这一个礼拜,感觉老师讲的内容很多,理解起来容易,记忆起来很难,真正
明白则是不可能,因为里面讲的很多东西如果不在外面作过一段时间的oracle
数据库开发则根本不可能明白,这是很正常的。由此我联想到张老师说的一句话
:“如果老师讲解的内容都完全理解了,那么月薪1万5绝对没问题”,这是基于
什么逻辑我不清楚,但是我实在是很不以为然的,这个观点肯定是站不住脚的,
月薪1万5意味着什么我们还是知道的,而且有这样能力的人好像也没必要来培训
吧。

方老师刚才说了一下协议和学生守则的关系,迟到和早退对协议是有影响的,
请假也是,达到一定次数协议就作废了,而且最重要的一点是:绝对不可以
自己用软件录制老师上课讲解的内容!一旦发现……双方都不好看的,而且
强调了一下安全的重要性,方老师的话说的很明白了,只要一出这个北大机房的
门,他们就不负责了,这也是很正常的,都这么大的人了,还让人处处负责怎么
行呢……而且如果有事情要离开的话必须及时和老师打招呼,不可以私自早退,
这一点要记住。

方老师很快就要离开这里了,他有别的事情,估计以后不会再负责我们这里的
培训管理了,这里现在改由itcast王老师来接手,据说她的技术是很强的。

总之,钱货两清,我已经是船上的人,这条路必须坚定不移的走下去,今天的废话
好像说的太多了,但是总之详细的记载每天的情况,且一直记载4个月是我必须要
作的,不能让这次的培训就这么毫无痕迹的从我的记忆里面消失,让这些文字划下
记忆的痕迹吧,毕竟自己忘的东西已经太多了。


 

你可能感兴趣的:(四个月的编程培训经历)