2009年2月24日星期二

关于oracle rownum的知识汇总

1.

http://rake.itpub.net/post/4038/27463

得到前n条记录

直接选择前n条记录。

select * from table_name where rownum<=n; 直接选择前10条记录。

(或是rownum <>或是rownum != n+1)

选出前n条记录后再排序

select * from table_name where rownum<=n order by field_name;

选出前n条最大的记录。(先排序,再选择)

select * from (select * from table_name order by field_name desc)

where rownum <=n ;

得到最后n条记录

注意:因为rownum是不能用大于号来和数字比较的。 rownum > n 是无效的。

方法一:集合之差

很慢

select * from table_name

minus

select * from table_name

where rownum <= (select count(*)-n from table_name);

order by filed_name

(先选再排序)

方法二:子查询

较快

select *

from ( select rownum id,t.* from table_name t)

where id >(select count(*)-10 from table_name);

得到表的nm条记录

select * from (select rownum id,t.* from table_name

where ……

and rownum <= m order by field_name)

where id > n;

(先选再排序再选)

要先排序再选则须用select嵌套,内层排序外层选。

取得某列中第n大的行

使用dense_rank()函数

select column_name from

(select table_name.*,dense_rank() over (order by column_name desc) rank from table_name)

where rank = &N

关于rownum

rownum是随着结果集生成的,一旦生成,就不会变化了;同时,生成的结果是依次递加的,没有1就永远不会有2


2.

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。
举例说明:
例如表:student(学生)表,表结构为:
ID    char(6)      --学号
name    VARCHAR2(10)   --姓名
create table student (ID char(6), name VARCHAR2(100));
insert into sale values('200001',‘张一’);
insert into sale values('200002',‘王二’);
insert into sale values('200003',‘李三’);
insert into sale values('200004',‘赵四’);
commit;

(1) rownum 对于等于某值的查询条件
如 果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因 为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)
SQL> select rownum,id,name from student where rownum=1;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200001 张一
SQL> select rownum,id,name from student where rownum =2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------

(2)rownum对于大于某值的查询条件
如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录
SQL> select rownum,id,name from student where rownum >2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
那如何才能找到第二行以后的记录呀。可以使用以下的子查询方法来解决。注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL>select * from(select rownum no ,id,name from student) where no>2;
NO ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
4 200004 赵四
SQL> select * from(select rownum,id,name from student)where rownum>2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------

(3)rownum对于小于某值的查询条件
如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。显然rownum对于rownum1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> select rownum,id,name from student where rownum <3;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200001 张一
2 200002 王二
综 上几种情况,可能有时候需要查询rownum在某区间的数据,那怎么办呀从上可以看出rownum对小于某值的查询条件是人为true的,rownum对 于大于某值的查询条件直接认为是false的,但是可以间接的让它转为认为是true的。那就必须使用子查询。例如要查询rownum在第二行到第三行之 间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记 录行。但是这样的操作会在大数据集中影响速度。
SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;
NO ID NAME
---------- ------ ---------------------------------------------------
2 200002 王二
3 200003 李三

(4)rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。
SQL> select rownum ,id,name from student order by name;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
2 200002 王二
1 200001 张一
4 200004 赵四
可以看出,rownum并不是按照name列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询
SQL> select rownum ,id,name from (select * from student order by name);
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200003 李三
2 200002 王二
3 200001 张一
4 200004 赵四
这样就成了按name排序,并且用rownum标出正确序号(有小到大)
笔者在工作中有一上百万条记录的表,在jsp页面中需对该表进行分页显示, 便考虑用rownum来作,下面是具体方法(每页
显示20条):
“select * from tabname where rownum<20 order by name" 但却发现oracle却不能按自己的意愿来执行,而是先随便
取20条记录,然后再 order by,后经咨询oracle,说rownum确实就这样,想用的话,只能用子查询 来实现先排序,后
rownum,方法如下:
"select * from (select * from tabname order by name) where rownum<20",但这样一来,效率会较低很多。
后经笔者试验,只需在order by 的字段上加主键或索引即可让oracle先按 该字段排序,然后再rownum;方法不变:
“select * from tabname where rownum<20>

取得某列中第N大的行

select column_name from
(select table_name.*,dense_rank() over (order by column desc) rank from table_name)
where rank = &N;
 假如要返回前5条记录:

  select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)
假如要返回第5-9条记录:

select * from tablename
where …
and rownum<10
minus
select * from tablename
where …
and rownum<5
order by name
选出结果后用name排序显示结果。(先选再排序)

注意:只能用以上符号(<、<=、!=)。

