ODBC、OLEDB和ADO之间的关系 ,以及性能比较
学习了.net视频之后,对里面涉及到的数据库连接部分中的一些概念表示很无语。网上很多相关资料,但除了网站不一样外,基本上内容都神一样的一致。
现在,我就通过结合看到的一些资料再加上自己的理解试图去解释一下,有不对的,还请大家指教!
看一张图:
看图中右半部分,我们先来了解一下ODBC这个概念。
1.ODBC:
要了解ODBC是什么,先了解一下数据库连接的相关知识。其实,在最开始连接数据库时,由于数据库种类繁多,各种数据库连接有不同的需求,这个时期,数据库连接主要依靠各种API函数来进行连接。而ODBC就是将这些API函数封装起来形成统一的接口如上图所示(ODBC上方有一个唯一的接口)。图中所示的ODBC层代表ODBC中各种数据库的驱动器(driver),当SQL语句进入接口后,驱动器管理程序通过辨别将它们分别对应的进入各自的驱动器(driver),由驱动器来讲SQL语句送入各种不同的数据库。
不知道上面这样写,有没有把这个ODBC给介绍的明白一点儿,学习要生活化,这样才容易理解。我来举个例子。
我们把ODBC假想成一辆汽车,汽车中有一名司机(driver),把下面的各种数据库假设程不同的工厂。如果司机接收到接口中的命令(SQL语句)——将汽车上的货物运到某个工厂中。那么司机(driver)会根据命令中所指明的货物的类型,自己去辨别到底应该进入哪个工厂才能完成任务。
大家看,上面这个例子中接收的命令就好像是数据库中的SQL语句,那么司机就好像是驱动器(driver),而不同的工厂就好像是不同种类的数据库。这样理解,有没有简单一点儿呢?
2.OLEDB与ODBC
好了,再来看一下OLEDB,在上面的例子中我们理解了ODBC,还有我们必须知道,ODBC负责的只是结构化数据库的连接。这样我们就会比较容易理解OLEDB。
OLEDB其实和ODBC类似,都是负责数据库连接的低级接口。而OLEDB不仅支持结构化数据库如SQL server,Oracel Access等,而且还支持非结构化数据源的连接如EXCEL等。
OLEDB(对象连接和嵌入数据库),是一组对象的集合,一种读写数据的方法。在使用OLEDB时,使用步骤为:初始化OLE、连接到数据源、发出命令、处理结果、释放数据源对象并停止初始化OLE。他可以通过ODBC连接到数据库,也可以之间连接到数据库。当不通过ODBC时,这时在这其中并不涉及到驱动器的成分,因此,此时的数据库连接速度会更快。同时,我们可以知道,只要支持ODBC的数据源是一定能够支持OLEDB的。但是反过来则不一定。
3.ADO
通过图中,我们看到ADO是位于应用程序和OLEDB之间的。它属于数据库连接中的高层接口。
是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO中的命令对象来执行。
如何理解上面这个概念呢?其实我们可以联系我们学到的关于ADO控件的相关知识。在原来学习VB的时候,我们如果想要连接到数据库的话,必须加载一个引用空间,里面含有connection,command,recordset等一些相关数据库连接的对象,其实这个引用就是ADO。我们通过这些对象建立对数据库的连接,我们只需编写访问数据库的代码,而并不用关系数据库是如何实现的。
看完了三者的关系,让我们来看看他们操作数据的速度如何,以打开access为例
性能对比:
sql access
oledb dsn oledb dsn
时间 18 82 62 99
查询1,000条记录: 100 150 2900 5400
显然,oledb链接方式相对于dsn有很大的优势.购买虚拟主机的小站,大多是php+mysql或者asp+access的组合,一般没有dsn数据源的配置,而且我们也不需要.同时mssql是一种昂贵的数据库,如果使用效率低下的access,我们应该尽量的减少数据库引擎的压力.我经常看见一些站点给出提示:数据库连接失败,显然,又是access出毛病了.
常用的连接access的办法:
oledb
openstr="provider=microsoft.jet.oledb.4.0;" & "data source = " & server.mappath(db)
odbc
openstr="Driver={Microsoft Access Driver (*.mdb)};DBQ=" &Server.Mappath(db)
这两者在性能上也有一定的差别.下面是一个测试文件,对两者进行比较.
<%
dim openmode,action,db,openstr,rs,conn
openmode=request.QueryString("openmode")
action=request.QueryString("action")
db="#niceidea.mdb"
set conn=server.createobject("adodb.connection")
if penmode="oledb" then penstr="provider=microsoft.jet.oledb.4.0;" & "data source = " & server.mappath(db)
if penmode="odbc" then penstr="Driver={Microsoft Access Driver (*.mdb)};DBQ=" &Server.Mappath(db)
Dim strStartTime
Dim strEndTime
strStartTime = Timer ''''''''''''''''''''''''''''''''开始时间
''''''''''''''''''''''''''''''''反复打开数据库50次
if action="open" then
for i=1 to 50
conn.open(openstr)
conn.close
next
set conn=nothing
end if
''''''''''''''''''''''''''''''''移动记录集10000次
if action="move" then
conn.open(openstr)
set rs=conn.execute("select * from visitor")
for i=1 to 10000
rs.movenext
next
rs.close
set rs=nothing
conn.close
set conn=nothing
end if
''''''''''''''''''''''''''''''''反复打开记录集1000次
if action="getrs" then
conn.open(openstr)
set rs=server.CreateObject("adodb.recordset")
dim sqlstr
sqlstr="select * from visitor"
for i=1 to 1000
rs.open sqlstr,conn,1,1
rs.close
next
set rs=nothing
conn.close
set conn=nothing
end if
%>
<%
'''''''''''''''''''''''''''''''' 加载完毕的时间
strEndTime = Timer
Response.Write ("运行处理时间: ")
Response.Write 1000*(strEndTime - strStartTime)
Response.Write (" 毫秒.")
response.end
%>
得到的数据如下:
odbc反复打开数据库50次:
6062.5 毫秒.
oledb反复打开数据库50次:
4601.563毫秒.
odbc移动记录集10000次:
1132.813 毫秒.
oledb移动记录集10000次:
304.6875 毫秒.
odbc反复打开记录集1000次:
8734.375 毫秒.
oledb反复打开记录集1000次:
7960.938 毫秒.
测试环境,ce1.70/512m/windows xp sp2/withnetbox(不再开发的测试服务器)
显然,在效率上,oledb有些微的优势。微软已经不更新ODBC,用JET方式连接数据库是一种更有效率的办法,特别是在需要移动游标的时候.另外,两者还有一些其他方面的区别,oledb是一种更底层的方法,在这种数据库连接方式中,应该注意的规范更多,就像用sql和access时候,某些查询语句也会不一样.例如:
select from user where id=1
将是一句错误的查询语句,因为user是系统保留的关键字.需要改为
select from [user] where id=1
如果使用odbc连接,则不存在上述情况.
如果使用jet连接,在某些虚拟主机中可能会因为access版本的不同而导致连接失败;所以你需要首先确定主机的引擎版本;在尽可能的情况下,使用以下语句打开access,将提高asp的效率,还有稳定性:
"provider=microsoft.jet.oledb.4.0;" & "data source = " & server.mappath(db)
此外,打开数据库和记录集对象都是很消耗cpu资源的,尽可能减少查询是很必要的