精华内容
下载资源
问答
  • 数据库访问方式

    千次阅读 2019-04-20 16:17:22
    数据库访问方式
                   

     

    数据库访问方式

     

    异构数据库系统混合查询—JDBC/ODBC

     

        异构数据库系统是由多个异构的成员数据库系统组成的数据库系统,异构性体现为各个成员数据库之间在硬件平台、操作系统或数据库管理系统等方面的不同。

             

        Internet上大量信息通过数据库系统可以得到有效的管理。由于历史等原因,Internet上的数据库系统不少是异构的。为了在Internet环境下,基于异种系统平台实现对异构数据库的查询和联合使用,必须提供一个独立于特定的数据库管理系统的统一编程界面。

     

         目前许多数据库系统均支持SQL,对于由SQL数据库组成的异构数据库系统,JDBC和ODBC为访问其异构成员提供了统一的方式,也为各异构成员之间的协作和多个成员之上的操作打下了基础。下文简单介绍了JDBC和ODBC对各个异构的数据库进行统一访问和协作的原理及其应用。

     

     

    ODBC


           ODBC(Open DataBase Connectivity)是微软倡导的、当前被业界广泛接受的、用于数据库访问的应用程序编程接口(API),它以X/Open和 ISO/IEC的调用级接口(CLI)规范为基础,并使用结构化查询语言(SQL)作为其数据库访问语言。 ODBC总体结构有四个组件:

        A. 应用程序:执行处理并调用ODBC API函数,以提交 SQL语句并检索结果。

        B. 驱动程序管理器(Driver Manager):根据应用程序需要加载/卸载驱动程序,处理ODBC函数调用,或把它们传送到驱动程序。

        C. 驱动程序:处理ODBC函数调用,提交SQL请求到一个指定的数据源,并把结果返回到应用程序。如果有必要,驱动程序修

                           改一应程序请求,以使请求与相关的DBMS支持的语法一致。

        D. 数据源:包括用户要访问的数据及其相关的操作系统、DBMS及用于访问DBMS的网络平台。

     

     

    ODBC驱动程序的使用把应用程序从具体的数据库调用中隔离开来。

    驱动程序管理器针对特定数据库的各个驱动程序进行集中管理,并向应用程序提供统一的标准接口,这就为ODBC的开放性奠定了基础。

     

     

    数据库独立性

         ODBC是为最大的互用性而设计的,要求一个应用程序有用相同的源代码(不用重新编译或重新链接)访问不同的数据库管理系统(DBMS)的能力。

     

         ODBC定义了一个标准的调用层接口(CLI)。这包含 X/Open和ISO/IEC的CLI规范中的所有函数,并提供应用程序普遍需要的附加函数。每个支持ODBC的DBMS需要不同的库或驱动程序,驱动程序实现ODBC API中的函数。当需要改变驱动程序时,应用程序不需要重新编译或者重新链接,只是动态加载新的驱动程序,并调用其中的函数即可。如果要同时访问多个DBMS系统,应用程序可加载多个驱动程序。如何支持驱动程序取决于操作系统,例如,在Windows操作系统上,驱动程序是动态链接库(DLL)。使用相同源代码的应用程序访问不同的DBMS,体现了 ODBC的数据库独立性。

     

     

    对数据库特殊功能的支持

        各个DBMS参照的标准、提供的功能不尽相同,应用程序如何以统一的接口使用各个DBMS特有的功能呢?

    一方面,ODBC为所有DBMS功能都定义了公共接口。这些DBMS功能比多数DBMS支持的更多,但只要求驱动程序实现这些功能的一个子集。另一方面,ODBC定义了API和SQL语法一致层,它规定驱动程序应支持的基本功能。 ODBC还提供两个函数(SQLGetInfo和SQLGetFunctions)返回关于驱动程序和DBMS能力的一般信息及驱动程序支持的函数列表。因此,应用程序可以检查DBMS支持的特殊功能。

     

        这样,编写应用程序时,就可以检查并自动使用各个驱动程序对应的DBMS所支持的特殊功能。这样做的优点是当增加DBMS支持的功能时,应用程序不需要改变,只需安装更新的驱动程序,应用程序便可以自动发现并使用这些功能。

     

    互操作能力

          通过使用多个驱动程序可以同时访问多个DBMS系统。 ODBC提供的Driver Manager实现所有的ODBC函数,多数是传递调用给驱动程序中的ODBC 函数,并静态链接应用程序,或在应用程序运行时加载它。这样,应用程序在Driver Manager 中按名调用驱动ODBC函数,而不是通过每个驱动程序中的指针。当应用程序需要通过特定的驱动程序时,它首先需要一个标识驱动程序的连接句柄。Driver Manager加载驱动程序,并存储每个驱动程序中的函数地址。要使驱动程序调用一个ODBC函数,可在应用程序调用 Driver Manager中的函数,并为驱动程序传送连接句柄,然后Driver Manager使用以前存储的地址来调用函数。

     

      ODBC可以同时连接到多个DBMS,解决了同时访问多个DBMS的问题,提供了异构成员数据库之间互操作的能力。

     

     

    JDBC


       JDBC(Java DataBase Connectivity)是Java与数据库的接口规范,JDBC定义了一个支持标准SQL功能的通用低层的应用程序编程接口(API),它由Java 语言编写的类和接口组成,旨在让各数据库开发商为Java程序员提供标准的数据库API。 JDBC API定义了若干Java中的类,表示数据库连接、SQL指令、结果集、数据库元数据等。它允许Java程序员发送SQL指令并处理结果。通过驱动程序管理器,JDBC API可利用不同的驱动程序连接不同的数据库系统。

     

          JDBC与ODBC都是基于X/Open的SQL调用级接口, JDBC的设计在思想上沿袭了ODBC,同时在其主要抽象和SQL CLI实现上也沿袭了ODBC,这使得JDBC容易被接受。JDBC的总体结构类似于ODBC,也有四个组件:应用程序、驱动程序管理器、驱动程序和数据源

     

        JDBC保持了ODBC的基本特性,也独立于特定数据库。使用相同源代码的应用程序通过动态加载不同的JDBC驱动程序,可以访问不同的DBMS。连接不同的DBMS时,各个DBMS之间仅通过不同的URL进行标识。JDBC的 DatabaseMetaData接口提供了一系列方法,可以检查DBMS对特定特性的支持,并相应确定有什么特性,从而能对特定数据库的特性予以支持。与ODBC一样,JDBC也支持在应用程序中同时建立多个数据库连接,采用JDBC可以很容易地用SQL语句同时访问多个异构的数据库,为异构的数据库之间的互操作奠定基础。

     

         但是,JDBC除了具有ODBC的上述特点外,更具有对硬件平台、操作系统异构性的支持。这主要是因为ODBC使用的是C语言,而JDBC使用的是Java语言。Java语言具有与平台无关、移植性强、安全性高、稳定性好、分布式、面向对象等众多优点,而JDBC确保了“100%纯Java”的解决方案,利用Java的平台无关性, JDBC应用程序可以自然地实现跨平台特性,因而更适合于Internet上异构环境的数据库应用。

     

        此外,JDBC驱动程序管理器是内置的,驱动程序本身也可通过Web浏览器自动下载,无须安装、配置;而ODBC驱动程序管理器和ODBC驱动程序必须在每台客户机上分别安装、配置。

     

     

    JDBC和ODBC在Internet上的应用
     

    JDBC和ODBC由于具有数据库独立性甚至平台无关性,因而对Internet上异构数据库的访问提供了很好的支持。

     

         在Internet上访问数据库通常采用三层模式。以JDBC为例,在三层模式中客户端的Java Applet主要作为用户界面,它不直接与数据库交换信息,而是通过自定义的应用层网络协议与应用服务器交互,应用服务器通过JDBC与数据库服务器交换信息,并实现应用逻辑。DM3的JDBC和ODBC驱动程序支持目前流行的ASP和JSP技术,可以分别借助ODBC和JDBC同时访问Internet上多个异构的数据库。

     

         ASP是面向Web服务器的技术,客户端浏览器不需要任何附加的软件支持。ASP使用VBScript之类的脚本语言,它在HTML代码中嵌入某种程序代码,由HTML代码负责描述信息的显示样式,由嵌入的程序代码来描述处理逻辑。在ASP 下,VBScript代码被ASP引擎在Web服务器端解释执行,执行结果被重新嵌入到HTML代码中,然后一起发送给浏览器。这里,VBScript代码可以通过ODBC访问多个异构的数据库。

     

        JSP是一种基于Java Servlet的Web开发技术,它和ASP 非常相似,但又有区别:在JSP下,嵌入HTML页面的程序代码是Java代码;页面中嵌入的程序代码被编译成Servlet(这种编译操作仅在对JSP页面的第一次请求时发生)并由Java 虚拟机执行。这里Java代码可以通过JDBC访问多个异构的数据库,其平台无关性特别好。当前,Internet上的数据库应用已越来越多,JDBC和ODBC必将在Internet上的异构数据库访问中发挥重要的作用。

     

     

    微软了的数据访问方式历史演变

     

    ODBC(Open Database Connectivity):

    是Microsoft公司开发和定义的一套数据库访问标准,称为开放数据库系统互联。ODBC提供了一种编程接口,可以使用一个ODBC应用程序访问各种数据库管理系统,例如Access、MySQL、DB2、FoxPro、SQL Server和Oracle等,它是第一个使用SQL访问不同关系数据库的数据访问技术。使用ODBC应用程序能够通过单一的命令操纵不同的数据库,而开发人员需要做的仅仅只是针对不同的应用加入相应的ODBC驱动。
      
    DAO(Data  Access Objects):

    不像ODBC那样是面向C/C++程序员的,它是微软提供给Visual Basic开发人员的一种简单的数据访问方法,但不提供远程访问功能。


    RDO(Remote Data Object):

    在使用DAO访问不同的关系型数据库的时候,Jet引擎不得不在DAO和ODBC之间进行命令的转化,导致了性能的下降,而RDO(Remote Data Objects)的出现就顺理成章了。
      
    OLE DB(Object Linking and Embedding DataBase):

    OLE DB(对象链接和嵌入数据库)随着越来越多的数据以非关系型格式存储,需要一种新的架构来提供这种应用和数据源之间的无缝连接,基于COM(Component Object Model)的OLE DB应运而生了。
      
    ADO(ActiveX Data Object):

    基于OLE DB之上的ADO更简单、更高级、更适合Visual Basic程序员,同时消除了OLE DB的多种弊端,取而代之是微软技术发展的趋势。

     

     ADO.NET

    是一种基于标准的程序设计模型,可以用来创建分布式应用以实现数据共享。在ADO.NET中,DataSet占据重要地位,它是数据库里部分数据在内存中的拷贝。与ADO中的RecordSet不同,DataSet可以包括任意个数据表,每个数据表都可以用于表示自某个数据库表或视图的数据。DataSet驻留在内存中,且不与原数据库相连,即无需与原数据库保持连接。完成工作的底层技术是XML,它是DataSet所采用的存储和传输格式。在运行期间,组件 (如某个业务逻辑对象或asp.net web表单)之间需要交换DataSet中的数据。数据以XML文件的形式从一个组件传输给另一个组件,由接收组件将文件还原为DataSet形式。DataSet的有关方法与关系数据模型完全一样

     

         因为各个数据源的协议各不相同,我们需要通过正确的协议来访问数据源。有些比较老的数据源用ODBC协议,其后的一些数据源用OleDb协议,现在,仍然还有许多新的数据源在不断出现,ADO.NET提供了访问数据源的公共方法,对于不同的数据源,它采用不同的类库。这些类库称为Data Providers,并且通常是以数据源的类型以及协议来命名的

     

    ADO.NET Data Providers是一组提供访问指定数据源的基本类库。API的开头字符表明了他们支持的协议。

     

    Provider

    API 前缀

    数据源描述

    ODBC Data Provider

    Odbc

    提供ODBC接口的数据源。一般是比较老的数据库。

    OleDb Data Provider

    OleDb

    提供OleDb接口的数据源,比如AccessExcel

    Oracle Data Provider

    Oracle

    Oracle数据库

    SQL Data Provider

    Sql

    Microsoft SQL Server数据库

    Borland Data Provider

    Bdp

    通用的访问方式能访问许多数据库,比如InterbaseSQL ServerIBM DB2Oracle

     

     

     

    这些数据库连接方式ODBC,DAO,RDO,OLE DB,ADO,ADO.NET都是基于oracle客户端(oracle OCI),中间通过SQL*Net与数据库通信。如果为了追求性能,可以自己开发最适合自己数据库连接方式。

     

     

     

    Java程序连接数据库的方式

     

    Java程序连接数据库的方式有三种方式:OCI方式、thin方式和JdbcOdbc桥方式

     

     

    1. OCI方式

    这种实现方法是直接使用数据库厂商提供的用专用的网络协议创建的驱动程序,通过它可以直接将JDBC API调用转换为直接网络调用。这种调用方式一般性能比较好,而且也是实用中最简单的方法。因为它不需要安装其他的库或中间件。几乎所有的数据库厂商都为他们的数据库提供了这种数据库提供了这种JDBC驱动程序,也可以从第三方厂商获得这些驱动程序。

     

    应用程序---JDBC API---驱动程序---数据源

     

     

    2. Thin方式

    thin方式是纯java实现tcp/ip的通讯,而oci方式,客户端通过native java method调用c library访问服务端,而这个c library就是oci(oracle called interface),因此这个oci总是需要随着oracle客户端安装

     

    oracle jdbc oci方式是用java与c两种语言编写的,把jdbc call调用,转换成c调用,通过SQL*Net与数据库通信。而oracle jdbc thin驱动方式全采用java编写,使用jvm统一管理内存,也是通过SQL*Net与数据库通信。

     

     

    3. JdbcOdbc桥方式(用于windows平台)

    JDBC-ODBC桥接器是用JdbcOdbc.Class和一个用于访问ODBC驱动程序的本地库实现的。

    由于JDBC在设计上与ODBC很接近。在内部,这个驱动程序把JDBC的方法映射到ODBC调用上,这样,JDBC就可以和任何可用的ODBC驱动程序进行交互了。这种桥接器的优点是,它使JDBC目前有能力访问几乎所有的数据库。通行方式如下所示:

     

    应用程序--->JDBC API--->JDBC-ODBC--->ODBC API--->ODBC层--->数据源

     

     

     

     

    事务控制

    无论是java,还是.net都是支持事务控制的,事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问

     

    事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写。

     

    原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。

    一致性:表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。

    隔离性:表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。

    持久性:表示已提交的数据在事务执行失败时,数据的状态都应该正确。

     

     

    Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。

    .net事务分为本地事务和分布式事务

     

     

     

    jdbc/odbc主要优化方式:


         1.选择正确的jdbc/odbc驱动程序
         2.Connention的优化  使用连接池来管理Connection对象
         3.Statement的优化   使用批量更新等
         4.Result的优化  正确的从数据库中get数据等

     

     

     

     

    -------end------

     

     

     

     

     

     

               
    展开全文
  • 本人最近完成了一个封装数据库访问抽象层的项目。我们开发的数据库访问抽象层作为分布式集群基础平台的一个组件。可以支持不同数据库编程接口(OCI、mysql、ODBC、pgsql)等。本系列博客主要分享一下我在开发数据库...

    摘要
    本人最近完成了一个封装数据库访问抽象层的项目。我们开发的数据库访问抽象层作为分布式集群基础平台的一个组件。可以支持不同数据库编程接口(OCI、mysql、ODBC、pgsql)等。本系列博客主要分享一下我在开发数据库访问抽象层组件的遇到的问题和收获。
    在本文主要介绍数据库访问抽象层的概念,常见的几种数据库编程接口ODBC、JDBC、OLE-DB、ADO、OCI等。

    数据库访问抽象层的意义
    数据库访问抽象层是封装了数据库底层操作的介于应用逻辑程序和数据之间的中间件。目的是为了隐藏因为数据库方言的不同,而在存取数据中的差异。使整个系统在变更商业数据库的时候,做到改动最小,或者只需要修改数据库的配置文件即可。
    提供一种轻型、清晰、方便的 API ,统一各种不同 RDBMS 库的共有特性,但不排除更高级的特性。通过动态库提供可选的较大程度的抽象/兼容性。针对以上理解,本文共分为四个部分:
     第一部分是1、2章,主要探讨几种数据库编程接口的选择;
     第二部分是第3章,详细描述ODBC的安装与配置;
     第三部分是4、5章,讨论ODBC的数据类型以及支持的函数;
     第四部分是6章,编写一个ODBC编程接口的测试程序
     第五部分是第7章,作为附录介绍ODBC编程常遇到的两个问题。


    1. 概念
    服务器后台数据库的编程接口包括OCI、JDBC、ODBC、OLE-DB、ADO,本小节分别阐述几种概念并分析他们之间的关系。
    1.1. 什么是JDBC?
    Java语言访问数据库的一种规范,是一套API。
    JDBC(Java Database connectivity)API,即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库。比如建立数据库连接、执行SQL语句进行数据的存取操作。
    JDBC规范采用接口和实现分离的思想设计了Java数据库的编程框架。接口包含在Java.sql及Javax.sql包中,其中Java.sql属于JavaSE,Javax.sql属于JavaEE。这些接口的实现类叫做数据库驱动程序,由数据库的厂商或其它的厂商或个人提供。

    这里写图片描述
    图1-1

    1.2. 什么是ODBC?
    ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。
    应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。
    达梦数据库(DM DATABASE,以下简称DM)的DM ODBC 3.0遵照Microsoft ODBC 3.0规范设计与开发,实现了ODBC应用程序与DM的互连接口。用户可以直接调用DM ODBC 3.0接口函数访问DM,也可以使用可视化编程工具如Visual C++、C++ Builder、PowerBuilder等利用DM ODBC 3.0访问DM。

    图1-2
    图 1-2

    1.3. 什么是OLE-DB
    OLE DB(Object Link and embed 即对象连接与嵌入。)是微软的战略性的通向不同的数据源的低级应用程序接口。OLE DB不仅包括微软资助的标准数据接口开放数据库连通性(ODBC)的结构化问题语言(SQL)能力,还具有面向其他非SQL数据类型的通路。 作为微软的组件对象模型(COM)的一种设计,OLE DB是一组读写数据的方法(在过去可能被称为渠道)。OLD DB中的对象主要包括数据源对象、阶段对象、命令对象和行组对象。使用OLE DB的应用程序会用到如下的请求序列:初始化OLE 连接到数据源 发出命令 处理结果 释放数据源对象并停止初始化OLE
    OLE DB标准中定义的新概念—-OLE DB将传统的数据库系统划分为多个逻辑组件,这些组件之间相对独立又相互通信。这种组件模型中的各个部分被冠以不同的名称:数据提供者(Data Provider)。 提供数据存储的软件组件,小到普通的文本文件、大到主机上的复杂数据库,或者电子邮件存储,都是数据提供者的例子。有的文档把这些软件组件的开发商也称为数据提供者。

    1.4. 什么是ADO
    微软公司的ADO (ActiveX Data Objects)是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO中的命令对象来执行。
    ADO被设计来继承微软早期的数据访问对象层,包括RDO (Remote DataObjects)和DAO(Data Access Objects)。ADO在1996年冬被发布。
    ADO包括了6个类:Connection,Command,Recordset,Errors,Parameters,Fields。

    1.5. OLE-DB 和ODBC的区别
    由于OLEDB和ODBC 标准都是为了提供统一的访问数据接口,所以曾经有人疑惑:OLE DB 是不是替代ODBC 的新标准?答案是否定的。实际上,ODBC 标准的对象是基于SQL 的数据源(SQL-Based Data Source),而OLE DB 的对象则是范围更为广泛的任何数据存储。从这个意义上说,符合ODBC 标准的数据源是符合OLE DB 标准的数据存储的子集。

    1.6. ADO、OLE-DB和ODBC的关系
    通俗点 OLE DB和ODBC都是最底层的东西,而ADO对象给我们提供了一个“可视化”,和应用层直接交互的组件,我们不用过多的关注OLE-DB的内部机制,只需要了解ADO通过OLE-DB创建数据源的几种方法即可,就可以通过ADO轻松地获取数据源。ADO是应用程序和数据底层的一个中间层,ADO对象通过OLE-DB间接取得数据库中的数据。OLE-DB只是提供了通向各种数据库的一个通用接口,可以用下图2-1来表示:

    图1-3
    图1-3
    1.7 OCI编程接口的简介

    请参照如下连接的简介:
    http://baike.baidu.com/link?url=i57cAhZrzMiGI1lNLp3se9Tkg_9BSdwDp3K_vVS-IwR5m90mcdsjv_366kASh46xjPRM8kYJs3K0djJG9BSOZ_
    pgsql编程接口的简介:
    http://baike.baidu.com/link?url=k0sIoIwe9U1ySbQLk6CR3soEFw9smmeF35Q3D7Cz-Etc4GjBgFIc-Ze288J07ECe6xNY6d-dgcgJ3O4A02O1mK


    2. 标准接口的选择
    2.1. 为什么不选择JDBC?
    由1.1和1.2两个小节可知,JDBC属于Java数据库编程接口,ODBC支持C/C++等变成语言。根据需求我们需要封装一套通用C/C++数据库封装层API,故JDBC不可行。

    2.2. 为什么不选择ADO?
    由2小节可知,ADO是对OLE-DB的封装,优势主要在于易用性和可视化,本质上ADO是数据库访问抽象层。而我们的需求是提供类似PCS系统DBAPI的API接口函数,可以方便的支持不同的数据库。如果选择ADO,则我们需要在ADO的基础上再封装一层API接口,而数据库操作是偏向底层。过多的封装在一定程度上降低整个系统的性能。基于以上原因而不选择ADO。

    2.3. 用OLE-DB还是ODBC?
    从网络查找资料了解到选择OLE-DB和ODBC的一些基本的原则:
    ① 非OLE 环境 —— 如果要访问支持ODBC 的数据库,而该数据库又在不支持OLE 的服务器上,那么ODBC 是最好的选择。
    ② 非SQL 环境 —— ODBC 在处理SQL 时非常出众。处理非SQL 数据库时,OLE-DB则具有非常明显的优势。
    ③ OLE 环境 —— 对支持OLE 的服务器来说,选择OLE-DB 还是ODBC 也许是希望各半。如果有ODBC 驱动程序可供利用,那么使用ODBC 是一个好主意;否则,就只有选择OLE-DB了。
    ④ 所需的互操作性 如果需要可互操作的数据库部件,那么只有选择OLE-DB。
    综合以上基本原则②和我们的需求,个人认为我们更适合选择ODBC编程接口。
    结论
    根据以上原则,选择ODBC作为待封装的编程接口。


    3. ODBC的安装与配置
    使用ODBC 方法访问一个DM 数据库服务器之前,必须先对自己的应用程序所用的ODBC 资源进行配置。本小节将介绍如何在linux环境下安装和配置ODBC 资源。
    在 Linux 上配置ODBC 数据源的方式有两种,手动配置和图形配置。下面将以麒麟操作系统为例详细描述Linux环境安装unixODBC数据源、手动配置达梦ODBC数据源。

    3.1. 编译和安装unixODBC数据源
    ① 将压缩包unixODBC-2.3.0.tar.gz上传到 linux /usr/local 下,然后执行 tar -xzvf unixODBC-2.3.0.tar.gz
    ② 进入cd /usr/local/unixODBC-2.3.0 执行 ./configure –prefix=/usr/local/unixODBC-2.3.0 –includedir=/usr/include –libdir=/lib64/lib -bindir=/usr/bin –sysconfdir=/etc
    ③ 执行 make
    ④ 执行 make install
    ⑤ 通过 odbc_config –version 确定odbc安装是否成功,显示2.3.0表示已经成功安装。

    3.2. 配置达梦ODBC资源
    达梦数据库ODBC达梦数据库驱动程序如下表格3-1所示。达梦ODBC有两个配置文件odbcinst.ini和odbc.ini。odbcinst.ini文件负责配置DM 数据库ODBC 驱动,odbc.ini文件负责配置 DSN(data source name)。这两个文件的路径通过命令获取,如下图所示。达梦ODBC需要的动态库:libdmapi.so、libdmcrypto_engine.so、libdmodbc.so、libdmucvt.so、libdmzip.so。

    [root@localhost etc]# odbc_config --odbcini
    /etc/odbc.ini
    [root@localhost etc]# odbc_config --odbcinstini
    /etc/odbcinst.ini
    

    图3-1

    odbcinst.ini文件配置项:
    ① [dm]设置DSN(data source name)-即设置数据源名。
    ② Driver指定动态驱动库路经。
    odbc.ini文件配置项:
    ① Driver指定动态驱动库路经;
    ② SERVER指定数据库节点IP地址
    ③ UID指定登陆用户名
    ④ PWD指定登陆密码
    ⑤ TCP_PORT指定端口号,默认12345
    现在通过实例配置文件odbc.ini需要修改字段SERVER,使之等于达梦数据库服务端节点IP。odbcinst.ini需要修改字段Driver,使之与动态库libdmodbc.so实际路径相同(注:与达梦手册中配置不同部分,以本文档为准)。图3-3和图3-4是备调测试系统BDTEST sgs1-net1节点上两个文件配置的两个实例:

    [dm]
    Description = dm
    Driver =dm
    SERVER =192.168.200.100
    UID=SYSDBA
    PWD=SYSDBA
    TCP_PORT=12345
    

    图3-3 odbc.ini文件

    [dm]
    Description=dm
    Driver = /etc/dm_odbc_lib/libdmodbc.so
    

    表格 3 4文件odbcinst.ini

    配置完成后在任意路径,通过命令测试连接。方法如下图所示:

    [root@localhost /]# isql dm SYSDBA SYSDBA
    +---------------------------------------+
    | Connected!              |
    |                        |
    | sql-statement            |
    | help [tablename]          |
    | quit                    |
    |                        |
    +---------------------------------------+
    

    图 3-5 测试连接


    4. ODBC的数据类型
    客户程序可以通过SQLGetTypeInfo 函数来获取DM ODBC 3.0 支持的数据类型信息。由
    SQLGetTypeInfo 返回的数据类型是数据源所支持的数据类型,它们是预备用于DDL
    (DataDefinitionLanguage)语句的。调用 DM ODBC 3.0 的SQLGetTypeInfo,返回支持的数据类型如图5-1如下:

    图5-1
    图4-1
    注:要支持interval 数据类型,必须在数据源中进行设置,否则将不提供对该类数据类型的支持。变长字符串的最大长度实际上是受库块大小的约束,上面的约束是在库大小为8K 时的最大长度。


    5. 达梦ODBC支持的函数
    DM ODBC 3.0 遵照Microsoft ODBC 3.0 规范设计与开发

    客户程序可以通过SQLGetFunctions 函数来获取DM ODBC 3.0 支持的函数信息。由SQLGetFunctions 返回的函数列表是数据源所支持的函数。以下按照类型分类列出了DM ODBC 3.x 提供的函数。应用程序能够通过调用SQLGetFunctions 来获得指定函数的支持信息。
    5.1. 连接到数据源
    下面的函数用于连接到数据源:
    (1)SQLAllocHandle:分配环境、连接、语句或者描述符句柄。
    (2)SQLConnect:建立与驱动程序或者数据源的连接。访问数据源的连接句柄包含了包
    括状态、事务申明和错误信息的所有连接信息。
    (3)SQLDriverConnect:与SQLConnect 相似,用来连接到驱动程序或者数据源。但它比
    SQLConnect 支持数据源更多的连接信息,它提供了一个对话框来提示用户设置所有的连接信息
    以及系统信息表没有定义的数据源。
    (4)SQLBrowseConnect:支持一种交互方法来检索或者列出连接数据源所需要的属性和
    属性值。每次调用函数可以获取一个连接属性字符串,当检索完所有的属性值,就建立起与数
    据源的连接,并且返回完整的连接字符串,否则提示缺少的连接属性信息,用户根据此信息重
    新输入连接属性值再次调用此函数进行连接。
    5.2. 获取驱动程序和数据源信息
    下面的函数用来获取驱动程序和数据源信息:
    (1)SQLDataSources:能够被调用多次来获取应用程序使用的所有数据源的名字。
    (2)SQLDrivers:返回所有安装过的驱动程序清单,包括对它们的描述以及属性关键字。
    (3)SQLGetInfo:返回连接的驱动程序和数据源的元信息。
    (4)SQLGetFunctions:返回指定的驱动程序是否支持某个特定函数的信息。
    (5)SQLGetTypeInfo:返回指定的数据源支持的数据类型的信息。
    5.3. 设置或者获取驱动程序属性
    下面的函数用来设置或者获取驱动程序属性:
    (1)SQLSetConnectAttr:设置连接属性值。
    (2)SQLGetConnectAttr:返回连接属性值。
    (3)SQLSetEnvAttr:设置环境属性值。
    (4)SQLGetEnvAttr:返回环境属性值。
    (5)SQLSetStmtAttr:设置语句属性值。
    (6)SQLGetStmtAttr:返回语句属性值。
    5.4. 设置或者获取描述符字段
    下面的函数用来设置或者获取描述符字段:
    (1)SQLGetDescField:返回单个描述符字段的值。
    (2)SQLGetDescRec:返回当前描述符记录的多个字段的值。
    (3)SQLSetDescField:设置单个描述符字段的值。
    (4)SQLSetDescRec:设置描述符记录的多个字段。
    5.5. 准备SQL 语句
    下面的函数用来准备SQL 语句:
    (1)SQLPrepare:准备要执行的SQL 语句。
    (2)SQLBindParameter:在SQL 语句中分配参数的缓冲区。
    (3)SQLGetCursorName:返回与语句句柄相关的游标名称。
    (4)SQLSetCursorName:设置与语句句柄相关的游标名称。
    (5)SQLSetScrollOptions:设置控制游标行为的选项。
    5.6. 提交SQL 请求
    下面的函数用来提交SQL 请求:
    (1)SQLExecute:执行准备好的SQL 语句。
    (2)SQLExecDirect:执行一条SQL 语句。
    (3)SQLNativeSql:返回驱动程序对一条SQL 语句的翻译。
    (4)SQLDescribeParam:返回对SQL 语句中指定参数的描述。
    (5)SQLNumParams:返回SQL 语句中参数的个数。
    (6)SQLParamData:与SQLPutData 联合使用在运行时给参数赋值。
    (7)SQLPutData:在SQL 语句运行时给部分或者全部参数赋值。
    5.7. 检索结果集及其相关信息
    下面的函数用来检索结果集及其相关信息:
    (1)SQLRowCount:返回INSERT、UPDATE 或者DELETE 等语句影响的行数。
    (2)SQLNumResultCols:返回结果集中列的数目。
    (3)SQLDescribeCol:返回结果集中列的描述符记录。
    (4)SQLColAttribute:返回结果集中列的属性。
    (5)SQLBindCol:为结果集中的列分配缓冲区。
    (6)SQLFetch:在结果集中检索下一行元组。
    (7)SQLFetchScroll:返回指定的结果行。
    (8)SQLGetData:返回结果集中当前行某一列的值。
    (9)SQLSetPos:在取到的数据集中设置游标的位置。这个记录集中的数据能够刷新、更
    新或者删除。
    (10)SQLBulkOperations:执行块插入和块书签操作,其中包括根据书签更新、删除或者
    取数据。
    (11)SQLMoreResults:确定是否能够获得更多的结果集,如果能就执行下一个结果集的
    初始化操作。
    (12)SQLGetDiagField:返回一个字段值或者一个诊断数据记录。
    (13)SQLGetDiagRec:返回多个字段值或者一个诊断数据记录。
    5.8. 取得数据源系统表的信息
    下面的函数用来取得数据源系统表的信息:
    (1)SQLColumnPrivileges:返回一个关于指定表的列的列表以及相关的权限信息。
    (2)SQLColumns:返回指定表的列信息的列表。
    (3)SQLForeignKeys:返回指定表的外键信息的列表。
    (4)SQLPrimaryKeys:返回指定表的主键信息的列表。
    (5)SQLProcedureColumns:返回指定存储过程的参数信息的列表。
    (6)SQLProcedures:返回指定数据源的存储过程信息的列表。
    (7)SQLSpecialColumns:返回唯一确定某一行的列的信息,或者当某一事务修改一行的
    时候自动更新各列的信息。
    (8)SQLStatistics:返回一个单表的相关统计信息和索引信息。
    (9)SQLTablePrivileges:返回相关各表的名称以及相关的权限信息。
    (10)SQLTables:返回指定数据源中表信息。
    5.9. 终止语句执行
    下面的函数用来终止语句执行:
    (1)SQLFreeStmt:终止语句执行,关闭所有相关的游标,放弃没有提交的结果,选择释
    放与指定语句句柄相关的资源。
    (2)SQLCloseCursor:关闭一个打开的游标,放弃没有提交的结果。
    (3)SQLCancel:放弃执行一条SQL 语句。
    (4)SQLEndTran:提交或者回滚事务。
    5.10. 中断连接
    下面的函数处理中断连接的任务:
    (1)SQLDisconnect:关闭指定连接。
    (2)SQLFreeHandle:释放环境、连接、语句或者描述符句柄。
    5.11. ODBC编程:
    使用ODBC编程的基本步骤如下图所示
    5-2
    图5-2

    6编写两个简单建立连接和断开连接的示例程序

    6.1建立连接:

    int DMODBCDBApi::Connect(const char *pszConnectStr,const char *pszUser,const char *pszPasswd)
    {
    // 检测返回代码是否为成功标志,当为成功标志时返回TRUE,否则返回FALSE
    #define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
    // 检测返回代码是否为失败标志,当为失败标志时返回TRUE,否则返回FALSE
    #define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
        // 申请一个环境句柄
        SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
        // 设置环境句柄的ODBC版本
        SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3,
        SQL_IS_INTEGER);
        // 申请一个连接句柄
        SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
        sret = SQLConnect(hdbc, (SQLCHAR *)pszConnectStr, SQL_NTS, (SQLCHAR *)pszUser, SQL_NTS, (SQLCHAR*)pszPasswd, SQL_NTS);
        if (RC_NOTSUCCESSFUL(sret))
        {
            // 连接数据源失败! 进行相应的错误处理
            printf("RC_NOTSUCCESSFUL!!!\n");
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
            SQLFreeHandle(SQL_HANDLE_ENV, henv);
            return -1;
        }
        connected = true;
        printf("CONNECT SUCCESSFUL!!!\n");
        return 0;
    }
    

    6.2 断开连接的示例程序

    int DMODBCDBApi::DisConnect()
    {
        // 断开与数据源之间的连接
        SQLDisconnect(hdbc);
        // 释放连接句柄
        SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
        // 释放环境句柄
        SQLFreeHandle(SQL_HANDLE_ENV, henv);
        // 连接状态为断开
        connected = false;
        hdbc = NULL;
        henv = NULL;
        return 0;
    }
    

    6.3 Makefile编写的关键点注意

    INCDIR = -I. -I/usr/include/
    LIBDIR = -L/lib64/lib 
    LIBS = -lodbc                           
    #连接的是UnixODBC数据源动态库,而不是达梦ODBC动态库
    

    7. 附录
    在探索过程中发现,觉得在以后编程实战也可能遇到的问题记录如下:
    7.1. 调用达梦动态库段错误
    解决方法:
    编写makefile的时候,连接的动态库是UnixODBC数据源的动态库而非达梦的动态库;
    7.2. 打不开动态库
    如下图所示:cannot open shared object file: No such file or directory

    图7-2

    sgs1-net2:/lib64/lib # ls libodbc.so.1
    libodbc.so.1
    但是ldd命令找不到,说明程序运行加载动态库的时候未搜索到libodbc.so.1。
    于是找到解决方案:
    vi /etc/ld.so.conf
    加入路径/lib64/lib,如下所示:
    7-2
    图 7-2
    执行命令/sbin/ldconfig –v 更新程序加载动态库的路径

    展开全文
  • Oracle数据库访问性能优化

    万次阅读 多人点赞 2018-02-20 16:02:36
    所有数据库包括Oracle的sql优化都是针对程序员的... 根据计算机硬件的基本性能指标及其在数据库中主要操作内容,可以整理出如下图所示的性能基本优化法则: 这个优化法则归纳为5个层次: 1、减少数据访问(减少磁盘...

           所有数据库包括Oracle的sql优化都是针对程序员的,而不是针对dba的,第一,尽量防止模糊,明确指出,即用列名代替*,第二,在where语句上下工夫。第三多表查询和子查询,第四尽量使用绑定。

           根据计算机硬件的基本性能指标及其在数据库中主要操作内容,可以整理出如下图所示的性能基本优化法则:

           这个优化法则归纳为5个层次:
           1、减少数据访问(减少磁盘访问)
           2、返回更少数据(减少网络传输或磁盘访问)
           3、减少交互次数(减少网络传输)
           4、减少服务器CPU开销(减少CPU及内存开销)
           5、利用更多资源(增加资源)
           由于每一层优化法则都是解决其对应硬件的性能问题,所以带来的性能提升比例也不一样。传统数据库系统设计是也是尽可能对低速设备提供优化方法,因此针对低速设备问题的可优化手段也更多,优化成本也更低。我们任何一个SQL的性能优化都应该按这个规则由上到下来诊断问题并提出解决方案,而不应该首先想到的是增加资源解决问题。

           以下是每个优化法则层级对应优化效果及成本经验参考:

    优化法则

    性能提升效果

    优化成本

    减少数据访问

    1~1000

    返回更少数据

    1~100

    减少交互次数

    1~20

    减少服务器CPU开销

    1~5

    利用更多资源

    @~10

    1 减少数据访问

    1.1 创建并使用正确的索引

           数据库索引的原理非常简单,但在复杂的表中真正能正确使用索引的人很少,即使是专业的DBA也不一定能完全做到最优。
           索引会大大增加表记录的DML(INSERT,UPDATE,DELETE)开销,正确的索引可以让性能提升100,1000倍以上,不合理的索引也可能会让性能下降100倍,因此在一个表中创建什么样的索引需要平衡各种业务需求。
    一、SQL什么条件会使用索引?
           当字段上建有索引时,通常以下情况会使用索引:
           INDEX_COLUMN = ?
           INDEX_COLUMN > ?
           INDEX_COLUMN >= ?
           INDEX_COLUMN < ?
           INDEX_COLUMN <= ?
           INDEX_COLUMN between ? and ?
           INDEX_COLUMN in (?,?,...,?)
           INDEX_COLUMN like ?||'%'(后导模糊查询)
           T1. INDEX_COLUMN=T2. COLUMN1(两个表通过索引字段关联)

    二、SQL什么条件不会使用索引?

    查询条件

    不能使用索引原因

    INDEX_COLUMN <> ?

    INDEX_COLUMN not in (?,?,...,?)

    不等于操作不能使用索引

    function(INDEX_COLUMN) = ?

    INDEX_COLUMN + 1 = ?

    INDEX_COLUMN || 'a' = ?

    经过普通运算或函数运算后的索引字段不能使用索引

    INDEX_COLUMN like '%'||?

    INDEX_COLUMN like '%'||?||'%'

    含前导模糊查询的Like语法不能使用索引

    INDEX_COLUMN is null

    B-TREE索引里不保存字段为NULL值记录,因此IS NULL不能使用索引

    NUMBER_INDEX_COLUMN='12345'

    CHAR_INDEX_COLUMN=12345

    Oracle在做数值比较时需要将两边的数据转换成同一种数据类型,如果两边数据类型不同时会对字段

    值隐式转换,相当于加了一层函数处理,所以不能使用索引。

    a.INDEX_COLUMN=a.COLUMN_1

    给索引查询的值应是已知数据,不能是未知字段值。

    注:经过函数运算字段的字段要使用可以使用函数索引,这种需求建议与DBA沟通。

    有时候我们会使用多个字段的组合索引,如果查询条件中第一个字段不能使用索引,那整个查询也不能使用索引。

    如:我们company表建了一个id+name的组合索引,以下SQL是不能使用索引的

    Select * from company where name=?

    Oracle9i后引入了一种index skip scan的索引方式来解决类似的问题,但是通过index skip scan提高性能的条件比较特殊,使用不好反而性能会更差。

    三、我们一般在什么字段上建索引?
           这是一个非常复杂的话题,需要对业务及数据充分分析后再能得出结果。主键及外键通常都要有索引,其它需要建索引的字段应满足以下条件:
           1、字段出现在查询条件中,并且查询条件可以使用索引;
           2、语句执行频率高,一天会有几千次以上(并发测试必须有索引);
           3、通过字段条件可筛选的记录集很小,那数据筛选比例是多少才适合?
           这个没有固定值,需要根据表数据量来评估,以下是经验公式,可用于快速评估:
           小表(记录数小于10000行的表):筛选比例<10%;
           大表:(筛选返回记录数)<(表总记录数*单条记录长度)/10000/16
           单条记录长度≈字段平均内容长度之和+字段数*2

     

           以下是一些字段是否需要建B-TREE索引的经验分类:

     

     

    字段类型

    常见字段名

    需要建索引的

    字段

    主键

    ID,PK

    外键

    PRODUCT_ID,COMPANY_ID,MEMBER_ID,ORDER_ID,TRADE_ID,PAY_ID

    有对像或身份标识意义字段

    HASH_CODE,USERNAME,IDCARD_NO,EMAIL,TEL_NO,IM_NO

    索引慎用字段,

    需要进行数据

    分布及使用场

    景详细评估

    日期

    GMT_CREATE,GMT_MODIFIED

    年月

    YEAR,MONTH

    状态标志

    PRODUCT_STATUS,ORDER_STATUS,IS_DELETE,VIP_FLAG

    类型

    ORDER_TYPE,IMAGE_TYPE,GENDER,CURRENCY_TYPE

    区域

    COUNTRY,PROVINCE,CITY

    操作人员

    CREATOR,AUDITOR

    数值

    LEVEL,AMOUNT,SCORE

    长字符

    ADDRESS,COMPANY_NAME,SUMMARY,SUBJECT

    不适合建索引

    的字段

    描述备注

    DESCRIPTION,REMARK,MEMO,DETAIL

    大字段

    FILE_CONTENT,EMAIL_CONTEN

    四、如何知道SQL是否使用了正确的索引?
           简单SQL可以根据索引使用语法规则判断,复杂的SQL不好办,判断SQL的响应时间是一种策略,但是这会受到数据量、主机负载及缓存等因素的影响,有时数据全在缓存里,可能全表访问的时间比索引访问时间还少。要准确知道索引是否正确使用,需要到数据库中查看SQL真实的执行计划,这个话题比较复杂,详见SQL执行计划专题介绍。

    以下是执行计划获取方式:

     

    select SQL_TEXT,SQL_ID,OPTIMIZER_MODE,parsing_schema_name,LAST_ACTIVE_TIME from V$SQLAREA;

    select from table(dbms_xplan.display_cursor('gsyvkdr40w01r'));----gsyvkdr40w01r为SQL_ID

    五、索引对DML(INSERT,UPDATE,DELETE)附加的开销有多少?
           这个没有固定的比例,与每个表记录的大小及索引字段大小密切相关,以下是一个普通表测试数据,仅供参考:
           索引对于Insert性能降低56%
           索引对于Update性能降低47%
           索引对于Delete性能降低29%
           因此对于写IO压力比较大的系统,表的索引需要仔细评估必要性,另外索引也会占用一定的存储空间。

    1.2 只通过索引访问数据

          有些时候,我们只是访问表中的几个字段,并且字段内容较少,我们可以为这几个字段单独建立一个组合索引,这样就可以直接只通过访问索引就能得到数据,一般索引占用的磁盘空间比表小很多,所以这种方式可以大大减少磁盘IO开销。
          如:select id,name from company where type='2';
          如果这个SQL经常使用,我们可以在type,id,name上创建组合索引
          create index my_comb_index on company(type,id,name);
          有了这个组合索引后,SQL就可以直接通过my_comb_index索引返回数据,不需要访问company表。
          还是拿字典举例:有一个需求,需要查询一本汉语字典中所有汉字的个数,如果我们的字典没有目录索引,那我们只能从字典内容里一个一个字计数,最后返回结果。如果我们有一个拼音目录,那就可以只访问拼音目录的汉字进行计数。如果一本字典有1000页,拼音目录有20页,那我们的数据访问成本相当于全表访问的50分之一。

          切记,性能优化是无止境的,当性能可以满足需求时即可,不要过度优化。在实际数据库中我们不可能把每个SQL请求的字段都建在索引里,所以这种只通过索引访问数据的方法一般只用于核心应用,也就是那种对核心表访问量最高且查询字段数据量很少的查询。

    1.3 优化SQL执行计划

          SQL执行计划是关系型数据库最核心的技术之一,它表示SQL执行时的数据访问算法。由于业务需求越来越复杂,表数据量也越来越大,程序员越来越懒惰,SQL也需要支持非常复杂的业务逻辑,但SQL的性能还需要提高,因此,优秀的关系型数据库除了需要支持复杂的SQL语法及更多函数外,还需要有一套优秀的算法库来提高SQL性能。
          目前ORACLE有SQL执行计划的算法约300种,而且一直在增加,所以SQL执行计划是一个非常复杂的课题,一个普通DBA能掌握50种就很不错了,就算是资深DBA也不可能把每个执行计划的算法描述清楚。虽然有这么多种算法,但并不表示我们无法优化执行计划,因为我们常用的SQL执行计划算法也就十几个,如果一个程序员能把这十几个算法搞清楚,那就掌握了80%的SQL执行计划调优知识。

          推荐使用的SQL执行计划优化工具:Dell SQL Optimizer for Oracle

    2 返回更少的数据

    2.1 数据分页处理

    一般数据分页方式有:
    1、客户端(应用程序或浏览器)分页
          将数据从应用服务器全部下载到本地应用程序或浏览器,在应用程序或浏览器内部通过本地代码进行分页处理
          优点:编码简单,减少客户端与应用服务器网络交互次数
          缺点:首次交互时间长,占用客户端内存
          适应场景:客户端与应用服务器网络延时较大,但要求后续操作流畅,如手机GPRS,超远程访问(跨国)等等。
    2、应用服务器分页
         将数据从数据库服务器全部下载到应用服务器,在应用服务器内部再进行数据筛选。以下是一个应用服务器端Java程序分页的示例:
         List list=executeQuery(“select * from employee order by id”);
         Int count= list.size();
         List subList= list.subList(10, 20);
          优点:编码简单,只需要一次SQL交互,总数据与分页数据差不多时性能较好。
          缺点:总数据量较多时性能较差。
          适应场景:数据库系统不支持分页处理,数据量较小并且可控。
    3、数据库SQL分页
          采用数据库SQL分页需要两次SQL完成
          一个SQL计算总数量
          一个SQL返回分页后的数据
          优点:性能好
          缺点:编码复杂,各种数据库语法不同,需要两次SQL交互。
          oracle数据库一般采用rownum来进行分页,常用分页语法有如下两种:

    (1)直接通过rownum分页:

    select*from(

             select a.*,rownum rn from

                       (select*from product a where company_id=? orderby status) a

             whererownum<=20)

    where rn>10;

          数据访问开销=索引IO+索引全部记录结果对应的表数据IO
    (2)采用rowid分页语法

          优化原理是通过纯索引找出分页记录的ROWID,再通过ROWID回表返回数据,要求内层查询和排序字段全在索引里。

     

    createindex myindex on product(company_id,status);

    select b.*from(

             select*from(

                       select a.*,rownum rn from

                                (selectrowid rid,status from product a where company_id=? orderby status) a

                       whererownum<=20)

             where rn>10) a, product b

    wherea.rid=b.rowid;

           数据访问开销=索引IO+索引分页结果对应的表数据IO
           实例:
           一个公司产品有1000条记录,要分页取其中20个产品,假设访问公司索引需要50个IO,2条记录需要1个表数据IO。

     

    那么按第一种ROWNUM分页写法,需要550(50+1000/2)个IO,按第二种ROWID分页写法,只需要60个IO(50+20/2);

    2.2 只返回需要的字段

           通过去除不必要的返回字段可以提高性能,例:
           调整前:select * from product where company_id=?;
           调整后:select id,name from product where company_id=?;
           优点:
           1、减少数据在网络上传输开销
           2、减少服务器数据处理开销
           3、减少客户端内存占用
           4、字段变更时提前发现问题,减少程序BUG
           5、如果访问的所有字段刚好在一个索引里面,则可以使用纯索引访问提高性能。
           缺点:增加编码工作量
           由于会增加一些编码工作量,所以一般需求通过开发规范来要求程序员这么做,否则等项目上线后再整改工作量更大。
           如果你的查询表中有大字段或内容较多的字段,如备注信息、文件内容等等,那在查询表时一定要注意这方面的问题,否则可能会带来严重的性能问题。如果表经常要查询并且请求大内容字段的概率很低,我们可以采用分表处理,将一个大表分拆成两个一对一的关系表,将不常用的大内容字段放在一张单独的表中。如一张存储上传文件的表:
           T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE,FILE_CONTENT)
           我们可以分拆成两张一对一的关系表:
           T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE)
           T_FILECONTENT(ID, FILE_CONTENT)

           通过这种分拆,可以大大提少T_FILE表的单条记录及总大小,这样在查询T_FILE时性能会更好,当需要查询FILE_CONTENT字段内容时再访问T_FILECONTENT表。

    3 减少交互次数

    3.1 batch DML

           数据库访问框架一般都提供了批量提交的接口,jdbc支持batch的提交处理方法,当你一次性要往一个表中插入1000万条数据时,如果采用普通的executeUpdate处理,那么和服务器交互次数为1000万次,按每秒钟可以向数据库服务器提交10000次估算,要完成所有工作需要1000秒。如果采用批量提交模式,1000条提交一次,那么和服务器交互次数为1万次,交互次数大大减少。采用batch操作一般不会减少很多数据库服务器的物理IO,但是会大大减少客户端与服务端的交互次数,从而减少了多次发起的网络延时开销,同时也会降低数据库的CPU开销。

           假设要向一个普通表插入1000万数据,每条记录大小为1K字节,表上没有任何索引,客户端与数据库服务器网络是100Mbps,以下是根据现在一般计算机能力估算的各种batch大小性能对比值:

     单位:ms

    No batch

    Batch=10

    Batch=100

    Batch=1000

    Batch=10000

    服务器事务处理时间

    0.1

    0.1

    0.1

    0.1

    0.1

    服务器IO处理时间

    0.02

    0.2

    2

    20

    200

    网络交互发起时间

    0.1

    0.1

    0.1

    0.1

    0.1

    网络数据传输时间

    0.01

    0.1

    1

    10

    100

    小计

    0.23

    0.5

    3.2

    30.2

    300.2

    平均每条记录处理时间

    0.23

    0.05

    0.032

    0.0302

    0.03002

           从上可以看出,Insert操作加大Batch可以对性能提高近8倍性能,一般根据主键的Update或Delete操作也可能提高2-3倍性能,但不如Insert明显,因为Update及Delete操作可能有比较大的开销在物理IO访问。以上仅是理论计算值,实际情况需要根据具体环境测量。另外从测试角度来说,使用Batch也降低了并发性(毕竟Batch属于事务操作)。

    3.2 In List

           很多时候我们需要按一些ID查询数据库记录,我们可以采用一个ID一个请求发给数据库,如下所示:

           for:varin ids[] do begin

                    select*from mytable whereid=:var;

           end;
           我们也可以做一个小的优化, 如下所示,用ID INLIST的这种方式写SQL:

     

           select*frommytable whereidin(:id1,id2,...,idn);

     

           通过这样处理可以大大减少SQL请求的数量,从而提高性能。那如果有10000个ID,那是不是全部放在一条SQL里处理呢?答案肯定是否定的。首先大部份数据库都会有SQL长度和IN里个数的限制,如ORACLE的IN里就不允许超过1000个值。
           另外当前数据库一般都是采用基于成本的优化规则,当IN数量达到一定值时有可能改变SQL执行计划,从索引访问变成全表访问,这将使性能急剧变化。随着SQL中IN的里面的值个数增加,SQL的执行计划会更复杂,占用的内存将会变大,这将会增加服务器CPU及内存成本。
           评估在IN里面一次放多少个值还需要考虑应用服务器本地内存的开销,有并发访问时要计算本地数据使用周期内的并发上限,否则可能会导致内存溢出。

           综合考虑,一般IN里面的值个数超过20个以后性能基本没什么太大变化,也特别说明不要超过100,超过后可能会引起执行计划的不稳定性及增加数据库CPU及内存成本,这个需要专业DBA评估。

    3.3 设置Fetch Size

           当我们采用select从数据库查询数据时,数据默认并不是一条一条返回给客户端的,也不是一次全部返回客户端的,而是根据客户端fetch_size参数处理,每次只返回fetch_size条记录,当客户端游标遍历到尾部时再从服务端取数据,直到最后全部传送完成。所以如果我们要从服务端一次取大量数据时,可以加大fetch_size,这样可以减少结果数据传输的交互次数及服务器数据准备时间,提高性能。

           以下是jdbc测试的代码,采用本地数据库,表缓存在数据库CACHE中,因此没有网络连接及磁盘IO开销,客户端只遍历游标,不做任何处理,这样更能体现fetch参数的影响:

    String vsql ="select * from t_employee";

    PreparedStatementpstmt =conn.prepareStatement(vsql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);

    pstmt.setFetchSize(1000);

    ResultSetrs = pstmt.executeQuery(vsql);

    int cnt = rs.getMetaData().getColumnCount();

    Object o;

    while(rs.next()) {

        for(int i =1; i <= cnt; i++) {

           o = rs.getObject(i);

        }

    }

           测试示例中的employee表有100000条记录,每条记录平均长度135字节

           以下是测试结果,对每种fetchsize测试5次再取平均值:

    etchsize

     elapse_time(s

    1

    20.516

    2

    11.34

    4

    6.894

    8

    4.65

    16

    3.584

    32

    2.865

    64

    2.656

    128

    2.44

    256

    2.765

    512

    3.075

    1024

    2.862

    2048

    2.722

    4096

    2.681

    8192

    2.715

           Oracle jdbc fetchsize默认值为10,由上测试可以看出fetchsize对性能影响还是比较大的,但是当fetchsize大于100时就基本上没有影响了。fetchsize并不会存在一个最优的固定值,因为整体性能与记录集大小及硬件平台有关。根据测试结果建议当一次性要取大量数据时这个值设置为100左右,不要小于40。注意,fetchsize不能设置太大,如果一次取出的数据大于JVM的内存会导致内存溢出,所以建议不要超过1000,太大了也没什么性能提高,反而可能会增加内存溢出的危险。

           注:图中fetchsize在128以后会有一些小的波动,这并不是测试误差,而是由于resultset填充到具体对像时间不同的原因,由于resultset已经到本地内存里了,所以估计是由于CPU的L1,L2 Cache命中率变化造成,由于变化不大,所以笔者也未深入分析原因。

    3.4 使用存储过程

           大型数据库一般都支持存储过程,合理的利用存储过程也可以提高系统性能。如你有一个业务需要将A表的数据做一些加工然后更新到B表中,但是又不可能一条SQL完成,这时你需要如下3步操作:
           a:将A表数据全部取出到客户端;
           b:计算出要更新的数据;
           c:将计算结果更新到B表。
           如果采用存储过程你可以将整个业务逻辑封装在存储过程里,然后在客户端直接调用存储过程处理,这样可以减少网络交互的成本。
           当然,存储过程也并不是十全十美,存储过程有以下缺点:
           a、不可移植性,每种数据库的内部编程语法都不太相同,当你的系统需要兼容多种数据库时最好不要用存储过程。
           b、学习成本高,DBA一般都擅长写存储过程,但并不是每个程序员都能写好存储过程,除非你的团队有较多的开发人员熟悉写存储过程,否则后期系统维护会产生问题。
           c、业务逻辑多处存在,采用存储过程后也就意味着你的系统有一些业务逻辑不是在应用程序里处理,这种架构会增加一些系统维护和调试成本。
           d、存储过程和常用应用程序语言不一样,它支持的函数及语法有可能不能满足需求,有些逻辑就只能通过应用程序处理。
           e、如果存储过程中有复杂运算的话,会增加一些数据库服务端的处理成本,对于集中式数据库可能会导致系统可扩展性问题。
           f、为了提高性能,数据库会把存储过程代码编译成中间运行代码(类似于java的class文件),所以更像静态语言。当存储过程引用的对像(表、视图等等)结构改变后,存储过程需要重新编译才能生效,在24*7高并发应用场景,一般都是在线变更结构的,所以在变更的瞬间要同时编译存储过程,这可能会导致数据库瞬间压力上升引起故障(Oracle数据库就存在这样的问题)。

           个人观点:普通业务逻辑尽量不要使用存储过程,定时性的ETL任务或报表统计函数可以根据团队资源情况采用存储过程处理。

    3.5 优化业务逻辑

           要通过优化业务逻辑来提高性能是比较困难的,这需要程序员对所访问的数据及业务流程非常清楚。

           举个例子:12306网站的春运购票压力很大,可以通过业务优化来解决部分问题,比如按客流量分散,一方面从时间上分散(允许提前两个月订票,将购买压力分散到不同时间段),另一方面按客运段分布(按省市、客户段分布售票,避免票源集中发售),还可以按需求差异分类处理(比如按T、K、G、D车型分类,一等座、二等座、硬座、卧铺分类等)。

    3.6 使用ResultSet游标处理记录

           现在大部分Java框架都是通过jdbc从数据库取出数据,然后装载到一个list里再处理,list里可能是业务Object,也可能是hashmap。
           由于JVM内存一般都小于4G,所以不可能一次通过sql把大量数据装载到list里。为了完成功能,很多程序员喜欢采用分页的方法处理,如一次从数据库取1000条记录,通过多次循环搞定,保证不会引起JVM Out of memory问题。
           很多持久层框架(如iBatis)为了尽量让程序员使用方便,封装了jdbc通过statement执行数据返回到resultset的细节,导致程序员会想采用分页的方式处理问题。实际上如果我们采用jdbc原始的resultset游标处理记录,在resultset循环读取的过程中处理记录,这样就可以一次从数据库取出所有记录。显著提高性能。

         这里需要注意的是,采用resultset游标处理记录时,应该将游标的打开方式设置为FORWARD_READONLY模式(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY),否则会把结果缓存在JVM里,造成JVM Out of memory问题。以下代码示例:

    String vsql ="select * from t_employee";

    PreparedStatementpstmt =conn.prepareStatement(vsql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);

    pstmt.setFetchSize(100);

    ResultSetrs = pstmt.executeQuery(vsql);

    int col_cnt = rs.getMetaData().getColumnCount();

    Object o;

    while(rs.next()) {

             for(int j =1; j <= col_cnt; j++) {

                       o = rs.getObject(j);

             }

    }

           以上代码实际执行时间为3.156秒,而采用分页的方法处理实际需要6.516秒。性能提高了1倍多,如果采用分页模式数据库每次还需发生磁盘IO的话那性能可以提高更多。

    4 减少数据库服务器CPU运算

    4.1 使用绑定变量

           绑定变量是指SQL中对变化的值采用变量参数的形式提交,而不是在SQL中直接拼写对应的值。
           非绑定变量写法:Select * from employee where id=1234567
           绑定变量写法:
           Select * from employee where id=?

           Preparestatement.setInt(1,1234567)

           Java中Preparestatement就是为处理绑定变量提供的对像,绑定变量有以下优点:
           1、防止SQL注入
           2、提高SQL可读性
           3、提高SQL解析性能,不使用绑定变更我们一般称为硬解析,使用绑定变量我们称为软解析。
           第1和第2点很好理解,做编码的人应该都清楚,这里不详细说明。关于第3点,到底能提高多少性能呢,下面举一个例子说明:
           假设有这个这样的一个数据库主机:
           2个4核CPU 
           100块磁盘,每个磁盘支持IOPS为160
           业务应用的SQL如下:
           select * from table where pk=?
           这个SQL平均4个IO(3个索引IO+1个数据IO)
           IO缓存命中率75%(索引全在内存中,数据需要访问磁盘)
           SQL硬解析CPU消耗:1ms  (常用经验值)

           SQL软解析CPU消耗:0.02ms(常用经验值)

           假设CPU每核性能是线性增长,访问内存Cache中的IO时间忽略,要求计算系统对如上应用采用硬解析与采用软解析支持的每秒最大并发数:

    是否使用绑定变量

    CPU支持最大并发数

    磁盘IO支持最大并发数

    不使用

    2*4*1000=8000

    100*160=16000

    使用

    2*4*1000/0.02=400000

    100*160=16000

           从以上计算可以看出,不使用绑定变量的系统当并发达到8000时会在CPU上产生瓶颈,当使用绑定变量的系统当并行达到16000时会在磁盘IO上产生瓶颈。所以如果你的系统CPU有瓶颈时请先检查是否存在大量的硬解析操作。

           使用绑定变量为何会提高SQL解析性能,这个需要从数据库SQL执行原理说明,一条SQL在Oracle数据库中的执行过程如下图所示:

           当一条SQL发送给数据库服务器后,系统首先会将SQL字符串进行hash运算,得到hash值后再从服务器内存里的SQL缓存区中进行检索,如果有相同的SQL字符,并且确认是同一逻辑的SQL语句,则从共享池缓存中取出SQL对应的执行计划,根据执行计划读取数据并返回结果给客户端。

           如果在共享池中未发现相同的SQL则根据SQL逻辑生成一条新的执行计划并保存在SQL缓存区中,然后根据执行计划读取数据并返回结果给客户端。

           为了更快的检索SQL是否在缓存区中,首先进行的是SQL字符串hash值对比,如果未找到则认为没有缓存,如果存在再进行下一步的准确对比,所以要命中SQL缓存区应保证SQL字符是完全一致,中间有大小写或空格都会认为是不同的SQL。

           如果我们不采用绑定变量,采用字符串拼接的模式生成SQL,那么每条SQL都会产生执行计划,这样会导致共享池耗尽,缓存命中率也很低。

           一些无需使用绑定变量的场景:
           a、数据仓库应用,这种应用一般并发不高,但是每个SQL执行时间很长,SQL解析的时间相比SQL执行时间比较小,绑定变量对性能提高不明显。数据仓库一般都是内部分析应用,所以也不太会发生SQL注入的安全问题。
           b、数据分布不均匀的特殊逻辑,如产品表,记录有1亿,有一产品状态字段,上面建有索引,有审核中,审核通过,审核未通过3种状态,其中审核通过9500万,审核中1万,审核不通过499万。
           要做这样一个查询:
           select count(*) from product where status=?
           采用绑定变量的话,那么只会有一个执行计划,如果走索引访问,那么对于审核中查询很快,对审核通过和审核不通过会很慢;如果不走索引,那么对于审核中与审核通过和审核不通过时间基本一样;
           对于这种情况应该不使用绑定变量,而直接采用字符拼接的方式生成SQL,这样可以为每个SQL生成不同的执行计划,如下所示。
           select count(*) from product where status='approved'; //不使用索引(审核通过)
           select count(*) from product where status='tbd'; //不使用索引(审核未通过)

           select count(*) from product where status='auditing';//使用索引(审核中)

    4.2 合理使用排序

           Oracle的排序算法一直在优化,但是总体时间复杂度约等于nLog(n)。普通OLTP系统排序操作一般都是在内存里进行的,对于数据库来说是一种CPU的消耗,曾在PC机做过测试,单核普通CPU在1秒钟可以完成100万条记录的全内存排序操作,所以说由于现在CPU的性能增强,对于普通的几十条或上百条记录排序对系统的影响也不会很大。但是当你的记录集增加到上万条以上时,你需要注意是否一定要这么做了,大记录集排序不仅增加了CPU开销,而且可能会由于内存不足发生硬盘排序的现象,当发生硬盘排序时性能会急剧下降,这种需求需要与DBA沟通再决定,取决于你的需求和数据,所以只有你自己最清楚,而不要被别人说排序很慢就吓倒。
           以下列出了可能会发生排序操作的SQL语法:
           Order by
           Group by
           Distinct
           Exists子查询
           Not Exists子查询
           In子查询
           Not In子查询
           Union(并集),Union All也是一种并集操作,但是不会发生排序,如果你确认两个数据集不需要执行去除重复数据操作,那请使用Union All 代替Union。
           Minus(差集)
           Intersect(交集)
           Create Index

           Merge Join,这是一种两个表连接的内部算法,执行时会把两个表先排序好再连接,应用于两个大表连接的操作。如果你的两个表连接的条件都是等值运算,那可以采用Hash Join来提高性能,因为Hash Join使用Hash 运算来代替排序的操作。具体原理及设置参考SQL执行计划优化专题。

    4.3 减少比较操作

           我们SQL的业务逻辑经常会包含一些比较操作,如a=b,a<b之类的操作,对于这些比较操作数据库都体现得很好,但是如果有以下操作,我们需要保持警惕:
           Like模糊查询,如下所示:
           a like ‘%abc%’
           Like模糊查询对于数据库来说不是很擅长,特别是你需要模糊检查的记录有上万条以上时,性能比较糟糕,这种情况一般可以采用专用Search或者采用全文索引方案来提高性能。
           不能使用索引定位的大量In List,如下所示:
           a in (:1,:2,:3,…,:n)   ----n>20
           如果这里的a字段不能通过索引比较,那数据库会将字段与in里面的每个值都进行比较运算,如果记录数有上万以上,会明显感觉到SQL的CPU开销加大,这个情况有两种解决方式:
           a、将in列表里面的数据放入一张中间小表,采用两个表Hash Join关联的方式处理;
           b、采用str2varList方法将字段串列表转换一个临时表处理,关于str2varList方法可以在网上直接查询,这里不详细介绍。
           以上两种解决方案都需要与中间表Hash Join的方式才能提高性能,如果采用了Nested Loop的连接方式性能会更差。

           如果发现我们的系统IO没问题但是CPU负载很高,就有可能是上面的原因,这种情况不太常见,如果遇到了最好能和DBA沟通并确认准确的原因。

    4.4 大量复杂运算在客户端处理

           什么是复杂运算,一般我认为是一秒钟CPU只能做10万次以内的运算。如含小数的对数及指数运算、三角函数、3DES及BASE64数据加密算法等等。

           如果有大量这类函数运算,尽量放在客户端处理,一般CPU每秒中也只能处理1万-10万次这样的函数运算,放在数据库内不利于高并发处理。

    5 利用更多的资源

    5.1 客户端多进程并行访问

           多进程并行访问是指在客户端创建多个进程(线程),每个进程建立一个与数据库的连接,然后同时向数据库提交访问请求。当数据库主机资源有空闲时,我们可以采用客户端多进程并行访问的方法来提高性能。如果数据库主机已经很忙时,采用多进程并行访问性能不会提高,反而可能会更慢。所以使用这种方式最好与DBA或系统管理员进行沟通后再决定是否采用。
           例如:
           我们有10000个产品ID,现在需要根据ID取出产品的详细信息,如果单线程访问,按每个IO要5ms计算,忽略主机CPU运算及网络传输时间,我们需要50s才能完成任务。如果采用5个并行访问,每个进程访问2000个ID,那么10s就有可能完成任务。
           那是不是并行数越多越好呢,开1000个并行是否只要50ms就搞定,答案肯定是否定的,当并行数超过服务器主机资源的上限时性能就不会再提高,如果再增加反而会增加主机的进程间调度成本和进程冲突机率。
           以下是一些如何设置并行数的基本建议:
           如果瓶颈在服务器主机,但是主机还有空闲资源,那么最大并行数取主机CPU核数和主机提供数据服务的磁盘数两个参数中的最小值,同时要保证主机有资源做其它任务。
           如果瓶颈在客户端处理,但是客户端还有空闲资源,那建议不要增加SQL的并行,而是用一个进程取回数据后在客户端起多个进程处理即可,进程数根据客户端CPU核数计算。
           如果瓶颈在客户端网络,那建议做数据压缩或者增加多个客户端,采用map reduce的架构处理。

           如果瓶颈在服务器网络,那需要增加服务器的网络带宽或者在服务端将数据压缩后再处理了。

    5.2 数据库并行处理

           数据库并行处理是指客户端一条SQL的请求,数据库内部自动分解成多个进程并行处理,如下图所示:

           并不是所有的SQL都可以使用并行处理,一般只有对表或索引进行全部访问时才可以使用并行。数据库表默认是不打开并行访问,所以需要指定SQL并行的提示,如下所示:
           select /*+parallel(a,4)*/ * from employee;
           并行的优点:
           使用多进程处理,充分利用数据库主机资源(CPU,IO),提高性能。
           并行的缺点:
           1、单个会话占用大量资源,影响其它会话,所以只适合在主机负载低时期使用;
           2、只能采用直接IO访问,不能利用缓存数据,所以执行前会触发将脏缓存数据写入磁盘操作。
           注:
           1、并行处理在OLTP类系统中慎用,使用不当会导致一个会话把主机资源全部占用,而正常事务得不到及时响应,所以一般只是用于数据仓库平台或大数据处理平台。
           2、一般对于百万级记录以下的小表采用并行访问性能并不能提高,反而可能会让性能更差。

    最后介绍一款Oracle基准性能测试工具swingbench

           目前网络上开源的oracle基准测试工具主要是orabm和swingbench,由于orabm不支持oracle 11g版本,所以建议使用swingben进行基准压力测试。另外,swingbench还能对rac进行测试。swingbench是UK based oracle Database Solutions group开发的一个oracle压力测试工具,好像是官方废弃的一个项目,官方页面http://dominicgiles.com/swingbench.html 上可以下载最新的软件版本。swingbench可以运行在windows和linux平台(可视化环境,基于JDK)。

    下载地址:http://www.dominicgiles.com/downloads.html
    作者博客:http://www.dominicgiles.com/blog/blog.html
    文档地址:http://www.dominicgiles.com/Swingbench.pdf

    展开全文
  • 主要的数据库访问技术

    千次阅读 2018-05-31 18:54:44
    主要的数据库访问技术:ODBC(Open Database Connectivity开放数据库互联)作为一个访问不同数据库的公共接口

    主要的数据库访问技术:

          1.ODBC(Open Database Connectivity[开放数据库互联])为访问不同的数据库提供了一个公共的接口。ODBC使用SQL作为访问数据库的标准。这一接口提供了最大限度的互操作性,一个应用可以通过相同的代码访问不同的数据库。

          2.JDBC(Java Data Base Connectivity[java数据库连接])用于java程序链接数据库的标准方法,一种可以执行SQL的java API,可以为    多种关系型数据库提供统一访问,由java编写的类和接口实现。

          3.ADO.NET是微软在.net框架下开发设计的一组用于和数据库交互的面向对象的类库。ADO.NET提供了对关系型数据库、XML和应用程序数据的访问,允许和不同类型的数据源以及数据库进行交互。

          4.PDO(PHP Data Object)为PHP访问数据库定义了一个轻量级的、一致性的接口,他提供了一个数据访问的抽象层,无论使用什么数据库都可以通过一致的函数执行查询和获取数据。

    展开全文
  • 数据库访问接口》

    千次阅读 2018-02-04 11:00:06
    不同的程序设计语言会有各自不同的数据库访问接口,程序语言通过这些接口,执行SQL语句,进行数据库管理,主要的数据库访问接口有: ODBC(开放数据库互连) ODBC使用SQL作为访问数据的标准,这一接口提供了最大限度...
  • Cobar分布式关系数据库访问代理

    千次阅读 2020-10-24 08:41:58
    Cobar是阿里巴巴开源的一个分布式关系数据库访问代理,介于应用服务器和数据库服务器之间(Cobar也支持非独立部署,以lib的方式和应用程序部署在一起)。应用程序通过JDBC驱动访问Cobar集群,Cobar服务器根据SQL和分...
  • 数据库访问接口之ODBC详解

    万次阅读 2018-07-29 11:55:41
    ODBC实际上是一个数据库访问函数库,使应用程序可以直接操纵数据库中的数据。ODBC是基于SQL语言的,是一种在SQL和应用界面之间的标准接口,他解决了嵌入式SQL接口非规范核心,免除了应用软件随数据库的改变而改变...
  • xampp开启Oracle数据库访问支持

    千次阅读 2017-09-04 14:03:09
    xampp全家桶用来做开发测试甚是简单方便,但是默认配置并不支持oracle数据库的访问,最近想折腾一下单位老内网网站的前端,准备直接从数据库提信息,下面记录一下xampp开启oracle数据库访问支持的步骤: 先看一下xampp...
  • oracle数据库访问权限控制

    千次阅读 2017-08-22 11:35:33
    oracle数据库访问权限控制 如果我们的数据库部署在外网上,如果数据库不设置访问控制权限,别人可以通过sqlplus 用户名/密码@ip:端口号(默认1521)连接该数据库进行操作,造成数据不安全。权限设置通过配置ip设置...
  • VB.Net - 数据库访问

    千次阅读 2018-03-01 09:35:53
    VB.Net - 数据库访问应用程序与数据库通信,首先,检索存储在那里的数据,并以用户友好的方式呈现它,其次,通过插入,修改和删除数据来更新数据库。Microsoft ActiveX Data Objects.Net(ADO.Net)是一个模型,.Net...
  • 数据库访问的优化

    千次阅读 2016-05-04 13:39:53
    一、数据库访问优化的五个法则  在实际开发,我们主要是需要对SQL语句进行优化,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里?根据木桶原理可以知道,最慢的设备往往是性能瓶颈。...
  • 如何使用本地Oracle数据访问远程Oracle数据库。知道远程数据库的ip、数据库名、数据库用户名、密码、service_name(sid)。例如:我想将远程数据库中的一张表中的数据插入到本地数据库表中。如何实现?不希望使用...
  • Django 数据库访问性能优化

    千次阅读 2016-08-24 17:16:59
    在进行Django数据库访问性能优化之前,首先应该使用标准的数据库技术对其进行优化,比如给字段加索引,通过使用 django.db.models.Field.db_index 来给一个Django模型类的字段加索引,设置这个属性字段的Field.db_...
  • SQL语句实现跨数据库访问

    千次阅读 2018-10-18 20:51:09
    SQL语句实现跨数据库访问 第一步: 启用Ad Hoc Distributed Queries语句: exec sp_configure 'show advanced options',1 reconfigure exec sp_configure 'Ad Hoc Distributed Queries',1 reconfigure 附关闭Ad ...
  • 写个简单的测试程序测试数据库访问接口DBI,实现功能: 1 输入参数 数据库类型、IP、端口、用户名、密码、数据库名、查询语句 2 输出: 0 如果能正常执行1 数据库类型不支持2 IP、端口连接不上 3 数据库登录错误 4 ...
  • 数据库访问慢的几个原因

    千次阅读 2019-09-18 07:12:05
    数据库访问慢先测试登录数据库用conn连接时,如果速度很快,使用客户端或工具连接时慢,可以检查如下几点1.监听日志过大listener.org一般在路径:$ORACLE_HOME\diag\tnslsnr\机器名\listener\tracelsnrctl status中...
  • Laravel监听数据库访问、打印SQL

    千次阅读 2016-03-10 17:31:43
    监听数据库访问 打印sql
  • 面向程序员的数据库访问性能优化法则

    万次阅读 多人点赞 2010-12-06 20:08:00
    面向程序员的数据库访问性能优化法则   特别说明: 1、 本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识; 2、 本文许多示例及概念是...
  • 通用数据库访问DLL实现

    千次阅读 2015-05-12 09:44:30
    通用数据库访问模块 实现接口: 通过范型类来做所有操作的对象,来对应任何表结构的数据。这种通用类型只能对单表操作吧,不是很方便。 包装通用事务和通用数据库链接对象,便于对不通数据库兼容 ...
  • 携程开源数据库访问框架Ctrip DAL

    千次阅读 2016-10-11 09:15:13
    伴随这一过程的是如何管理数据库扩展,如何规范数据库访问,如何保护数据库投资,如何应对访问量增加,如何预防安全问题等一系列挑战。 作为国内在线旅游行业的翘楚,携程也曾经面对同样困扰。为了应对这些挑
  • 数据库访问控制

    千次阅读 2018-10-25 10:26:36
    首先查看数据库现有用户 root用户登录 mysql -uroot -p 查询用户列表 use mysql;select user,host from user; 查询完成之后就可以看到这样的用户表 创建一个新用户 create user 'yuu6'@'localhost' ...
  • 开源轻量级数据库访问框架

    千次阅读 2016-08-23 15:57:44
    本框架为开源框架,旨在简化用户的数据库操作,提供便捷的数据库访问服务而封装。该框架依赖于JDBC,并且基于原生JAVA SE框架的封装。框架对比对于经常进行数据库开发和JAVA EE开发的编程人员而言,其最先使用到的...
  • ASP.NET 系统支持数据库访问设计

    千次阅读 2016-02-24 17:21:20
    三种数据库对应有三套数据库访问类,为了方便组织代码,往往将读写一种数据库的类放到对应命名的文件夹下,代码结构大概如下: 业务逻辑层: 以上面的代码为例,业务逻辑层要调用数据访问层时,可以这样
  • 通用数据库访问接口IDBHelper

    千次阅读 2012-01-16 10:05:29
    在三层构架中,关于数据库访问层的设计一般有两种设计方法  一种是:不同数据库都对应着一个DAL层,并且这些DAL中的类实现于IDAL中的接口。并且每个DAL对应着一个DBHelper数据库操作辅助类。  第二种是:只有一...
  • 本文讲述如何通过Spring+Mybatis构建多数据库访问的架构,并采用多线程提升数据库的访问效率。 需要说明一下,这种方式只适合数据库数量、名称固定,且不是特别多的情况。针对数据库数量不固定的情况,后面...
  • 利用ADO.NET的体系架构打造通用的数据库访问通用类

    万次阅读 多人点赞 2011-07-25 00:52:53
    在之前周公曾写过针对不同数据库的数据库访问通用类,如针对SQLite的、针对Access的、针对Oracle的、针对SQL Server的。总结了这些通用类的通用方法,其实无非就是针对不同类型的数据库创建Connection、Command、...
  • 相关文章:.NET下使用Oracle数据库、数据库访问技术(上) 在上一篇文章中介绍了.NET下使用Oracle数据提供程序访问Oracle的方法以及较老的数据库访问方式,ODBC,DAO,RDO等。总的说ODBC的出现使得程序员不必在关注与...
  • VB远程数据库访问方法

    千次阅读 2008-11-02 01:10:00
    VB远程数据库访问方法阚志刚 马瑞民 袁文翠 摘 要 本文介绍了VB提供的四种访问远程数据库的方法:数据访问对象、远程数据访问对象、开放式数据库互连API函数和VBSQL API函数,并给出了每种方法的优缺点。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 202,230
精华内容 80,892
关键字:

数据库访问