select * from tablename where rownum != 10;返回的是前9条记录。
不能用:>,>=,=,Between...and。由于rownum是一个总是从1开始的伪列,Oracle 认为这种条件 不成立,查不到记录.

另外,这个方法更快:

select * from (
select rownum r,a from yourtable
where rownum <= 20
order by name )
where r > 10
这样取出第11-20条记录!(先选再排序再选)

要先排序再选则须用select嵌套:内层排序外层选。
rownum是随着结果集生成的,一旦生成,就不会变化了;同时,生成的结果是依次递加的,没有1就永远不会有2!
rownum 是在 查询集合产生的过程中产生的伪列,并且如果where条件中存在 rownum 条件的话,则:

1: 假如 判定条件是常量,则:
只能 rownum = 1, <= 大于1 的自然数, = 大于1 的数是没有结果的, 大于一个数也是没有结果的
即 当出现一个 rownum 不满足条件的时候则 查询结束   this is stop key!

2: 当判定值不是常量的时候
若条件是 = var , 则只有当 var 为1 的时候才满足条件,这个时候不存在 stop key ,必须进行 full scan ,对每个满足其他where条件的数据进行判定
选出一行后才能去选rownum=2的行……


3.

对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<、<=、!=),并非说用>,& gt;=,=,between..and 时会提示SQL语法错误,而是经常是查不出一条记录来,还会出现似乎是莫名其妙的结果来,其实您只要理解好了这个 rownum 伪列的意义就不应该感到惊奇,同样是伪列,rownum 与 rowid 可有些不一样,下面以例子说明

假设某个表 t1(c1) 有 20 条记录

如果用 select rownum,c1 from t1 where rownum < 10, 只要是用小于号,查出来的结果很容易地与一般理解在概念上能达成一致,应该不会有任何疑问的。

可如果用 select rownum,c1 from t1 where rownum > 10 (如果写下这样的查询语句,这时候在您的头脑中应该是想得到表中后面10条记录),你就会发现,显示出来的结果要让您失望了,也许您还会怀疑是不谁删了一 些记录,然后查看记录数,仍然是 20 条啊?那问题是出在哪呢?

先好好理解 rownum 的意义吧。因为ROWNUM是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列 (强调:先要有结果集)。简单的说 rownum 是对符合条件结果的序列号。它总是从1开始排起的。所以你选出的结果不可能没有1,而有其他大于1的值。所以您没办法期望得到下面的结果集:

11 aaaaaaaa
12 bbbbbbb
13 ccccccc
.................

rownum >10 没有记录,因为第一条不满足去掉的话,第二条的ROWNUM又成了1,所以永远没有满足条件的记录。或者可以这样理解:

ROWNUM是一个序列,是oracle数据库从数据文件或缓冲区中读取数据的顺序。它取得第一条记录则rownum值为1,第二条为2,依次类推。如果 你用>,>=,=,between...and这些条件,因为从缓冲区或数据文件中得到的第一条记录的rownum为1,则被删除,接着取下 条,可是它的rownum还是1,又被删除,依次类推,便没有了数据。

有了以上从不同方面建立起来的对 rownum 的概念,那我们可以来认识使用 rownum 的几种现像

1. select rownum,c1 from t1 where rownum != 10 为何是返回前9条数据呢?它与 select rownum,c1 from tablename where rownum < 10 返回的结果集是一样的呢?
因为是在查询到结果集后,显示完第 9 条记录后,之后的记录也都是 != 10,或者 >=10,所以只显示前面9条记录。也可以这样理解,rownum 为9后的记录的 rownum为10,因条件为 !=10,所以去掉,其后记录补上,rownum又是10,也去掉,如果下去也就只会显示前面9条记录了

2. 为什么 rownum >1 时查不到一条记录,而 rownum >0 或 rownum >=1 却总显示所以的记录
因为 rownum 是在查询到的结果集后加上去的,它总是从1开始

3. 为什么 between 1 and 10 或者 between 0 and 10 能查到结果,而用 between 2 and 10 却得不到结果
原因同上一样,因为 rownum 总是从 1 开始

从上可以看出,任何时候想把 rownum = 1 这条记录抛弃是不对的,它在结果集中是不可或缺的,少了rownum=1 就像空中楼阁一般不能存在,所以你的 rownum 条件要包含到 1

但如果就是想要用 rownum > 10 这种条件的话话就要用嵌套语句,把 rownum 先生成,然后对他进行查询。
select *
from (selet rownum as rn,t1.* from a where ...)
where rn >10

一般代码中对结果集进行分页就是这么干的。

另外:rowid 与 rownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。rowid 相对于表来说又像表中的一般列,所以以 rowid 为条件就不会有 rownum那些情况发生。
另外还要注意:rownum不能以任何基表的名称作为前缀。

用一句SQL取出第 m 条到第 n 条记录的方法

参考各类资料:

一、MS SQL SERVER 版

从Table 表中取出第 m 条到第 n 条的记录:(Not In 版本)

SELECT TOP n-m+1 *
FROM Table
WHERE (id NOT IN (SELECT TOP m-1 id FROM Table ))


--从TABLE表中取出第m到n条记录 (Exists版本)

SELECT TOP n-m+1 * FROM TABLE AS a WHERE Not Exists
(Select * From (Select Top m-1 * From TABLE order by id) b Where b.id=a.id )
Order by id


--m为上标,n为下标,例如取出第8到12条记录,m=8,n=12,Table为表名

Select Top n-m+1 * From Table
Where Id>(Select Max(Id) From
(Select Top m-1 Id From Table Order By Id Asc) Temp)
Order By Id Asc

Oracle 版本:

Oracle中的实现,取得第M到N条记录:
SELECT * FROM (
SELECT * , ROWNUM AS CON FROM ( SELECT * FROM [TABLE] ORDER BY [ORDER] )
WHERE ROWNUM <= N )
WHERE CON >= M;

ref link:http://www.cnblogs.com/athrun/archive/2007/03/02/661213.html


其他相关:

1.直接取得数据库中的分页记录

前提是表中必须有主键

取得第M条记录之后的N条记录:
SELECT TOP N *
FROM [TABLE]
WHERE (ID NOT IN
(SELECT TOP M id
FROM [TABLE]
ORDER BY [ORDER]))
ORDER BY [ORDER]

2.查询表中连续的某几条记录
不要传任何列的条件参数,查询表中连续的某几条记录
如:表A,id列为主键
id name sex age
-------------------------
1 luoyi male 21
2 yaya female 20
3 lili female 22
4 wuyong male 25
.......................

这个表的记录还有很多,如果我想取第二、第三条记录,在oracle和mssqlserver中SQL代码分别为:

一、Oracle
在oracle中不能用top关键字,而用rownum,有两种方法可以实现
1.(select * from A where rownum <= 4) minus (select * from A where rownum <= 1)
这样就得到了二、三两条记录了。minus 关键字的意思是求两个结果集的差集,在数学中有这个概念,比如说两个集合可以合并、公有、差集.
2. select * from (select * from A where rownum <>  这句代码也可以实。主要运用了not in运算符

二、ms sql server
在server中没有minus,只能用类似于oracle的第二种方法
select * from (select top 3 * from A) as b where b.id not in(select top 1 id from A)
三、绘制出来的结果为:
id name sex age
--------------------------------
2 yaya female 20
3 lili female 22


3.查询数据库中的N条记录,然后,对这N条记录排序

正确答案1:
select top 10 * from TableName where id in(select top 10 id from TableName order by id) order by createtime
这条语句,就可以找出表中的前10条的记录,然后以createtime时间排序
要求是表中需要有一个主键

答案2
没有主键也可以
SELECT *
FROM (SELECT TOP 10 *
FROM titles) mm
ORDER BY pubdate DESC

4.随机取出若干条记录的SQL语句

Sql server:


select top 20 * from 表 order by newid()

Access:

SELECT top 20 * FROM 表 ORDER BY Rnd(id)

Rnd(id) 其中的id是自动编号字段,可以利用其他任何数值来完成

比如用姓名字段(UserName)

SELECT top 20 * FROM 表 ORDER BY Rnd(len(UserName))

MySql:

Select * From 表 Order By rand() Limit 20

2009年2月20日星期五

面试:自个写一个web服务器,你能多久时间写好?

下午去×××面试的时候被问到web服务器,要求自个写个简单的满足需求web服务器,并且问多久时间能写好。但是我就有点蒙了,我对这个不是太了解,对socke编程方面还算了解,但是从来没有关心过自己写个web服务器的问题。按理说凭我对java,c++网路编程的了解,写个简单的web服务器应该没问题, 但是要求我说出多久时间能写出来还真的为难我!我思考了下,回答的是说不准。现在真懊悔不已啊。只要对http比较了解的话,在参考下开源的轻量级的web服务器,我想不到星期因该就可以写好的!
下面看看web服务器的解释:

什么是WEB服务器

  WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务。
  (1)应用层使用HTTP协议。
  (2)HTML文档格式。
  (3)浏览器统一资源定位器(URL)。
  WWW代表万维网的意思
  WWW 是 Internet 的多媒体信息查询工具,是 Internet 上近年才发展起来的服务,也是发展最快和目前用的最广泛的服务。正是因为有了WWW工具,才使得近年来 Internet 迅速发展,且用户数量飞速增长。
  1、WWW简介
  WWW 是 World Wide Web (环球信息网)的缩写,也可以简称为 Web,中文名字为“万维网”。它起源于1989年3月,由欧洲量子物理实验室 CERN(the European Laboratory for Particle Physics)所发展出来的主从结构分布式超媒体系统。通过万维网,人们只要通过使用简单的方法,就可以很迅速方便地取得丰富的信息资料。 由于用户在通过 Web 浏览器访问信息资源的过程中,无需再关心一些技术性的细节,而且界面非常友好,因而 Web 在Internet 上一推出就受到了热烈的欢迎,走红全球,并迅速得到了爆炸性的发展。
  2、WWW的发展和特点
  长期以来,人们只是通过传统的媒体(如电视、报纸、杂志和广播等)获得信息。但随着计算机网络 的发展,人们想要获取信息,已不再满足于传统媒体那种单方面传输和获取的方式,而希望有一种主观的选择性。现在,网络上提供各种类别的数据库系统,如文献 期刊、产业信息、气象信息、论文检索等等。由于计算机网络的发展,信息的获取变得非常及时、迅速和便捷。
  到了1993年,WWW 的技术有了突破性的进展,它解决了远程信息服务中的文字显示、数据连接以及图像传递的问题,使得 WWW 成为 Internet 上最为流行的信息传播方式。 现在,Web 服务器成为 Internet 上最大的计算机群,Web 文档之多、链接的网络之广,令人难以想象。可以说,Web 为 Internet 的普及迈出了开创性的一步,是近年来 Internet 上取得的最激动人心的成就。
  WWW 采用的是客户/服务器结构,其作用是整理和储存各种WWW资源,并响应客户端软件的请求,把客户所需的资源传送到 Windows 95(或Windows98)、Windows NT、UNIX 或 Linux 等平台上。
  使用最多的 web server 服务器软件 有两个:微软的信息服务器(iis),和Apache。
  通俗的讲,Web服务器传送(serves)页面使浏览器可以浏览,然而应用程序服务器提供的 是客户端应用程序可以调用(call)的方法(methods)。确切一点,你可以说:Web服务器专门处理HTTP请求(request),但是应用程 序服务器是通过很多协议来为应用程序提供(serves)商业逻辑(business logic)。
  Web服务器可以解析(handles)HTTP协议。当Web服务器接收到一个HTTP请求 (request),会返回一个HTTP响应(response),例如送回一个HTML页面。为了处理一个请求(request),Web服务器可以响 应(response)一个静态页面或图片,进行页面跳转(redirect),或者把动态响应(dynamic response)的产生委托(delegate)给一些其它的程序例如CGI脚本,JSP(JavaServer Pages)脚本,servlets,ASP(Active Server Pages)脚本,服务器端(server-side)JavaScript,或者一些其它的服务器端(server-side)技术。无论它们(译者 注:脚本)的目的如何,这些服务器端(server-side)的程序通常产生一个HTML的响应(response)来让浏览器可以浏览。
  要知道,Web服务器的代理模型(delegation model)非常简单。当一个请求(request)被送到Web服务器里来时,它只单纯的把请求(request)传递给可以很好的处理请求 (request)的程序(译者注:服务器端脚本)。Web服务器仅仅提供一个可以执行服务器端(server-side)程序和返回(程序所产生的)响 应(response)的环境,而不会超出职能范围。服务器端(server-side)程序通常具有事务处理(transaction processing),数据库连接(database connectivity)和消息(messaging)等功能。
  虽然Web服务器不支持事务处理或数据库连接池,但它可以配置(employ)各种策略 (strategies)来实现容错性(fault tolerance)和可扩展性(scalability),例如负载平衡(load balancing),缓冲(caching)。集群特征(clustering—features)经常被误认为仅仅是应用程序服务器专有的特征。
  应用程序服务器(The Application Server)
  根据我们的定义,作为应用程序服务器,它通过各种协议,可以包括HTTP,把商业逻辑暴露给 (expose)客户端应用程序。Web服务器主要是处理向浏览器发送HTML以供浏览,而应用程序服务器提供访问商业逻辑的途径以供客户端应用程序使 用。应用程序使用此商业逻辑就象你调用对象的一个方法(或过程语言中的一个函数)一样。
  应用程序服务器的客户端(包含有图形用户界面(GUI)的)可能会运行在一台PC、一个Web 服务器或者甚至是其它的应用程序服务器上。在应用程序服务器与其客户端之间来回穿梭(traveling)的信息不仅仅局限于简单的显示标记。相反,这种 信息就是程序逻辑(program logic)。 正是由于这种逻辑取得了(takes)数据和方法调用(calls)的形式而不是静态HTML,所以客户端才可以随心所欲的使用这种被暴露的商业逻辑。
  在大多数情形下,应用程序服务器是通过组件(component)的应用程序接口(API)把 商业逻辑暴露(expose)(给客户端应用程序)的,例如基于J2EE(Java 2 Platform, Enterprise Edition)应用程序服务器的EJB(Enterprise JavaBean)组件模型。此外,应用程序服务器可以管理自己的资源,例如看大门的工作(gate-keeping duties)包括安全(security),事务处理(transaction processing),资源池(resource pooling), 和消息(messaging)。就象Web服务器一样,应用程序服务器配置了多种可扩展(scalability)和容错(fault tolerance)技术。
  例如,设想一个在线商店(网站)提供实时定价(real-time pricing)和有效性(availability)信息。这个站点(site)很可能会提供一个表单(form)让你来选择产品。当你提交查询 (query)后,网站会进行查找(lookup)并把结果内嵌在HTML页面中返回。网站可以有很多种方式来实现这种功能。我要介绍一个不使用应用程序 服务器的情景和一个使用应用程序服务器的情景。观察一下这两中情景的不同会有助于你了解应用程序服务器的功能。
  情景1:不带应用程序服务器的Web服务器
  在此种情景下,一个Web服务器独立提供在线商店的功能。Web服务器获得你的请求 (request),然后发送给服务器端(server-side)可以处理请求(request)的程序。此程序从数据库或文本文件(flat file,译者注:flat file是指没有特殊格式的非二进制的文件,如properties和XML文件等)中查找定价信息。一旦找到,服务器端(server-side)程序 把结果信息表示成(formulate)HTML形式,最后Web服务器把会它发送到你的Web浏览器。
  简而言之,Web服务器只是简单的通过响应(response)HTML页面来处理HTTP请求(request)。
  情景2:带应用程序服务器的Web服务器
  情景2和情景1相同的是Web服务器还是把响应(response)的产生委托 (delegates)给脚本(译者注:服务器端(server-side)程序)。然而,你可以把查找定价的商业逻辑(business logic)放到应用程序服务器上。由于这种变化,此脚本只是简单的调用应用程序服务器的查找服务(lookup service),而不是已经知道如何查找数据然后表示为(formulate)一个响应(response)。 这时当该脚本程序产生HTML响应(response)时就可以使用该服务的返回结果了。
  在此情景中,应用程序服务器提供(serves)了用于查询产品的定价信息的商业逻辑。(服务 器的)这种功能(functionality)没有指出有关显示和客户端如何使用此信息的细节,相反客户端和应用程序服务器只是来回传送数据。当有客户端 调用应用程序服务器的查找服务(lookup service)时,此服务只是简单的查找并返回结果给客户端。
  通过从响应产生(response-generating)HTML的代码中分离出来,在应用 程序之中该定价(查找)逻辑的可重用性更强了。其他的客户端,例如收款机,也可以调用同样的服务(service)来作为一个店员给客户结帐。相反,在情 景1中的定价查找服务是不可重用的因为信息内嵌在HTML页中了。
  总而言之,在情景2的模型中,在Web服务器通过回应HTML页面来处理HTTP请求(request),而应用程序服务器则是通过处理定价和有效性(availability)请求(request)来提供应用程序逻辑的。
  警告(Caveats)
  现在,XML Web Services已经使应用程序服务器和Web服务器的界线混淆了。通过传送一个XML有效载荷(payload)给服务器,Web服务器现在可以处理数据和响应(response)的能力与以前的应用程序服务器同样多了。
  另外,现在大多数应用程序服务器也包含了Web服务器,这就意味着可以把Web服务器当作是应 用程序服务器的一个子集(subset)。虽然应用程序服务器包含了Web服务器的功能,但是开发者很少把应用程序服务器部署(deploy)成这种功能 (capacity)(译者注:这种功能是指既有应用程序服务器的功能又有Web服务器的功能)。相反,如果需要,他们通常会把Web服务器独立配置,和 应用程序服务器一前一后。这种功能的分离有助于提高性能(简单的Web请求(request)就不会影响应用程序服务器了),分开配置(专门的Web服务 器,集群(clustering)等等),而且给最佳产品的选取留有余地。

大型WEB服务器

   在UNIX和LINUX平台下使用最广泛的免费HTTP服务器是W3C、NCSA和APACHE服务器,而Windows平台NT/2000/2003 使用IIS的WEB服务器。在选择使用WEB服务器应考虑的本身特性因素有:性能、安全性、日志和统计、虚拟主机、代理服务器、缓冲服务和集成应用程序 等,下面介绍几种常用的WEB服务器。
  Microsoft IIS
  Microsoft的Web服务器产品为Internet Information Server (IIS), IIS 是允许在公共Intranet或Internet上发布信息的Web服务器。IIS是目前最流行的Web服务器产品之一,很多著名的网站都是建立在IIS 的平台上。IIS提供了一个图形界面的管理工具,称为 Internet服务管理器,可用于监视配置和控制Internet服务。
  IIS是一种Web服务组件,其中包括Web服务器、FTP服务器、NNTP服务器和SMTP 服务器,分别用于网页浏览、文件传输、新闻服务和邮件发送等方面,它使得在网络(包括互联网和局域网)上发布信息成了一件很容易的事。它提供 ISAPI(Intranet Server API)作为扩展Web服务器功能的编程接口;同时,它还提供一个Internet数据库连接器,可以实现对数据库的查询和更新。
  官方网站:http://www.microsoft.com
  下载地址:http://www.eryin.com/Server/Soft/200808/02257.html
  IBM WebSphere
  

  WebSphere Application Server 是 一 种功能完善、开放的Web应用程序服务器,是IBM电子商务计划的核心部分,它是基于 Java 的应用环境,用于建立、部署和管理 Internet 和 Intranet Web 应用程序。 这一整套产品进行了扩展,以适应 Web 应用程序服务器的需要,范围从简单到高级直到企业级。
  WebSphere 针对以 Web 为中心的开发人员,他们都是在基本 HTTP服务器和 CGI 编程技术上成长起来的。IBM 将提供 WebSphere 产品系列,通过提供综合资源、可重复使用的组件、功能强大并易于使用的工具、以及支持 HTTP 和 IIOP 通信的可伸缩运行时环境,来帮助这些用户从简单的 Web 应用程序转移到电子商务世界。
  官方网站:http://www.ibm.com
  下载地址:http://www.ibm.com/developerworks/cn/downloads/ws/wasce/
  BEA WebLogic
  BEA WebLogic Server 是一种多功能、基于标准的web应用服务器,为企业构建自己的应用提供了坚实的基础。各种应用开发、部署所有关键性的任务,无论是集成各种系统和数据库, 还是提交服务、跨 Internet 协作,起始点都是 BEA WebLogic Server。由于 它具有全面的功能、对开放标准的遵从性、多层架构、支持基于组件的开发,基于 Internet 的企业都选择它来开发、部署最佳的应用。
  BEA WebLogic Server 在使应用服务器成为企业应用架构的基础方面继续处于领先地位。BEA WebLogic Server 为构建集成化的企业级应用提供了稳固的基础,它们以 Internet 的容量和速度,在连网的企业之间共享信息、提交服务,实现协作自动化。
  官方网站:http://www.bea.com
  下载地址:http://www.oracle.com/bea/index.html
  Apache
  Apache仍然是世界上用的最多的Web服务器,市场占有率达60%左右。它源于 NCSAhttpd服务器,当NCSA WWW服务器项目停止后,那些使用NCSA WWW服务器的人们开始交换用于此服务器的补丁,这也是apache名称的由来(pache 补丁)。世界上很多著名的网站都是Apache的产物,它的成功之处主要在于它的源代码开放、有一支开放的开发队伍、支持跨平台的应用(可以运行在几乎所 有的Unix、Windows、Linux系统平台上)以及它的可移植性等方面。
  官方网站:http://www.apache.org
  下载地址:http://www.eryin.com/Server/Soft/200808/01245.html
  Tomcat
  Tomcat是一个开放源代码、运行servlet和JSP Web应用软件的基于Java的Web应用软件容器。Tomcat Server是根据servlet和JSP规范进行执行的,因此我们就可以说Tomcat Server也实行了Apache-Jakarta规范且比绝大多数商业应用软件服务器要好。
  Tomcat是Java Servlet 2.2和JavaServer Pages 1.1技术的标准实现,是基于Apache许可证下开发的自由软件。Tomcat是完全重写的Servlet API 2.2和JSP 1.1兼容的Servlet/JSP容器。Tomcat使用了JServ的一些代码,特别是Apache服务适配器。随着Catalina Servlet引擎的出现,Tomcat第四版号的性能得到提升,使得它成为一个值得考虑的Servlet/JSP容器,因此目前许多WEB服务器都是采 用Tomcat。
  官方网站:http://tomcat.apache.org
  下载地址:http://www.eryin.com/Server/Soft/200808/02250.html

小型WEB服务器

  【 micro_httpd - really small HTTP server】
  特点:
  * 支持安全的 .. 上级目录过滤
  * 支持通用的MIME类型
  * 支持简单的目录
  * 支持目录列表
  * 支持使用 index.html 作为首页
  * Trailing-slash redirection
  * 程序总共代码才200多行
  这个httpd适合学习简单的Web Server编写学习,因为它只有一个简单的框架,只能够处理简单的静态页,可以考虑用来放静态页。
  官方地址:http://www.acme.com/software/micro_httpd/
  下载地址:http://www.acme.com/software/micro_httpd/micro_httpd_12dec2005.tar.gz
  【 mini_httpd - small HTTP server 】
  特点:
  * 支持GET、HEAD、POST方法
  * 支持CGI功能
  * 支持基本的验证功能
  * 支持安全 .. 上级目录功能
  * 支持通用的MIME类型
  * 支持目录列表功能
  * 支持使用 index.html, index.htm, index.cgi 作为首页
  * 支持多个根目录的虚拟主机
  * 支持标准日志记录
  * 支持自定义错误页
  * Trailing-slash redirection
  mini_httpd 也是相对比较适合学习使用,大体实现了一个Web Server的功能,支持静态页和CGI,能够用来放置一些个人简单的东西,不适宜投入生产使用。
  官方地址:http://www.acme.com/software/thttpd/
  下载地址:http://www.acme.com/software/mini_httpd/mini_httpd-1.19.tar.gz
  【 thttpd - tiny/turbo/throttling HTTP server 】
  thttpd中是一个简单,小型,轻便,快速和安全的http服务器.
  简单:它能够支持HTTP/1.1协议标准,或者超过了最低水平
  小巧:它具有非常少的运行时间,因为它不fork子进程来接受新请求,并且非常谨慎的分配内存(性能对比表:http://www.acme.com/software/thttpd/benchmarks.html)
  便携:它能够在大部分的类Unix系统上运行,包括FreeBSD, SunOS 4, Solaris 2, BSD/OS, Linux, OSF等等
  快速:它的速度要超过主流的Web服务器(Apache, NCSA, Netscape),在高负载情况下,它要快的多
  安全:它努力的保护主机不受到攻击,不中断服务器
  thttpd 类似于lighttpd,对于并发请求不使用fork()来派生子进程处理,而是采用多路复用(Multiplex)技术来实现。因此效能很好。同时它还 有一个特点就是基于URL的文件流量限制,这对于下载的流量控制而言是非常方便的。象Apache就必须使用插件实现,效率较thttpd低。
  thttpd跟lighttpd类似,适合静态资源类的服务,比如图片、资源文件、静态HTML等等的应用,性能应该比较好,同时也适合简单的CGI应用的场合。
  官方地址:http://www.acme.com/software/thttpd/
  下载地址:http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz
  【 lighttpd - light footprint + httpd = LightTPD 】
  Lighttpd是一个德国人领导的开源软件,其根本的目的是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。具有非常低的内存开销,cpu占用率低,效能好,以及丰富的模块等特点。
  lighttpd 是众多OpenSource轻量级的web server中较为优秀的一个。支持FastCGI, CGI, Auth, 输出压缩(output compress), URL重写, Alias等重要功能,而Apache之所以流行,很大程度也是因为功能丰富,在lighttpd上很多功能都有相应的实现了,这点对于apache的用 户是非常重要的,因为迁移到lighttpd就必须面对这些问题。
  实用起来lighttpd确实非常不错,apache主要的问题是密集并发下,不断的 fork()和切换,以及较高(相对于 lighttpd而言)的内存占用,使系统的资源几尽枯竭。而lighttpd采用了Multiplex技术,代码经过优化,体积非常小,资源占用很低, 而且反应速度相当快。
  利用apache的rewrite技术,将繁重的cgi/fastcgi任务交给lighttpd来完成,充分利用两者的优点,现在那台服务器的负载下降了一个数量级,而且反应速度也提高了一个甚至是2个数量级!
  lighttpd 适合静态资源类的服务,比如图片、资源文件、静态HTML等等的应用,性能应该比较好,同时也适合简单的CGI应用的场合。
  官方地址:http://www.lighttpd.net/
  下载地址:http://www.lighttpd.net/download/lighttpd-1.4.16.tar.gz
  【 SHTTPD - Simple HTTPD 】
  Shttpd是另一个轻量级的web server,具有比thttpd更丰富的功能特性,支持CGI, SSL, cookie, MD5认证, 还能嵌入(embedded)到现有的软件里。最有意思的是不需要配置文件! 由于shttpd可以嵌入其他软件,因此可以非常容易的开发嵌入式系统的web server,官方网站上称shttpd如果使用uclibc/dielibc(libc的简化子集)则开销将非常非常低。
  特点:
  * 小巧、快速、不膨胀、无需安装、简单的40KB的exe文件,随意运行
  * 支持GET, POST, HEAD, PUT, DELETE 等方法
  * 支持CGI, SSL, SSI, MD5验证, resumed download, aliases, inetd模式运行
  * 标准日志格式
  * 非常简单整洁的嵌入式API
  * dietlibc friendly. NOT that friendly to the uClibc (*)
  * 容易定制运行在任意平台:Windows, QNX, RTEMS, UNIX (*BSD, Solaris, Linux)
  由于shttpd可以轻松嵌入其他程序里,因此shttpd是较为理想的web server开发原形,开发人员可以基于shttpd开发出自己的webserver!
  官方网站:http://shttpd.sourceforge.net/
  下载地址:http://jaist.dl.sourceforge.net/sourceforge/shttpd/shttpd-1.38.tar.gz


经过这次给了我一个教训,我发现我自个对细节方面太过于强调,而对大局、提纲没有一个整体的认识。哎,只缘身在此山中啊!

2009年2月17日星期二

好几天没更新了

忙着工作,无暇顾及。 晚上也不想看书看视频学习。 生活是那么苦闷! 真不知道改怎么办了!感觉自个做了个错误的决定,现在已经没法挽回了!
晚上继续spring的学习!坚持,坚持!再坚持!

2009年2月10日星期二

【spring学习流水帐】第二天

今晚主要学习:
1.配置管理spring的bean作用域

i)默认每个创建的bean是单例实例,延迟初始化bean,这是bean节点的属性lazy-init="true" 所有的bean都延迟初始化,设置beans节点的default-lazy-init="true"
ii)可以配置为prototype模式的实例,即每次从容器中获取的bean都是新的对象。scope="prototype"
iii)bean的scope属性:prototype,singleton
iv)注意beans.xml 里面节点属性是大小写区分的!

2.spring管理bean的生命周期
i)默认情况下,即bean是在singleton模式下实例化,bean随容器的实例化而实例化,即他们同时实例化;
ii)在prototype模式下,bean在容器初始化时没有实例化,而是在getBean()调用后实例化的;
iii)bean节点的init-method属性,bean实例化时调用的初始化方法
iv)bean节点的destory-method属性,bean销毁是调用的方法。容器不关闭,bean不销毁。AbstractApplicationContext的close方法可以正常销毁容器。

3.Spring依赖注入的原理
i)属性注入:bean节点的property子节点,其name属性的实例名、ref依赖的bean的id值属性;
ii)内部bean的方式注入,此bean只能被其外部bean使用不能被其他bean使用;
iii)基本属性注入:bean->property->bean->name,value;
iv)bean创建控制权的转移,实现了反转控制。

研读openfire通信部分代码

由于工作原因又捡起了java,还是做通信部分。以前是用mina搭建通信服务器,那个简单啊!简单的设置下,服务器就跑起来了!不过这次要求不同,要做成一个组件,需要方便集成spring中,所以做起来不是那么容易!我有个习惯-喜欢研究人家的优秀代码为我所用。openfire也是用mina做通信部分的,他们最新的openfire-3.6.3用的用的是mina-1.1.8-snapshot。当了源代码看了通信部分之后感慨万分!他们写的代码砸的那么优雅啊? 看着那个舒服!用java真的好! 也许是俺用C#写了1年的页面代码被弄啥了吧? openfire集成mina的工作做得很好,从openfire里面学习借鉴到许多优秀的思想。

spring2.5.6学习进度被工作拖延!准备晚上钻研!

2009年2月9日星期一

【spring学习流水帐】第一天




1.资料准备
(1)springsource上下载必要的包,文档等
(2)jdk6up12,eclipse3.4
(3)学习视频(传智播客的)

2.学习内容
(1)全面阐释Spring及其各项功能
(2)搭建与测试Spring的开发环境
(3)编码剖析Spring管理Bean的原理
简单的说就是读取spring的bean配置文件,然后通过xml解析器获得bean的实例,再创建出来,提供给我们使用。
(4)Spring的三种实例化Bean的方式
第一种:通过构造函数实例化
第二种:通过静态工厂方法实例化
第三种:通过实力工厂方法实例化