用历史的眼光去看待现在的问题!

发布新日志

  • 男人频道

    2010-05-04 17:09:42

  • 关于 SQL SERVER 2000 网络服务未能打开

    2008-06-21 22:20:59

    今天在配置 Contineo  创建数据库时老是失败,提示检查 数据库连接字符串是否正确,后来才弄清原因是SQL Server未能打开网络服务,用端口查看器查看系统确实也没看到1433端口。

    在事件查看器中可查看到有以下错误:

    您正在运行的 Microsoft SQL Server 2000 或 Microsoft SQL Server 2000 桌面引擎(又称 MSDE)的版本包含已知的与 Windows 的 此版本一起使用时的漏洞。要减少计算机的漏洞,免受特定病毒 攻击,应该禁用 Microsoft SQL Server 2000、MSDE (或同时)的  TCP/IP 和 UDP 网络端口。要启用这些端口,您必须从 http://www.microsoft.com/sql/downloads/default.asp  安装修补程序,或 Microsoft SQL Server 2000 或 MSDE 的 最新 service pack。

    有关更多信息,请参阅在 http://go.microsoft.com/fwlink/events.asp 的帮助和支持

    原来SQL Server 的网络服务已被禁止了,需安装补丁程序。

    后来 更新了 SQL Server 2000 的SP4 补丁重启后才好的。

     

     

     

  • 安装 contineo 在线文档管理系统

    2008-06-21 22:07:25

    Contineo是一个基于网络的在线文档管理系统,使用这款系统可以帮助用户管理各种流行格式的文档。
    Contineo开发过程中就非常注重文档的本身特点和生命周期,并尽可能的方便用户开发、编辑和管理文档的过程。该软件同时也提供了搜索、发布等各种功能以满足用户的需求。它提供了两种文档共享方法,一种是在线直接发布,另外一种是通过电子邮件发送给指定用户。
    服务器端依赖:
    >=JRE-1.4.0
    管理功能包括:
    用户管理
    组管理
    搜索索引管理
    备份管理
    文档功能包括:
    通过HTTP添加文档
    下载文档
    编辑、删除文档
    版本管理
    下载控制(权限控制)
    目录压缩等
    支持的数据库类型包括:
    Oracle 8i/9i
    IBM DB2 UDB 8.1
    MS SQL Server 6.5/7.0/2000
    Informix Dynamic Server 9.2/9.3
    Sybase ASE 12.5
    MySQL 4.1/5.0
    PostgreSQL 7.x/8.x
    Firebird 1.5.x
    SAP DB 7.x
    HSQLDB 1.7

    首先 需要下载 contineo 的二进制 安装包(里面包含个 contineo.war文件),服务器选用 apache tomcat

    若jdk用的是1.6 那么 apache最好用 version 6

    若jdk用的1.5的那么 apache最好用 version 5

    1、 将 contineo.war 文件放到 apache/webapps目录下

    2、 修改 Apache Tomacat 目录conf下的文件 tomcat-user.xml

    增加一个admin角色:

    <role rolename="admin" />

    然后创建一个admin角色的用户:

    <user username="admin" password="secret" roles="admin"/>

    修改后的 tomcat-user.xml 文件至少包含以下信息:

    <?xml version='1.0' encoding='utf-8'?>

    <tomcat-users>

    <role rolename="manager"/>

    <role rolename="admin"/>

    <user username="admin" password="secret" roles="manager,admin"/>

    </tomcat-users>

    3、 在浏览器中输入:http://localhost:8080/contineo/setup (将有如下对话框弹出,输入上面配置中设置的用户名和密码)

    clip_image002

    4、 登录后 进行设置( 第一步 先设置工作目录)

    clip_image004

    5、 第二步 设置 数据库(第一种为contineo自带的一个非常简单的数据管理系统,第二种为其它数据库系统)

    clip_image006

    6、第三步 设置数据库( 在此处 选用 SQL Server2000 ,在此前先利用SQL server创建数据库,名称自定,此处以contineo为例)

    clip_image008

    7、创建成功后 如下图所示 contineo 安装成功,并自动创建用户admin 密码也为admin

    点击 click here 按钮即进入contineo系统

    clip_image010

    8、 进入 contineo系统 http://localhost:8080/contineo/login.iface?rvn=6

    用户admin 密码为admin

    clip_image012

     

  • Rich Internet Applications 的技术选项

    2007-09-02 11:36:37

    By Mr. Vaibhav V. Gadge (vaigadge@in.ibm.com), 软件工程师, IBM

    Web 应用程序就要进入下一级别了,Rich Internet Application (RIA) 可以极大地增强用户交互。在本文对 RIA 的概述中,您将学习如何将其应用于用户界面 (UI) 层。Web 开发人员和架构师可能对该领域里当前可用的几种常见技术 —— Laszlo、XUL、XForms、 Macromedia Flex 和 Dojo 的讨论特别感兴趣。本文还包括其他技术的链接。本文假设您相当了解传统的 UI 工具,比如 HTML 和 XML。

    Rich Internet Application (RIA) 超出了 HTML 提供的传统用户界面 (UI) 控件的标准有限集合,比如文本框、复选框或单选按钮。RIA 为用户提供了丰富得多的控件集合,以及一种更加高级的服务器交互机制。使用 RIA,当从浏览器提交数据时,用户不必刷新页面;他们可以仅刷新页面的一部分,具有更好的错误处理,等等。

    本文内容包括:

    RIA 概述

    术语 “Rich Internet Application” 已经出现几年了,但该概念还被称为:

    • 远程脚本
    • X Internet
    • 富 (Web) 客户机
    • 富 Web 应用程序

    Internet 是信息的巨大来源,许多技术在努力以高级和用户友好的方式改进 Web 上的信息传递和存储性能。在大多数 Web 应用程序中,大量处理发生在服务器端,只有用户交互发生在客户机端。从而使服务器承担了沉重的数据和处理负载,以及网络通信中不断增加的依赖性。

    传统的基于客户机-服务器的架构具有高的灵活性和丰富性,但随着 Web 的成长而日渐消亡。一个原因是缺乏客户机应用程序的一致性和标准化。现在,勿庸置疑,浏览器是已经被人们普遍接受的 Web 工具。但是,它缺乏智能处理。所以责任在于可以交付更丰富的用户体验并能在客户端进行简单处理的客户机应用程序。RIA 提供了设计更好、更快、更吸引人并更无限可用的用户体验的机会 —— 全部在浏览器中实现。

    致力于 Web 和 internet UI 层的开发人员通常在 UI 层上进行试验,尝试可以在最少外部支持下有效工作的各种 RIA 工具。但是,在多数情况下,浏览器需要一些支持以使插件、扩展或下载在浏览器内部无缝工作。

    本文讨论有助于为业务案例确定最佳 RIA 选择的工具和参数。本文不可能讨论 RIA 的所有因素,但我将重点介绍您在评估 RIA 技术时审核的一些重要特性。

    评估内容

    评估 RIA 技术时,需要考虑下列因素:

    UI 丰富性
    开发 UI 时有多少基本的、开箱即用的 UI 小部件或控件可以使用?可以如何使用这些控件进行数据绑定和事件绑定?新控件应易于使用,并易于插卸。一些 RIA 技术提供了添加丰富性的简单方法和信息更丰富的可视体验,比如页面中的动画 API。例如,为了确保用户仅点击某个按钮一次,可以将此按钮做成动画以从视图中移出。
    复杂性
    开发人员已经使用现有的基于页面的模型很多年了,因为它简单易用,但是可能很笨重。RIA 技术必须易于使用、构建和扩展。它还应该与现有 Web 技术相互操作。
    灵活性和组件化
    与不同中间件组件协作的灵活性非常重要。协作应该能够容易地组合和扩展,以创建新的自定义小部件。创建自定义小部件之后,就可以在应用程序中重用它们。
    刷新页面

    刷新页面的一块而不是整个页面有非常显著的好处,因为它直接依赖于网络流量。刷新一块使得应用程序更快、更可用并使用户具有更好的视觉体验。它还有助于更好地管理错误。

    假设用户在网页上执行一个操作或第一个任务,并且数据在后台提交给服务器。然后用户在同一页面上继续执行另一个任务。同时,来自第一个任务的反馈已经返回并更新同一页面的某个部分。因此,如果这样设计网页,则会使工作和任务更有效率。

    安全性
    采用 RIA 时,确保与传统应用程序相比不会增加安全性威胁。一定要清楚围绕服务器通信或下载在客户机上的浏览器插件和扩展的安全性。
    对基本 Web 范例的支持
    技术应支持当今 Web 应用程序中涉及的基本 Web 范例,比如国际化、用户设备独立、浏览器独立和对上载和下载功能的二进制文件传输支持。甚至技术的成熟度也很重要。
    工具
    检查以集成开发环境 (IDE) 形式可供开发人员使用的工具,以及单元测试和调试支持。工具可以是带有现有编辑器或受支持编辑器的插件。
    可用性
    用户期望浏览器应用程序使用常用的浏览器功能。具体来说,保存图片、Ctrl+F 以搜索页面上的内容以及复制粘贴等功能不能在基于 Flash 的解决方案中工作。以人机交互 (HCI) 原理设计您的 RIA 可用性





    回页首


    UI 技术

    本节讨论当前 UI 技术提供的一些不同选项。

    Laszlo

    Laszlo 是领先的开放源码平台,用于在 Web 中使用 Flash 来开发和交付 RIA。Flash 播放器最初具有一个小插件以在浏览器中运行 Flash 文件。因为其高可靠性和兼容性,它被扩展用于创建闪烁的动画图片。后来的版本合并了一些重要的脚本兼容性、与服务器的数据交换,Flash 6 添加了双向音频和视频通信。

    Laszlo 已经扩展了该丰富性,使用脚本语言来生成 Flash 并交付给浏览器。它提供了一个用于构建 RIA 的开发源码 XML 本地平台。

    什么是 XPath?
    XML Path Language 是 W3C 推荐的语言,设计用于寻址 XML 文档中的信息。XPath 的主要目的在于导航 XML 文档中的任何节点和属性。

    它只需要在任何浏览器上安装 Flash 5.x+。脚本以一种叫做 LZX 的基于 XML 的语言编写。LZX 是一种面向对象的基于标记的语言,使用 XML 和 Javascrīpt 语法创建动态生成的 Flash 文件。服务器上的 LZX 编译器编译 LZX 文件并将 Flash 发送到浏览器中。实际的数据交换是以 XML 形式进行的,LZX 控件使用 XPath 来表示 XML。事件也很容易与控件绑定。每个控件定义一组可以从父事件继承事件的事件。清单 1 中的示例展示了如何使用事件。


    清单 1. 示例 simplelaszlo.lzx

    				
    <canvas width="500" height="80">
    <view>
         <text align="center" valign="middle">Hello, World!</text>
         <button >Update
    <method event="onclick">
     Debug.write("Button pressed");
    </met>
    </button>
    </view>
    </canvas>

    您将发现 Laszlo 易于学习、开发新组件、组件化并与任何 Web 应用程序集成。与其他 RIA 工具相比,它具有丰富的组件库。

    LZX 能够让 HTTP 和 Web 服务使用 SOAP 和 RPC 协议在后台请求服务器,而无需刷新页面。插件已经就绪,可以将任何 Web 应用程序文件与 Laszlo 库集成。当前,基于 Eclipse 的 IDE 可供开发使用。还有一些工具可用于在客户端的 LZX 中进行调试。有趣的是,它们还提供了 Lzunit 框架以用于测试 Laszlo 应用程序。

    最近,Laszlo 宣布了支持使用相同的现有框架将应用程序以 DHTML 交付给浏览器。这使您可以选择配置时希望将应用程序交付为 DHTML 还是 Flash。Laszlo 还扩展了对 Ajax 社区和多个设备交付的支持。

    图 1 展示了 Laszlo 和 Dojo 的示例。


    图 1. 用 Laszlo 和 Dojo 创建的 RIA 图片
    Laszlo、Dojo 演示图片

    XUL

    XML 用户界面语言 (XUL) 是 Mozilla 的基于 XML 的跨平台语言,用于描述应用程序的用户界面。它提供了可用于页面中的现成组件库。目前,它仅应用于基于 Gecko 的浏览器中,比如 Mozilla Firefox 或 Netscape 6 以上版本。

    XUL 使用基于 XML 的标记语言描述用户界面控件。它提供了各种流行的富 Internet 控件,比如菜单、选项卡、树和弹出菜单。XUL 使用文档对象模型 (DOM) 存储节点树。加载了所有 XUL 文件之后,XUL 将所有标记解析并转换为层次文档结构的节点。然后可以使用此 DOM 结构、DOM 结构的方法以及 XUL 函数提供的其他方法来检查并修改数据。您始终可以从 Javascrīpt 访问并操作 DOM,并使之像典型的 HTML 控件一样易于处理。每个控件和每个节点都具有多个属性来定义其外观和结构。

    从远程位置访问时,浏览器像处理 HTML 或其他浏览器内容一样处理 XUL 文件。但是,当它们作为扩展而本地安装在其 chrome 系统的浏览器中时,条目将收到访问系统和书签的特殊权限。在这种情况下,它可以执行其他的特权操作。

    Mozilla 浏览器本身也是一组软件包,其中包括 XUL 文件、Javascrīpt 和样式表,但它是相当大的而且非常复杂的扩展。

    XUL 使用 eXtensible Bindings Language (XBL) 进行绑定。每个控件可以使用 Mozilla 的 XBL 被绑定。XUL 使用 RDF 格式,可用于存储资源。可以使用其他格式的数据,并从中创建 RDF 数据,该数据将绑定到 XUL 格式。

    因为 XUL 类似于 XML 文件,所以可以使用 IDE 的任何文本编辑器或 XML 编辑器。因为相同的底层代码处理所有 XUL 文件、HTML 和 SVG,所以可以使用 CSS 属性设置 XUL 文件的样式。它对定位具有内置支持,因为所有文本内容在浏览器中是保持分离的。

    皮肤 在 Mozilla 中由 CSS 文件组成,定义浏览器的用户界面。可以为不同的外观修改和创建皮肤,而无需更改代码。它类似于通过添加功能来扩展浏览器 API 的功能。

    如果在 Mozilla Firefox 中运行 清单 2 中的文件,它将呈现一个文本框和按钮。


    清单 2. 示例 simplexul.xul

    				
    <?xml version="1.0"?>
    <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
    <window id="example-window" title="Example 2.4.1"
            xmlns:html="http://www.w3.org/1999/xhtml"
            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <label control="label" value="Enter some text"/>
    <textbox id="textid"/>
    <button id="yes" label="Yes"/>
    </window>

    XForms

    XForms 1.0 提供了一种新的用于联机交互的平台独立标记语言。W3C 已经出现了用于实现 XForms 的规范,而且 XForm 被认为是 HTML 形式的继任者。

    XForms 独立于表示设备。无需对传统浏览器、PDA 移动电话、语言浏览器、甚至一些更奇怪的新兴客户机(比如 instant messenger)进行任何更改,就可以传递 XForms。这使得 XForms 成为更吸引 RIA 的工具。

    在 XForms 中,实际数据(XML 表单定义)与表单表示分离。这种设备独立的 XML 表单定义叫做 XForms 模型,可以用于许多标准的或专用的用户界面。

    XForms 用户界面提供了一组标准的可视控件,旨在于替换当今的 XHTML 表单控件。它们可用于 XHTML SVG 或其他组、语言浏览器组中,还可以独立开发 XForms 的用户界面组件。XForms 模型被引用在每个 XForms 控件中以呈现数据。它遵循 XPath 以引用 XML 中的元素。提交数据时,它只能提交已填充的 XML 数据模型。

    XML 事件
    XML 事件 是一种 XML 语言,能够一致地将事件监听器和关联的事件处理程序与 DOM 事件集成。当事件发生时,它被通过文档树路径分配给元素(目标),并可以再次传递回树中。观察者可以响应路径中的事件。

    XForms 使用 XML 事件来处理事件和动作。XML 事件指定事件、观察者和处理程序。正如 清单 3 所示,DOMActivate 是事件,消息元素是处理程序,父触发器是观察者。

    可以将 XForms 与 AJAX 集成。当前,在 W3C 中,可以找到 20 多个 XForms 示例实现。许多供应商,其中包括 IBM,已经开发了 XML 的 XForms 引擎(参阅 参考资料 中的 XML Forms Package)。Mozilla 已经宣布在 Mozilla 运行的所有平台上支持 XForms。要查看 XForms 实现的优秀示例,请参阅 参考资料

    清单 3 展示了一个简单的 XForms 示例,显示了一个用 FormFaces™ 实现呈现的文本框和按钮。


    清单 3. 显示用 FormFaces 实现呈现的文本框和按钮的 XForm

    				
    <!DOCTYPE  html PUBLIC "-//W3C//DTD XHTML 1.0//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:form=http://www.w3.org/2002/xforms
    xmlns:ev="http://www.w3.org/2001/xml-events"  xml:lang="en">
      <head>
        <title>Simple example</title>
          <link rel="stylesheet" type="text/css" href="xforms.css" />
          <scrīpt type="text/javascrīpt" src="../../formfaces.js"></scrīpt>
          <form:model>
          <form:instance>
            <data xmlns="">
              <greeting>Hi there!</greeting>
            </data>
          </form:instance>
        </form:model>
     </head>
     <body>
       <form:input ref="greeting" incremental="true">
        <form:label>Greeting:</form:label>
       </form:input>
    	<form:trigger>
    	<form:label>Trigger</form:label>
    	<form:message level="modal" ev:event="DOMActivate">You clicked 
    	   button</form:message>
      </form:trigger>
      </body>
    </html>

    Dojo

    Dojo 是用 JavaScrip 编写的开放源码 DHTML 工具包。Dojo Toolkit 提供了一组核心库,和一组丰富的不同的软件包库,每个库提供特定的函数。Dojo 提供较低级的 API 来编写可移植的 Javascrīpt 并简化复杂的脚本。可以很容易很快地原型化交互小部件和动画转换。它提供了事件系统、I/O 软件包和一般语言增强的库。可以用 Dojo 编写脚本,并根据您的需要包括任意多个可用的 API。

    Dojo 还提供了一组可直接用于任何应用程序中的小部件库。可以使用其中一些核心小部件作为 UI 控件,比如菜单小部件、选项卡集、树小部件等等。还有一般函数,比如布局小部件、日期选择器、SVG 小部件等等。

    Dojo 基于单个标记语言构建,提供了声明和使用响应 DHTML 界面组件的简单方法。清单 4 展示了一个简单的 Dojo 组件示例,它是 HTML 页面中一个面向用户的特殊按钮。


    清单 4. 示例 dojosample.html

    				
    <button dojoType="Button2" widgetId="helloButton">Hello World!</button>
    You need to include the Dojo widgets library that is required in your HTML page.
    <scrīpt type="text/javascrīpt">
    	  dojo.require("dojo.widget.*");
          dojo.require("dojo.widget.Button2");
    </scrīpt>	

    Dojo 工具包还包括一些调试选项。AJAX Toolkit Framework (ATF) 可用作功能强大的 IDE。这是 IBM 的 Emerging technology Toolkit (ETTK) 的一部分,是一组特殊的新兴技术。ATF 主要基于 Eclipse Web 工具项目,允许支持 DOM 浏览、Javascrīpt 调试等等。

    最近,Dojo Foundation 宣布了与 Laszlo 的合作协议。按照该协议,您可以在 Laszlo 的开放源码项目中使用 Dojo Toolkit。同样,Laszlo 将将库贡献给 Dojo Foundation,从而促进开放源码社区的发展。

    Macromedia Flex

    Macromedia Flex 是另一种基于 Flash 的用户界面。它提供位于应用服务器顶层的 Flex 表示服务器,并从该服务器动态生成 Flash 文件,然后交付给浏览器。这些 Flash 文件在浏览器的 Flash 播放器内部执行,并允许用户交互、执行操作、甚至生成 SOAP、HTTP 或 AMF 请求以连接回服务器。

    布局和 UI 组件在一种基于 XML 的语言 MXML 中定义。Flex 为可视组件、容器以及远程服务对象和数据模型提供了丰富的 MXML 扩展类。它还与控件进行数据绑定,并访问服务器端数据。

    ECMA 脚本语言 (Actionscrīpt 2) 嵌入在 MXML 中以处理事件、系统事件或构造复杂的数据模型。这是一种面向对象的语言,类似于 Javascrīpt 和 ECME 脚本。与 XForms 一样,Flex 保持数据模型、数据表示、数据验证器和数据服务分离(类似于 MVC 样式)。

    到达 MXML 的所有请求都通过 Flex 编译器进行处理,该编译器编译 MXML 并生成 SWF,然后将其高速缓存,直到它被修改并最终交付给浏览器为止。

    任何 XML 编辑器都可用于编写 MXML 脚本,但 Macromedia 还提供了一个特殊的 IDE 进行 Flex 应用程序开发,叫做 Flex Builder 1.5。它的优点是与 Flex 服务器集成。它还提供了一些组件,允许连接服务器、执行正常的 HTTP 调用、连接远程 Java™ 对象并从浏览器本身与 Web 服务交互。它可以与现有的 J2EE 和 .NET 应用程序模型集成。

    清单 5 展示了 Macromedia Flex 代码的一个示例。


    清单 5. Macromedia Flex 代码示例

    				
    <?xml version="1.0"?>
    <mx:Application xmlns:mx="http://macromedia.com/2003/mxml">
    <mx:Form label="Employee Information">
          <mx:FormItem label="First Name">
             <mx:TextInput id="firstName" />
          </mx:FormItem>
    </mx:FormItem>
    </mx:Form>
    <!-- The myEmployee data model. -->
    <mx:Model id="myEmployee">
       <name>
          <first />
          <last />
       </name>
       <department />
       <email />
    </mx:Model>
    mx:Binding source="firstName.text" destination="myEmployee.name.first" />
    </mx:Application>	

    Macromedia Flex 看起来类似于 Laszlo。二者都是丰富的功能强大的基于 Flash 的应用程序。Laszlo 位于 Flash 引擎外,所以性能可能有所欠缺,但它具有其他优点。





    回页首


    工具比较

    下表比较了上文讨论过的五种技术以及 Altiolive(一种丰富的企业应用程序)。


    表 1. 工具比较

    技术 浏览器技术 脚本 丰富性 亮点
    Laszlo Flash、XML LZX 文件+Javascrīpt 易于学习,丰富
    Mozilla XUL XUL 语言 XUL 文件+Javascrīpt 依赖浏览器,功能强大
    XForms Xform 取决于实现 限于一定程度 设备中立,遵循 W3C
    Dojo Javascrīpt HTML+Javascrīpt 限于一定程度 基于 Javascrīpt。正在成长,可适应。
    Macromedia Flex Flash、XML MXML 文件 非开放源码。Macromedia 的专有工具。
    Altiolive Applet、XML Java 限于一定程度 http://www.altio.com/





    回页首


    其他技术

    我们已经讨论了五种技术,当然还有其他一些技术。许多公司使用各种技术提供了非常特别的 RIA 原型。尽管一一讨论这些技术超出了本文范围,但下面这些技术值得一看:

    • Backbase —— 开发和销售帮助创建 AJAX 应用程序的软件。
    • Netvibes —— 自定义 Web 主页解决方案的免费服务。
    • Zimbra —— 下一代企业消息传送和协作的开放源码服务器和客户机技术。
    • Protopage —— 免费个人起始页面。
    • Nexaweb —— 用于绑定和部署 Enterprise Internet Application 的平台。
    • altio —— 浏览器中丰富的企业应用程序。





    回页首


    结束语

    本文介绍了 RIA,讨论了当前的 UI 技术,并推荐了其他技术。我希望工具比较将帮助您根据需要作出一个正确的选择。每种技术都有不同的优点,从而基于您的需要为开发人员提供了丰富的控件集合。

    本文讨论的技术为用户带来一些新奇的东西,并提供了更丰富的用户体验。您现在可以跨越浏览器并呈现给 PDA、跨平台的移动设备,并用音频、视频、图像和动画来丰富用户体验。RIA 几乎包含了 XML,因此 XML 无疑是优胜者。

    将来,我预计 RIA 将会在 Web UI 转换到下一级别中扮演重要的角色,并帮助准备支持 Web 2.0。



     

    参考资料

    学习


    获得产品和技术

    • Dojo 工具包:使用该 Javascrīpt 工具包加速您的 Web 开发。

    • Mozilla Firefox:设置浏览器以运行 XUL 文件。它还附带 Javascrīpt Debugger 扩展以帮助进行 Javascrīpt 调试。

    • Ajax Toolkit Framework:从 Eclipse Web 工具中,尝试着将它作为 Dojo 的 IDE 使用。

    • XML Forms Package:可从 alphaWorks 获得这些 XForms 引擎。

    • IBM 试用软件:使用可以直接从 developerWorks 下载的软件构建您的下一个开发项目。


    讨论



     

    关于作者

    Vaibhav V. Gadge 照片

    Vaibhav V. Gadge 是位于印度 Bangalore 的 IBM Software Lab 的一名软件工程师。他目前效力于 Websphere Product Center 的 Portal 团队。他是 Java 认证专家,具有多个平台上 Java、J2EE 和基于 Web 技术方面的大约五年的技术经验。他拥有从 Nagpur University 获得的电子工程学士学位。可以通过 vaigadge@in.ibm.com 与 Vaibhav 联系。

     

  • 在LoadRunner中实现对WebLogic的监控

    2007-04-08 22:20:45

    操作步骤:

    获得 LoadRunner Weblogic JMX Monitor ”。

    Controller 计算机上安装 Java 1.4 (如: j2re-1_4_2 )。

    为监控用户设置 管理员权限 ,以便监视 MBean MBean 是一个包含性能数据的容器)。

        用户名: weblogic

        码: weblogic

        Weblogic 端口号: 8001

    Weblogic 服务器加载类。

        weblogic.jar 文件从应用程序服务器安装文件夹(在 lib 文件夹中)复制到 < LoadRunner

    文件夹 >\classes 目录下。

    < LoadRunner 根文件夹 >\classes 目录下名为“ jmxri.jar ”的文件重命名为任意其它的文件

    名。(如:更名为“ jmxri_bak.jar ”) (或者移到其它目录,总之不要放在 classes 目录下)

    修改 < LoadRunner 根文件夹 >\ dat \monitors 目录下的 weblogicmon.ini

        [WebLogicMon]

        JVM=javaw.exe -Xms 64M -Xmx 256M ( JVM=javaw.exe)

    JavaVersion= 1.4.2

    (注意:此处的 JVM JavaVersion 一定要是 WebLogic 所使用的 JDK ,同时 contoller 所在机器上的 JVM 也需要有与之对应版本的 JVM 温馨提醒:如果 controller 所在机器上的存在多个 JDK ,此时要特别注意把路径指对。如 JVM=C:\Java\bin\JDK1.4.2\javaw.exe

        其余内容不作修改,保存修改后的配置文件。

    在“ Weblogic JMX Monitor 中添加需要的监控度量。

        Add Machine 128.32.99.113:7001 (端口号要加上!) UNIX

        Login Information weblogic / weblogic

     

    (以下步骤可以不执行)

    Weblogic 用户权限的设置

    设置用户权限,请执行下列操作:

    1 )打开 WebLogic 控制台( http://< 主机 : 端口 >/console )。 端口: 8001

    2 )在左侧的树中,选择“安全性” > ACL ”。

           如果正在使用 WebLogic 6.1 控制台,单击屏幕右侧的“新建 ACL... ”。

    3 )在“新建 ACL 名”框中,键入 weblogic.admin.mbean ,并单击“创建”。

           如果正在使用 WebLogic 6.1 控制台,请单击屏幕右侧的“添加新权限 ... ”。

    4 )在“新建权限”框中(或在 WebLogic 6.1 控制台的“权限”框中),键入 access 。在

    WebLogic 6.0 控制台中,单击“创建”。

    5 )在“用户”框和“组”框中,输入用于监视的任何用户或组的名称。

    6 )在 WebLogic 6.0 控制台中,单击“授予权限”。在 WebLogic 6.1 控制台中,单击“应用”。

  • 他乡终于遇故知

    2007-01-13 12:54:47

    今天最高兴的就是收到了刘升了消息!昨晚刚与他在QQ上留了言,没想到今天就在QQ上见到他了!可喜的是他一切都好!他现在在做一份照看棋牌室的工作,收入虽然不高但还过得去。我很想让他去接受个培训,走技术道路!我认为他很适合做技术的。如果一切OK的话明天我们就可以见面了!希望明天能见到他!
  • 每日构造与冒烟测试

    2007-01-06 13:26:46

    作者:Steve McConnell 来源:不详 http://www.csai.cn 2005年12月27日

      如果你想创建一个只包含一个源程序文件的简单程序,那么你只需要编译、连接那一个文件就可以了。如果是一个团队项目组,有着许多甚至上千个源程序文件,那么要创建一个可执行程序的过程就变得更复杂、更耗时。你必须用各种各样的组件将程序逐步建立起来。
      在微软或其它一些软件公司中惯例是:每日构造并做“冒烟测试”。每天都对已完成的源程序进行编译,然后连接组合成可执行的程序,并做“冒烟测试”,以简单的检查该执行程序在运行时是否会“冒烟”。
      带来的好处
      虽然这是一个非常简单的过程,但却有非常重要的意义:
      1、能最小化集成风险
      项目组可能遇到的一个很大的风险是,项目组成员根据不同的系统功能各自开发不同的代码,但是当这些代码集成为一个系统的时候,也许系统完成不了预期的功能。这种风险的发生取决于项目中的这种不兼容性多久才被发现,由于程序界面已经发生了变化,或者系统的主要部分已经被重新设计和重新实现了,相应的排错工作将非常困难和耗时。极端情况下,集成的错误可能回导致项目被取消掉。每日构造和冒烟测试可以使这种集成错误变得非常小,而且便于解决,防止了很多集成问题的产生。
      2、能减小产品低质量的风险
      这种风险是和集成不成功、集成出错相关联的。每天对集成的代码做一些少量的冒烟测试,即可杜绝项目中那些基本的质量问题。通过这种方式,使系统达到一种周知的良好状态,维护这样的系统可以防止系统逐步恶化到耗费大量时间排查质量问题的地步。
      3、能简单化错误诊断
      当系统每天都进行build和测试时,系统任何一天发生的错误都能够变得十分精细,便于排查。比如在17日系统还运行正常,18日就出错了,那么只需要检查这两次build之间的代码变化就可以了。
      4、能极大鼓舞项目组的士气   
      看到产品的不断成长,能够极大的鼓舞项目组的士气,有时甚至不管这个产品到底用来做什么。开发人员可能会为系统显示了一个矩形而感到激动。通过每日构造,产品每天进步一点,保证项目士气的持续高涨。
      进行每日构造和冒烟测试
      虽然说这是一个简单枯燥的活,每天进行build,每天进行测试,但也有着一些值得注意的细节:  
      1、每天坚持
      每日构造,最重要的就是“每日”。如Jim McCarthy所说,把每日构造看作是项目的“心跳”,没有“心跳”的话,项目也就死了(Dynamics of Software Development, Microsoft Press, 1995)。Michael Cusumano and Richard W. Selby描述了另外一种隐含的比喻,把每日构造比作项目的“同步脉冲”(Microsoft Secrets, The Free Press, 1995)。不同开发人员写的代码在他们的“脉冲”之间肯定都会存在“同步”的差异,但是必须有这样一个“同步脉冲”,使得这些代码能够组合为一个整体。当项目组坚持每天把这些不同的“脉冲”组合到一起的时候,开发人员脱离整体的情况就会得到极大程度的杜绝。
      有些项目组把这一过程简化为“每周build一次”。这样带来的问题是,某一次build失败后,可能要回溯好几周才能找到原因。如果这种情况发生的话,已经得不到经常build带来的好处了。
      2、严格检查每一次build
      要保证每一次build的成功,就必须保证build后的结果(也可称为build)是可以正常运行的,如果build不可运行,那么本次build被认为是不成功的,同时应该将修复此次build的工作提高到项目组最高级别来处理。
      对于如何衡量一个build,每一个项目组都会定义一些自己的标准,这些标准需要设定一个严格的质量级别来处理那些特别严重的缺陷,同时也需要具有一定的伸缩性来忽略掉那些微不足道的缺陷,一些不适当的关心也许会使整个过程举步为艰。
      一个好的build起码应该具备以下条件:
      ●能够成功编译所有的文件、库,以及其它相关组件;
      ●能够成功链接所有的文件、库,以及其它相关组件;
      ●不能存在任何使得系统无法运行或者运行出错的高级别故障;
      ●当然,必须通过冒烟测试
      3、每天进行冒烟测试
      冒烟测试应该是对整个系统流程从输入到输出的完整测试。测试不必是面面俱到的,但是应该能够发现系统中较大的问题。冒烟测试应该是足够充分的,通过了冒烟测试的build就可以认为是经过充分测试、足够稳定的。
      不进行冒烟测试的build是没有太大价值的。冒烟测试就像一个哨兵,在阻止着产品质量恶化和集成问题的产生,不进行冒烟测试,每日构造可能会变成浪费时间的练习。
      冒烟测试必须随着系统的扩充而扩充。最初,冒烟测试可能是非常简单的,比如验证系统是否会打印“Hello World”,随着系统功能的扩充,冒烟测试需要越来越充分。最初的冒烟测试也许只需要几秒钟来执行,逐渐地,测试可能会花费30分钟,1小时,甚至更长。
      4、建立一个专门的build小组
      在很多项目组,维护每日构造,并更新冒烟测试用例,会耗费一个人工作的大部分时间。因此在一些大的项目中,这项工作独立成不止一个人来完成的全职工作。比如在 Windows NT 3.0的研发中,就有一个由四个全职人员组成的专门的build小组(Pascal Zachary, Showstopper!, The Free Press, 1994)。
      5、为build增加修订,如果这样做有意义的话
      一般开发人员不会每天都经常向系统中快速的增加实际的代码,通常是每隔几天,他们在开发好完成某个功能的一套代码以后,然后集成到整个系统中。
      6、规定一些导致build失败的惩罚措施
      很多执行每日构造的项目组都会规定一些惩罚措施,来惩罚那些导致build失败的行为。从最开始,项目组成员就清楚的知道,build的正常执行是项目组的头等大事。一个失败的build是项目组的意外,无法成为项目组工作的准则。必须坚持:导致build失败的同事,必须停下手中的工作,首先来解决build失败的问题。如果一个项目组的build经常失败的话,久而久之的,再来谈build的正确性就没有意义了。
      有种轻松的惩罚措施,能够突出解决问题的优先性。Some groups give out lollipops to each "sucker" who breaks the build. This developer then has to tape the sucker to his office door until he fixes the problem. 有些项目组会惩罚犯错的同事戴上山羊角,或者向一个项目基金捐献5块钱。
      有些项目组对此的惩罚就有点残酷了。微软的开发人员,在一些知名度很高、很重要的产品如Windows NT,Windows 95,Excel等产品后期研发中,被要求随时带着寻呼机,如果你的代码导致build失败的话,即使是凌晨3点钟,也会要求你立即来处理这个问题。
      7、即使在压力下也需坚持每日构造和冒烟测试
      当项目进度的压力越来越大时,维护每日构造的工作看起来有些浪费时间,但是恰恰相反。在压力之下,开发人员丢掉一些平时的规定,会采用一些设计和实现的捷径,这在平时压力较小的环境下一般时不会用的。代码的review和单元测试也可能会比平时粗心一些,这些代码的状态变化也会比平时快很多。
      为防止这种情况的出现,每日构造会坚持相关的规定,让压力下的项目保持在正轨上。代码仍然每天在不断变化,但是构造过程使得这种变化每天都可控。
      谁能够从每日构造这种过程中得到好处呢?一些开发人员会抗议说,由于他们的项目太大,每天进行build是没有实际意义的。但是为什么现在最复杂的软件项目组却能够成功的执行每日构造的制度呢?本文首发时,Windows NT包括了560万行代码、分布在4万个源程序文件中,项目组仍然可以坚持每日构造。
  • 30岁前不必在乎的30件事

    2007-01-06 13:24:57

    放弃
      
      把握的反面就是放弃,选择了一个机会,就等于放弃了其他所有的可能。
      
      当新的机会摆在面前的时候,敢于放弃已经获得的一切,这不是功亏一篑,这不是半途而废,这是为了谋求更大的发展空间;或者什么都不为,只因为喜欢这样做,因为,年轻就是最大的机会。人,只有在三十岁之前才会有这个胆量,有这个别资本,有这个资格。
      
      失恋
      
      不是不在乎,是在乎不起。三十岁前最怕失去的不是已经拥有的东西,而是梦想。爱情如果只是一个过程,那么正是这个年龄应当经历的,如果要承但结果,三十岁以后,可能会更有能力,更有资格。其实,三十岁之前我们要做的事情很多,稍纵即逝,过久地沉溺在已经干涸的爱河的河床中,与这个年龄的生命节奏不合。
      
      离婚
      
      不是不在乎,是一切还来得及。一位三十八岁的女友与老公结婚十五年,冷战十三年,终于分手。她说:“如果说后来不愿意离婚是为了孩子,那第他第一次提出离婚我没有同意,现在想来真不知道为什么。如果个时候早分手,我的生活绝不会是今天这个样子。现在再重新开始,总觉得一切都晚了。”
      
      漂泊
      
      漂泊不是一种不幸,而是一种资格。趁着没有家室拖累,趁着身体健康,此时不飘何时飘?当然,漂泊的不一定是身体,也许只是幻想和梦境。新世纪的时尚领袖是飘一代,渴望漂泊的人惟一不飘的是那颗心。
      
      失业
      
      三十岁以前就尝到失业的滋味当然是一件不幸的事,但不一定是坏事。
      
      三十岁之前就过早地固定在一个职业上终此一生也许才是最大的不幸。失业也许让你想起埋藏很久而尘封的梦想,也许会唤醒连你自己都从未知道的潜能。也许你本来就没什么梦想,这时候也会逼着你去做梦。
      
      时尚
      
      不要追赶时尚。按说青年人应该是最时尚的,但是独立思考和个性生活更重要。在这个物质社会,其实对时尚的追求早已经成为对金钱的追求。今天,时尚是物欲和世俗的同义语。
      
      格调
      
      这是小资的东西,小资这个词在今天又二度流行,追求格调就是他们的专利。小资们说,有格调要满足四大要件:智慧、素养、自信和金钱。格调就是把高尚理解成穿着、气质、爱好的品位和室内装潢。也就是大老粗只会表现谈吐的庸俗,小资们已经有能力庸俗他们的心灵了。主流观念倒不是非要另类,另类已经成为年轻人观念的主流了,在今天,老土倒显得另类。关键是当今社会是一个创造观念的时代,而不是一个固守陈旧观念的时代。
      
      
      
      评价
      
      我们最不应该做出的牺牲就是因为别人的评价而改变自我,因为那些对你指手画脚的人自己也不知道他们遵从的规则是什么。千万不要只遵从规矩做事,规矩还在创造之中,要根据自己的判断做每一件事,虽然这样会麻烦一点。
      
      幼稚
      
      不要怕人说我们幼稚,这正说明你还年轻,还充满活力。成熟是个吓人的词儿,也是个害人的词儿。成熟和幼稚是对一个人最大而无当、最不负责任、最没用的概括。那些庸人,绝不会有人说他们幼稚。不信,到哪天你被生活压得老气横秋,暮气沉沉的时候,人们一定会说你成熟了,你就会知道成熟是个什么东西。
      
      不适应
      
      在一首摇滚里有这么一句:这个城市改变了我,这个城市不需要我。不要盲目地适应你生存的环境,因为很可能这环境自身已经不适应这个社会的发展了。
      
      失败
      
      我的老师曾经跟我说,一个人起码要在感情上失恋一次,在事业上失败一次,在选择上失误一次,才能长大。不要说失败是成功之母那样的老话,失败来得越早越好,要是三十岁,四十岁之后再经历失败,有些事,很可能就来不及了。
      
      错误
      
      这是年轻人的专利。
      
      浅薄
      
      如果每看一次《泰坦尼克号》就流一次眼泪,每看一次《大话西游》就笑得直不起腰,就会有人笑你浅薄。其实那只能说明你的神经依旧非常敏锐,对哪怕非常微弱的刺激都会迅速做出适应的反应;等你的感觉迟钝了,人们就会说你深沉了。
      
      明星
      
      不是不必在乎,是不能在乎。明星在商品社会是一种消费品,花了钱,听了歌,看了电影,明星们的表现再好,不过是物超所值而己,也不值得崇拜呀?就像你在地摊上花五十块钱买的裙子,别人都猜是八百块钱买的,物超所值了吧?
      
      你就崇拜上这身裙子了?
      
      代价
      
      不是不计代价,而是要明白做任何事都要付出代价。对我们这个年龄的人来说,这绝不是一句废话。否则,要到三十岁的时候才会明白自己曾经付出了多少代价,却不明白为什么付出,更不明白自己得到了多少,得到什么。
      
      孤独
      
      这是为自由付出的代价。
      
      失意
      
      包括感情上的,事业上的,也许仅仅是今天花了冤枉钱没买到可心的东西,朋友家高朋满座自己却插不上一句话。过分在乎失意的感受不是拿命运的捉弄来捉弄自己,就是拿别人的错误来惩罚自己。
      
      缺陷
      
      也许你个子矮,也许你长得不好看,也许你的嗓音像唐老鸭……那么你的优势就是你不会被自己表面的浅薄的亮点所耽搁,少花一些时间,少走一些弯,直接发现你内在的优势,直接挖掘自己深层的潜能。
      
      误会
      

      如果出于恶意,那么解释也没有用;如果出于善意,就不需要解释。专门说到误会倒不是因为一个人在三十岁之前被人误会的时候更多,而是这个年龄的人想不开的时候更多。
      
      谣言
      
      这是一种传染病,沉默是最好的疫苗。除非你能找出传染源,否则解释恰恰会成为病毒传播最理想的条件。
      
      疯狂
      
      这是年轻人最好的心理调适,只能说明你精力旺盛,身心健康。说你疯狂是某些生活压抑、心力交瘁的中老年人恶意的评价,他们就像一部年久修的机器,最需要调试,但只能微调,一次大修就会让他们完全报废。
      
      稳定
      
      三十岁之前就在乎稳定的生活,那只有两种可能,要么就是中了彩票,要么就是未老先衰。
      
      压力
      
      中年人能够承受多大压力检验的是他的韧性;年轻人能承受多大压力,焕发的是他的潜能。
      
      出国

      
      也许是个机会,也许是个陷阱。除非从考大学的那一刻你就抱着这个目标,否则,对待出国的态度应该像对待爱情一样,努力争取成败随缘。
      
      薪水
      
      只要是给人打工,薪水再高也高不到哪儿去。所以在三十岁之前,机会远比金钱重要,事业远比金钱重要,将来远比金钱重要。对大多数人来说,三十岁之前干事业的首要目标绝不是挣钱,而是挣未来。
      
      存款

      
      这倒不一定是因为我们钱少,年轻人现在谁都知道钱是有生命的。机会这么多,条件这么好,可以拿钱去按揭,做今天的事,花明天的钱;也可以拿钱去投资,拿钱去充电。钱只有在它流通的过程中才是钱,否则只是一沓世界上质量最好的废纸。
      
      房子
      
      除非你买房子是为了升值,要么就是你结婚了。我有个同学,家在外地,大学毕业之后,单位没有宿舍,家里就给他买了一套房子。他曾经有过去北京工作的机会,但是他觉得刚买了房子就离开这座城市说不过去,就放弃了。到现在他工作稳定,但一事无成。唯一的成就就是结婚了,并且有了孩子,因为他觉得该让这房子永远空着,所以房子变成了家。房子是都市生活的寓言,这个寓言不应该过早的和我们相关。
      
      年龄
      
      女孩子一过二十五就开始隐瞒自己的年龄,其实大可不必。现在青年期都延迟到四十五岁了,二十五又算得了什么呢?
      
      在乎

      
      这是一种拿不起、放不下的心态,它的反面不是放弃,而是天马行空,自由自在,永远保持革命乐观主义的精神。
  • 提升数据访问层的性能(二)

    2007-01-06 13:06:15

    3.    选择优化性能的功能


    3.1.    使用参数标记作为存储过程的参数


        调用存储过程时,用参数标记做为参数尽量不要用字符做参数。JDBC驱动调用存储过程时要么象执行其他SQL查询一样执行该过程,要么通过RPC直接调用来优化执行过程。如果象SQL查询那样执行存储过程,数据库服务器先解析该语句,验证参数类型,然后把参数转换成正确的数据类型,显然这种调用方式不是最高效的。
        SQL语句总是做为一个字符串送到数据库服务器上,例如,
    “{call getCustName (12345)}”。
    在这种情况下,即使程序员设想给getCustName唯一的参数是整型,事实上参数传进数据库的仍旧是字符串。数据库服务器解析该语句,分离出单个参数值12345,然后在把过程当作SQL语言执行之前,将字符串“12345”转换成整型值。
        通过RPC在数据库服务器中调用存储过程,就能避免使用SQL字符串带来的开销。
        情形1
        在这个例子中,就不能使用服务器端的RPC优化调用存储过程。调用的过程包括解析语句,验证参数类型,在执行过程之前把这些参数转换成正确的类型。
    CallableStatement cstmt = conn.prepareCall (   "{call getCustName (12345)}"); ResultSet rs = cstmt.executeQuery ();  
        情形2
        在这个例子中,可以使用服务器端RPC优化调用存储过程。由于应用避免了文字参数传递带来的开销,且JDBC能以RPC方式直接在数据库中调用存储过程来优化执行,所以,执行时间也大大地缩短了。
    CallableStatement cstmt =
         conn.prepareCall (   "{call getCustName (?)}");cstmt.setLong (1,12345);
    ResultSet rs = cstmt.executeQuery();
        JDBC根据不同的用途来优化性能,所以我们需要根据用途在PreparedStatement对象和Statement对象之间做出选择。如果执行一个单独的SQL语句,就选择Statement对象;如果是执行两次或两次以上就选择PreparedStatement对象。
        有时,为了提高性能我们可以使用语句池。当使用语句池时,如果查询被执行一次且可能再也不会被执行,那就使用Statement对象。如果查询很少被执行,但在语句池的生命期内可能再一次被执行,那么使用PreparedSatement。在相同的情形下,如果没有语句池,就使用Statement对象。

    3.2.    用批处理而不是用PreparedStatement语句


        更新大量的数据通常是准备一个INSERT语句并多次执行该语句,结果产生大量的网络往返。为了减少JDBC调用次数和提高性能,你可以使用PreparedStatement对象的addBatch()方法一次将多个查询送到数据库里。例如,让我们比较一下下边的例子,情形1和情形2。
        情形1:多次执行PreparedStatement语句
    PreparedStatement ps = conn.prepareStatement("INSERT into employees values (?, ?, ?)");
    for (n = 0; n < 100; n++) {  
     ps.setString(name[n]); 
     ps.setLong(id[n]);  
     ps.setInt(salary[n]); 
     ps.executeUpdate();
    }
        情形2:使用批处理
    PreparedStatement ps = 
    conn.prepareStatement(   "INSERT into employees values (?, ?, ?)");
    for (n = 0; n < 100; n++) {  
    ps.setString(name[n]);  
    ps.setLong(id[n]);  
    ps.setInt(salary[n]);  
    ps.addBatch();
    }
    ps.executeBatch();
        在情形1中,一个PreparedStatement用于多次执行一个INSERT语句。在这个情况下,为了100次插入需要101次网络往返,其中一次用于准备语句,额外100次网络往返用于执行每一个操作。当addBatch()方法的时候,如情形2所述,仅需要两个网络往返,一个准备语句,另一个执行批处理。尽管使用批处理需要更多的数据库CPU运算开销,但性能可由减少的网络往返获得。记住要让JDBC驱动在性能方面有良好的表现,就要减少JDBC驱动和数据库服务器之间的网络通讯量。

    3.3.    选择合适的游标


        选择合适的游标能提高应用的灵活性。本节总结了三类游标的性能问题。向前游标对连续读表中所有的行提供了优秀的性能。就检索表数据而言,没有一个检索数据的方法要比向前游标更快。然而,当应用必须处理非连续方式的行时,就不能使用它。
        对需要数据库高层次的并发控制和需要结果集向前和向后滚动能力的应用而言,JDBC驱动使用的无感知游标是最为理想选择。对无感知游标的第一次请求是获取所有的行(或者当JDBC使用“懒惰”方式读时,可以读取部分行)并将它们存储在客户端。那么,第一次请求将会非常慢,特别是当长数据被检索到的时候。后续的请求不再需要网络交通(或当驱动采用懒惰方式时,只有有限的网络交通)并处理得很快。由于第一次请求处理缓慢,无感知游标不应该用于一行数据的单个请求。当要返回长数据时,内存很容易被耗尽,所以开发人员也应该避免使用无感知游标。一些无感知游标的实现是把数据缓存在数据库中的零时表中,避免了性能问题,但是,大多数是把信息缓存在应用本地。
        无感知游标,有时又叫键集驱动的游标,使用标识符,如已经存在于你数据库中的ROWID。当你通过结果集滚动的时候,适合于标识符的数据会被检索到。由于每个请求都产生网络交通量,所以性能将会非常差。然而,返回非连续行不会更多的影响性能。
        为了更进一步说明,我们来看一个通常返回应用1000行数据的应用。在执行时或第一行被请求时,JDBC不会执行由应用提供的SELECT语句。而是JDBC驱动用键标识符替换查询的SELECT列表,例如,ROWID。这个修改的查询将会被驱动执行,并且所有1000键值将会被从数据库中检索出来并被驱动缓存。每一个来自应用对结果行的请求将转到JDBC驱动,为了返回合适的行,JDBC在它本地缓存中查询键值,构造一个类似于“WHERE ROWID=?”包含WHERE的优化的语句,执行这个修改了查询,然后从服务器上检索单个结果行。
        当应用使用来自缓存中的无感知(Insensitive)游标数据时,有感知(Sensitive)游标在动态情形下就是首选的游标模式。

    3.4.    有效地使用get方法


        JDBC提供了很多从结果集中检索数据的方法,例如getInt(),getString(),以及getObject()。getObject()方法是最普通的方法,但在没有说明非默认映射时提供了最差的性能。这是因为为了确定被检索值的类型和产生合适的映射,JDBC驱动必须做额外的处理。所以,总是使用能明确数据类型的方法。
        为了更好地提高性能,请提供被检索列的列数字,例如,getString(1),getLong(2),和getInt(3),而不是列名。如果列数字没有说明,网络流量是不受影响的,但转换和查找的成本上升了。例如,假设你使用getString(“foo”)…驱动可能不得不将列的标识符foo转换成大写(如果必要),并在列列表中用“foo”和所有的列名比较。如果提供了列数字,很大部分的处理都被节省了。
        例如,假如你有一个15列100行的结果集,列名没有包括在结果集中。你感兴趣的有三列,EMPLOEEMEN
    T(字符串),EMPLOYEENUMBER(长整型),和SALARY(整型)。如果你说明了getString(“EmployeeName”),getLong(“EmployeeNumber”)和getInt(“Salary”),每列的列名必须转换成和数据库元数据中匹配的大小写,毫无疑问查询将相应的增加。如果你说明getString(1),getLong(2),和getInt(15),性能将会大大地提高。

    3.5.    检索自动产生的键


        许多数据库已经隐藏了描述表中每行唯一键的列(又叫伪列)。通常,由于伪列描述了数据的物理磁盘地址,故而在查询中使用这种类型的列存取行是最快的方式。在JDBC3.0以前,应用仅能在插入数据之后立即执行SELECT语句检索到伪列的值。
    For example:
    //insert rowint 
    rowcount = stmt.executeUpdate (   "insert into LocalGeniusList (name) values ('Karen')"); 
    // now get the disk address - rowid - for the newly inserted row
    ResultSet rs = stmt.executeQuery (   "select rowid from LocalGeniusList where name = 'Karen'");
        这个检索伪列的方法有两个主要的缺点。第一,检索伪列需要通过网络把一个单独的查询语句发送到服务器上执行。第二,由于表中可能没有主键,查询条件可能不能唯一地确定行。在后边的情形中,多个伪列值被返回,应用或许不能确定哪个是最近插入的行。
    JDBC规范一个可选的特性是当行插入表时,能检索到行的自动产生的键信息。
    For example:
    int rowcount = stmt.executeUpdate (   "insert into LocalGeniusList (name) values ('Karen')",
    // insert row AND return 
    keyStatement.RETURN_GENERATED_KEYS);
    ResultSet rs = stmt.getGeneratedKeys (); 
    // key is automatically available
        即便该表没主键,这都给应用提供了一个唯一确定行值的最快方法。当存取数据时,检索伪列键的能力给JDBC开发人员提供了灵活性并创造了性能。

    4.    管理连接和数据更新

    4.1.    管理连接

        连接管理的好坏直接影响到应用的性能。采用一次连接创建多个Statement对象的方式来优化你的应用,而不是执行多次连接。在建立最初的连接之后要避免连接数据源。
        一个不好的编码习惯是执行SQL语时连接和断开好几次。一个连接对象可以有多个Statement对象和它关联。由于Statement对象是定义SQL语句信息的内存存储,它能管理多个SQL语句。此外,你可以使用连接池来显著地提高性能,特别是对那些通过网络连接或通过WWW连接的应用。连接池让你重用连接,关闭连接不是关闭与数据库的物理连接,而是将用完的连接放到连接池中。当一个应用请求一个连接时,一个活动的连接将从连接池中取出重用,这样就避免了创建新连接的而产生的网络I/O。

    4.2.    在事务中管理提交

        由于磁盘I/O和潜在的网络I/O,提交事务往往要慢。经常使用WSConnection.setAutoCommit(false)来关闭自动提交设置。
        提交实际上包括了什么呢?数据库服务器必须刷新包含更新的和新数据的磁盘上的每一个数据页。这通常是一个对日志文件连续写的过程,但也是磁盘I/O。默认情况下,当连接到数据源时,自动提交是打开的,由于提交每个操作需要大量的磁盘I/O,自动提交模式通常削弱了性能。此外,大部分数据库没有提供本地的自动提交模式。对这种类型的服务器,JDBC驱动对每一个操作必须明确地给服务器送出COMMIT语句和一个BEGIN TRANSACTION。
        尽管使用事务对应用的性能有帮助,但不要过度地使用。由于为了防止其他用户存取该行而在行上长时间的持有锁将减少吞吐量。短时间内提交事务可以最大化并发量。

    4.3.    选择正确的事务模式


        许多系统支持分布式事务;也就是说,事务能跨越多个连接。由于记录日志和所有包含在分布式事务中组件(JDBC驱动,事务监视器和数据库系统)之间的网络I/O,分布式事务要比普通的事务慢四倍。除非需要分布式事务,否则尽量避免使用它们。如果可能就使用本地事务。应该注意的是许多Java应用服务器提供了一个默认的利用分布式事务的事务行为。为了最好的系统性能,把应用设计在运行在单个连接对象之下,除非必要避免分布式事务。

    4.4.    使用updateXXX方法


        尽管编程的更新不适用于所有类型的应用,但开发人员应该试着使用编程的更新和删除,也就是说,使用ResultSet对象的updateXXX()方法更新数据。这个方法能让开发人员不需要构建复杂的SQL语句就能更新数据。为了更新数据库,在结果集中的行上移动游标之前,必须调用updateRow()方法。
        在下边的代码片断中,结果集对象rs的Age列的值使用getInt()方法检索出来,updateInt()方法用于用整型值25更新那一列。UpdateRow()方法用于在数据库中更新修改了值的行。 
    int n = rs.getInt("Age"); 
    // n contains value of Age column in the resultset rs...
    rs.updateInt("Age", 25); 
    rs.updateRow();
        除了使应用更容易地维护,编程更新通常产生较好的性能。由于指针已经定位在被更新的行上,定位行的所带来的开销就避免了。

    4.5.    使用getBestRowIdentifier()


        使用getBestRowIdentifier()(请参阅DatabaseMetaData接口说明)确定用在更新语句的Where子句中的最优的列集合。伪列常常提供了对数据的最快的存取,而这些列仅能通过使用getBestRowIdentifier()方法来确定一些应用不能被设计成利用位置的更新和删除。一些应用或许通过使用可查询的结果列,如调用getPrimaryKeys()或者调用getIndexInfo()找出可能是唯一索引部分的列,使Where子句简洁化。这些方法通常可以工作,但可能产生相当复杂的查询。看看下边的例子:
    ResultSet WSrs = WSs.executeQuery    ("SELECT first_name, last_name, ssn, address, city, state, zip    FROM emp");
    // fetch data...
    WSs.executeUpdate ("UPDATE EMP SET ADDRESS = ?   WHERE first_name = ? and last_name = ? and ssn = ?    and address = ? and city = ? and state = ?    and zip = ?");
    // fairly complex query
        应用应该调用getBestRowIdentifier()检索最优集合的能确定明确的记录的列(可能是伪列)。许多数据库支持特殊的列,它们没有在表中被用户明确地定义,但在每一个表中是“隐藏”的列(例如,ROWID和TID)。由于它们是指向确切记录位置的指针,这些伪列通常给数据提供了最快的存取。由于伪列不是表定义的部分,它们不会从getColumns中返回。为了确定伪列是否存在,调用getBestRowIndentifier()方法。
    再看一下前边的例子:
    ...
    ResultSet WSrowid = getBestRowIdentifier(... "emp", ...);
    ...
    WSs.executeUpdate ("UPDATE EMP SET ADDRESS = ?  WHERE ROWID = ?";
    // fastest access to the data!
        如果你的数据源没有包含特殊的伪列,那么getBestRowIdentifier()的结果集由指定表上的唯一索引组成(如果唯一索引存在)。因此,你不需要调用getIndexInfo来找出最小的唯一索引。

     

  • 提升数据访问层的性能(一)

    2007-01-06 12:59:56

    在J2EE应用中,我们经常通过JDBC访问企业资源。但JDBC用的不好,将会影响系统的性能。本文参照John Goodson的《Performance Tips for the Data Tier(JDBC)》一文,写成此文,希望对我们的开发有所帮助。
    本文从以下四个部分加以说明:
    l    适当地使用数据库的元数据方法
    l    检索需要的数据
    l    选择优化性能的功能
    l    管理连接和数据更新
    1.    适当地使用数据库的元数据方法
    1.1.    尽量少用元数据方法
    由于元数据方法执行速度比较慢,故要尽量少用元数据方法。由于调用元数据方法产生结果集需要大量的开销,由元数据方法产生的结果集应该缓存起来,而不是多次执行查询,这样可以提供JDBC的性能。例如在应用中你调用了getTypeInfo一次,你就应该将结果集缓存起来,共应用再次使用。
    1.2.    避免查询模式
    给元数据提供null参数或查询模式将会产生耗时的查询。同时,由于一些不需要的数据通过网络传递,导致网络流量的增大,降低整个系统的性能。由于元数据方法执行比较慢,所以尽可能地给它提供非null参数和高效地调用它。而我们的应用常出现这样的现象:
    ResultSet WSrs = WSc.getTables (null, null, "WSTable", null);
    应该改成:
    ResultSet WSrs = WSc.getTables ("cat1", "johng", "WSTable",  "TABLE");
    显然,在第一个getTables()调用中,应用可能需要知道WSTable表是否存在。当然, JDBC驱动按字面上的调用与解析请求不同。JDBC是这样解析请求的:返回所有的名称叫“WSTable”的表,视图,系统表,同义词,零时表,或在任何数据库目录中数据库的模式存在的别名。
    第二个getTables()的调用更准确地反映了应用需要知道什么。JDBC这样解析这个请求:返回所有名叫“WSTable”存在与当前目录中模式为“johng’的所有表。显然,JDBC驱动处理第二个请求要比处理第一个请求来得更有效。
    给元数据方法提供的信息越多,你得到的信息的准确性和性能也越高。
    1.3.    使用哑元查询来确定表的特征
    避免使用getColumns()确定一个表的特征。用getMedata()哑元查询替换之。考虑一个容许用户选择列的应用。应用应该用getColumns()返回用户列的信息还是准备一个哑元查询并调用getMetadata()呢?
    情形1:getColumns方法
    ResultSet WSrc = WSc.getColumns (... "UnknownTable" ...);// This call to getColumns() will generate a query to// the system catalogs... possibly a join// which must be prepared, executed, and produce// a result set. . .WSrc.next();string Cname = getString(4);. . .// user must retrieve N rows from the server// N = # result columns of UnknownTable// result column information has now been obtained
    情形2:getMetadata方法
    // prepare dummy queryPreparedStatement WSps = WSc.prepareStatement  ("SELECT * from UnknownTable WHERE 1 = 0");// query is never executed on the server - only preparedResultSetMetaData WSsmd=WSps.getMetaData();int numcols = WSrsmd.getColumnCount();...int ctype = WSrsmd.getColumnType(n)...// result column information has now been obtained
    在两个情形中,查询被送到服务器上。但在情形1中,查询必须被准备和执行,结果描述信息必须被简洁地表达,并且结果集必须送到客户端。在情形2中,一个简单的查询必须准备并且仅有结果描述信息被简洁地描述。显然,情形2是更好的性能模式。
    这多少有些把这个讨论复杂化了,让我们考虑一个不支持本地准备SQL语句的数据库。情形1的性能没有变,但由于哑元查询必须被求值而不是仅仅准备,因此情形2的性能稍微有些增加。因为查询语句的Where子句计算结果总是FALSE,因此查询没有产出结果行和不存取表数据的执行。在这个情形下,方法2仍然要比方法1做的好。
    总之,总是使用结果集元数据检索表列信息,如列名,列数据类型和列精度和数值范围。当被请求的信息不能从结果记录集(例如,表列默认值)获取的时候,仅仅使用getColumns()方法。
    2.    检索需要的数据
    2.1.    检索长数据
    除非必要,由于检索长数据会造成网络资源紧张而降低性能。通常大多数用户不需要看到长数据,如果用户需要看这些数据,应用再去检索。
    我们的代码中长出现这样的代码:select * from <table name> …如果选择的表中有长数据列,那这个查询的性能将会非常糟糕。再说,表中的所有数据项你都需要吗?如果不需要,为什么要让它们在网络上传递,浪费网络资源?
    例如,看看下边的JDBC代码:
    ResultSet rs = stmt.executeQuery (   "select * from Employees where SSID = '999-99-2222'");rs.next();string name = rs.getString (4);
    JDBC不是智能的。当你这样写代码的时候,它根本就不知道你真正需要那些列,它把所有的都返回当然是情理之中的事情了,所以开发的时候就劳烦把需要的列在Select语句中指明。如果Employees表中有照片之类的长数据字段,系统的性能之低就可想而知了。
    尽管有方法getClob()和getBlod()支持这种长数据字段的检索,但并不是每个数据库都支持它。所以记住:需要长数据的时候再去读它。
    2.2.    减少检索到的数据的大小
    有时候,长数据必须被检索。在这种情况下,大多数用户可能不需要在屏幕看到100k(或更多)的正文。 为了减少网络流量和提高性能,你可以通过调用setMaxRows(),setMaxFieldSize(),以及与驱动相关的setFetchSize()方法把检索到的数据大小减少到可管理的范围之内。另一个减少检索到的数据大小的方法是减少列的数量。如果驱动允许你定义包尺寸,使用最小的包尺寸将会满足你的需要。
    记住:注意只返回你需要的行和列。如果你返回了五列而你只需要两列,性能就降低了??特别是不需要的结果中包含了长数据。
    2.3.    选择正确的数据类型
    检索和送出某种数据的类型的开销是很昂贵的。当设计数据库模式时,选择能最有效处理的数据类型。例如,整型要比浮点数和小数数据要快。浮点数根据数据库特殊的格式定义,通常是压缩格式。为了能被数据库通讯协议处理,这些数据必须被解压后再转换成不同的格式。
    2.4.    检索记录集
    由于数据库系统对滚动游标的有限支持,大多数JDBC驱动不能实现滚动游标。除非你确定数据库支持滚动记录集(例如,rs),否则不要调用rs.last()和rs.getRow()去得到记录集有多少行。对模仿滚动游标的JDBC驱动而言,调用rs.last()会导致驱动为了到最后一行而通过网络检索所有的数据。可以替代的方法是你可以通过记录集枚举记录行数,或者通过提交在SELECT语句中一个带有COUNT列的查询得到行数。
    一般情况下,不要写依赖于记录集行数的代码,因为为了取得行数,驱动必须读取记录集中的所有的行。
  • SQL Server和Oracle防止数据锁定的比较

    2007-01-06 12:49:32

     来源:思达网校 

    数据库并行访问,也就是两个或两以上用户同时访问同一数据,这也是数据库引擎如何设计和实现适度反应所面临的最大问题。设计优良、性能卓越的数据库引擎可以轻松地同时为成千上万的用户服务。而“底气不足”的数据库系统随着更多的用户同时访问系统将大大降低其性能。最糟糕的情况下甚至可能导致系统的崩溃。

      当然,并行访问是任何数据库解决方案都最为重视的问题了,为了解决并行访问方面的问题各类数据库系统提出了各种各样的方案。 SQL Server和Oracle两大DBMS也分别采用了不同的并行处理方法。它们之间的实质差别在哪里呢?

    并行访问的问题

      并行访问出现问题存在若干种情况。在最简单的情形下,数量超过一个的用户可能同时查询同一数据。就这种情况而言数据库的操作目标很简单:尽可能地为用户们提供快速的数据访问。 这对我们现在常见的数据库来说不成问题:SQL Server和 Oracle 都采用了多线程机制,它们当然能够一次处理多个请求。

      不过,在用户修改数据的情况下并行访问问题就变得复杂起来了。显然,数据库通常只允许唯一用户一次修改特定的数据。当某一用户开始修改某块数据时, SQL Server和 Oracle 都能很快地锁定数据,阻止其他用户对这块数据进行更新,直到修改该数据的第1位用户完成其操作并提交交易(commit transaction)。但是,当某一位用户正在修改某块数据时假设另一位用户又正想查询该数据的信息时会发生什么情况呢?在这种情况下数据库管理系统又该如何动作呢?Oracle 和 SQL Server针对这一问题采取了不同的解决方案。

    SQL Server方法

      现在不妨假设有人开始修改SQL Server上存储的数据,于是这块数据立即被数据库锁定。数据锁定操作阻塞其他任何访问该数据的连接——连查询操作都不会放过。于是,这块被锁定的数据只有在交易被提交或者回滚之后才能接受其他访问操作。

      下面用SQL Server随带的pubs示例数据库做一个简单示范。在Query Analyzer内打开两个窗口。在第1个窗口中执行下列SQL操作语句,更新pubs数据库中某一图书的价格:

    use pubs
    go
    begin tran
    update titles
    set price = price * 1.05 中国公务网 2005-6-23 15:28:26
    where

    title_id = %27BU2075%27

      由于代码中并没有执行commit语句,所以数据变动操作实际上还没有最终完成。接下来,在另一个窗口里执行下列语句查询titles数据表:
    select title_id,title,price
    from titles
    order by title_id.

      你什么结果也得不到。窗口底部的小地球图标会转个不停。尽管我在先前的操作中仅仅更新了一行,但是,select语句的执行对象却恰好包含了其数据正被修改的一行。因此,上面的操作不会返回任何数据,除非回到第1个窗口提交交易或者回滚。

      SQL Server的数据锁定方案可能会降低系统的性能和效率。数据被锁定的时间越长,或者锁定的数据量越大,其他数据访问用户就越可能不得不等待其查询语句的执行。因此,从程序员的角度来看,对SQL Server编程的时候应该尽量地把交易代码设计得既小又快。

      在SQL Server的最近版本中,微软对SQL Server进行了某些修改,使其一次锁定的数据量大大减少,这是数据库设计中的一大重要改进。在6.5版及以前版本中,最少的数据锁定量是一页。哪怕你只在修改一行数据,而该行数据位于包含10行数据的一页上,则整页10行数据都会被锁定。显然,这么大的数据锁定量增加了其他数据访问连接不得不等待数据修正完成的概率。在SQL Server 7中,微软引入了行锁定技术,这样,目前的SQL Server只锁定实际正被改变的数据行。

      SQL Server的解决方案听起来很简单,但实际上其幕后为提供足够的系统高性能而采取了很多措施。例如,如果你在同时修改多行数据,SQL Server则会把数据锁定范围提升到页级别乃至锁定整个数据表,从而不必针对每一记录跟踪和维护各自的数据锁。

    Oracle方法

      下面我们再看看Oracle数据库是如何实施类似操作的。首先,我打开一个SQLPlus实例执行下列查询语句(这个例子可以在Oracle 9i中示例中找到)。这个实例称做查询实例:
    select first_name, last_name, salary
    from hr.employees
    where
    department_id = 20;
    代码返回两行数据,如下所示:

      然后,再打开另一个SQLPlus实例——更新实例来执行以下命令:
    SQL> update hr.employees
    2 set salary = salary * 1.05
    3 where
    4 department_id = 20
    5 /
    代码执行后回复消息称两行数据已被更新。
      注意,以上代码中并每有像在SQL Server示例那样键入“begin tran”字样的代码。Oracle 的SQLPlus隐含启用交易(你还可以模仿SQL Server的行为,设置“autocommit to on”自动地提交交易)。接下来我们在SQLPlus更新实例中再执行同查询实例一样的select语句。

      结果清楚地表明:Michael和Pat的薪水都增加了,然而这个时候我还没有提交数据变更交易。

      现在转到第1个SQLPlus查询实例重新运行查询,结果如下:

      Oracle不需要用户等待数据更新实例中操作被提交,它径直返回Michael和Pat的查询信息,但实际上返回的是数据更新开始之前的数据视图!

      这时候,熟悉SQL Server的人可能会说了,在查询中设置(NOLOCK)不也能达到同样的效果吗?可是,对SQL Server而言,在数据映像之前是不能获取数据的。指定(NOLOCK)实际上只是得到了没有提交的数据。Oracle的方法则提供了数据的一致视图,所有的信息都是针对交易的、基于存储数据快照的。

      如果在SQLPlus的更新实例中提交更新交易在查询实例中就能看到薪水数据发生变化。如果在查询实例中重新运行先前的查询语句,那么Oracle将返回新的薪水数值。

    存储数据快照

      说了半天,在给用户显示先前版本的数据同时,Oracle是如何允许其他用户修改数据的呢?其实,只要某一用户启动了一宗修改数据的交易,之前的数据映像就会被写到一个特殊的存储区域。这种“前映像”用来向任何查询数据的用户提供一致的数据库视图。这样,当其他用户在修改数据的时候,在以上的测试中我们就能看到尚未发生变更的薪金数据。

      这个特殊的存储区域在哪里呢?这个问题的答案就跟你正在使用的Oracle版本有关了。在 Oracle 8i及其以前版本中会为这一目的创建特殊的回滚段。然而,这种举措会给数据库管理员(DBA)带来管理和调整数据段的工作负担。例如,DBA必须确定为此需要的数据段的数量以及大小等。假如回滚段没有正确配置,那么对交易而言它们就可能不得不排队等待回滚段中出现必要的数据空间。

      Oracle 9i就不同了,这是Oracle的最新版本,Oracle实现了一种新特性,这就是所谓的undo表空间,它有效地消除了以上的管理复杂性。虽然回滚段仍然可以继续使用,但是,DBA现在可以选择创建undo表空间的方式令Oracle自己管理“前映像”的复杂空间分配。 WWW.GONGWU.COM.CN 2006-9-14 0:29:21
      Oracle的这种方法对程序员具有重要意义。因为回滚空间不是无限的,所以,更新交易的数据快照会取代先前交易的映像。因此,如果必要的回滚段被其他交易的映像覆盖的话。运行时间较长的查询操作就可能产生“ snapshot too old”错误。

      下面举个可能发生的案例。假设在上午11:59的时候某位职员开始更新John Doe帐务的交易。这宗交易在下午12:01被提交。同时,下午12:00某财务经理开始查询所有的客户帐务报表和当月收费总计。因为客户很多,所以这一查询操作很费了点时间,但是不论这次操作到底执行了多久,反正它检索出的结果就是下午12:00数据库中存在的数据。如果包含John Doe帐务前映像的回滚空间在查询执行到该客户名字的时候被覆盖则查询返回错误消息。

      Oracle的解决方案当然更为合理,在抽象意义上提供了相比SQL Server更佳的数据一致性。在执行Oracle查询的时候无须担心较长的查询操作会锁定重要的交易。但是,在两种数据库同时支持海量用户的情况下也很难证明Oracle是否就能真正实现具体条件下的数据一致性。

  • [推荐]数据库性能优化

    2007-01-06 12:43:44

    设计一个应用系统似乎并不难,但是要想使系统达到最优化的性能并不是一件容易的事。在开发工具、数据库设计、应用程序的结构、查询设计、接口选择等方面有多种选择,这取决于特定的应用需求以及开发队伍的技能。本文以SQL Server为例,从后台数据库的角度讨论应用程序性能优化技巧,并且给出了一些有益的建议。

    1 数据库设计

    要在良好的SQL Server方案中实现最优的性能,最关键的是要有1个很好的数据库设计方案。在实际工作中,许多SQL Server方案往往是由于数据库设计得不好导致性能很差。所以,要实现良好的数据库设计就必须考虑这些问题。

    1.1 逻辑库规范化问题

    一般来说,逻辑数据库设计会满足规范化的前3级标准:

    1.第1规范:没有重复的组或多值的列。

    2.第2规范:每个非关键字段必须依赖于主关键字,不能依赖于1个组合式主关键字的某些组成部分。

    3.第3规范:1个非关键字段不能依赖于另1个非关键字段。

    遵守这些规则的设计会产生较少的列和更多的表,因而也就减少了数据冗余,也减少了用于存储数据的页。但表关系也许需要通过复杂的合并来处理,这样会降低系统的性能。某种程度上的非规范化可以改善系统的性能,非规范化过程可以根据性能方面不同的考虑用多种不同的方法进行,但以下方法经实践验证往往能提高性能。

    1.如果规范化设计产生了许多4路或更多路合并关系,就可以考虑在数据库实体(表)中加入重复属性(列)。

    2.常用的计算字段(如总计、最大值等)可以考虑存储到数据库实体中。

    比如某一个项目的计划管理系统中有计划表,其字段为:项目编号、年初计划、二次计划、调整计划、补列计划…,而计划总数(年初计划+二次计划+调整计划+补列计划)是用户经常需要在查询和报表中用到的,在表的记录量很大时,有必要把计划总数作为1个独立的字段加入到表中。这里可以采用触发器以在客户端保持数据的一致性。

    3.重新定义实体以减少外部属性数据或行数据的开支。相应的非规范化类型是:

    (1)把1个实体(表)分割成2个表(把所有的属性分成2组)。这样就把频繁被访问的数据同较少被访问的数据分开了。这种方法要求在每个表中复制首要关键字。这样产生的设计有利于并行处理,并将产生列数较少的表。

    (2)把1个实体(表)分割成2个表(把所有的行分成2组)。这种方法适用于那些将包含大量数据的实体(表)。在应用中常要保留历史记录,但是历史记录很少用到。因此可以把频繁被访问的数据同较少被访问的历史数据分开。而且如果数据行是作为子集被逻辑工作组(部门、销售分区、地理区域等)访问的,那么这种方法也是很有好处的。

    1.2 生成物理数据库

    要想正确选择基本物理实现策略,必须懂得数据库访问格式和硬件资源的操作特点,主要是内存和磁盘子系统I/O。这是一个范围广泛的话题,但以下的准则可能会有所帮助。

    1.与每个表列相关的数据类型应该反映数据所需的最小存储空间,特别是对于被索引的列更是如此。比如能使用smallint类型就不要用integer类型,这样索引字段可以被更快地读取,而且可以在1个数据页上放置更多的数据行,因而也就减少了I/O操作。

    2.把1个表放在某个物理设备上,再通过SQL Server段把它的不分簇索引放在1个不同的物理设备上,这样能提高性能。尤其是系统采用了多个智能型磁盘控制器和数据分离技术的情况下,这样做的好处更加明显。

    3.用SQL Server段把一个频繁使用的大表分割开,并放在2个单独的智能型磁盘控制器的数据库设备上,这样也可以提高性能。因为有多个磁头在查找,所以数据分离也能提高性能。

    4.用SQL Server段把文本或图像列的数据存放在1个单独的物理设备上可以提高性能。1个专用的智能型的控制器能进一步提高性能。

    2 与SQL Server相关的硬件系统

    与SQL Server有关的硬件设计包括系统处理器、内存、磁盘子系统和网络,这4个部分基本上构成了硬件平台,Windows NT和SQL Server运行于其上。

    2.1 系统处理器(CPU)

    根据自己的具体需要确定CPU结构的过程就是估计在硬件平台上占用CPU的工作量的过程。从以往的经验看,CPU配置最少应是1个80586/100处理器。如果只有2~3个用户,这就足够了,但如果打算支持更多的用户和关键应用,推荐采用Pentium Pro或PⅡ级CPU。

    2.2 内存(RAM)

    为SQL Server方案确定合适的内存设置对于实现良好的性能是至关重要的。SQL Server用内存做过程缓存、数据和索引项缓存、静态服务器开支和设置开支。SQL Server最多能利用2GB虚拟内存,这也是最大的设置值。还有一点必须考虑的是Windows NT和它的所有相关的服务也要占用内存。

    Windows NT为每个WIN32应用程序提供了4GB的虚拟地址空间。这个虚拟地址空间由Windows NT虚拟内存管理器(VMM)映射到物理内存上,在某些硬件平台上可以达到4GB。SQL Server应用程序只知道虚拟地址,所以不能直接访问物理内存,这个访问是由VMM控制的。Windows NT允许产生超出可用的物理内存的虚拟地址空间,这样当给SQL Server分配的虚拟内存多于可用的物理内存时,会降低SQL Server的性能。

    这些地址空间是专门为SQL Server系统设置的,所以如果在同一硬件平台上还有其它软件(如文件和打印共享,应用程序服务等)在运行,那么应该考虑到它们也占用一部分内存。一般来说硬件平台至少要配置32MB的内存,其中,Windows NT至少要占用16MB。1个简单的法则是,给每一个并发的用户增加100KB的内存。例如,如果有100个并发的用户,则至少需要32MB+100用户*100KB=42MB内存,实际的使用数量还需要根据运行的实际情况调整。可以说,提高内存是提高系统性能的最经济的途径。

    2.3 磁盘子系统

    设计1个好的磁盘I/O系统是实现良好的SQL Server方案的一个很重要的方面。这里讨论的磁盘子系统至少有1个磁盘控制设备和1个或多个硬盘单元,还有对磁盘设置和文件系统的考虑。智能型SCSI-2磁盘控制器或磁盘组控制器是不错的选择,其特点如下:

    (1)控制器高速缓存。

    (2)总线主板上有处理器,可以减少对系统CPU的中断。

    (3)异步读写支持。

    (4)32位RAID支持。

    (5)快速SCSI—2驱动。

    (6)超前读高速缓存(至少1个磁道)。

    3 检索策略

    在精心选择了硬件平台,又实现了1个良好的数据库方案,并且具备了用户需求和应用方面的知识后,现在应该设计查询和索引了。有2个方面对于在SQL Server上取得良好的查询和索引性能是十分重要的,第1是根据SQL Server优化器方面的知识生成查询和索引;第2是利用SQL Server的性能特点,加强数据访问操作。

    3.1 SQL Server优化器

    Microsoft SQL Server数据库内核用1个基于费用的查询优化器自动优化向SQL提交的数据查询操作。数据操作查询是指支持SQL关键字WHERE或HAVING的查询,如SELECT、DELETE和UPDATE。基于费用的查询优化器根据统计信息产生子句的费用估算。

    了解优化器数据处理过程的简单方法是检测SHOWPLAN命令的输出结果。如果用基于字符的工具(例如isql),可以通过键入SHOW SHOWPLAN ON来得到SHOWPLAN命令的输出。如果使用图形化查询,比如SQL Enterprise Manager中的查询工具或isql/w,可以设定配置选项来提供这一信息。

    SQL Server的优化通过3个阶段完成:查询分析、索引选择、合并选择。

    1.查询分析

    在查询分析阶段,SQL Server优化器查看每一个由正规查询树代表的子句,并判断它是否能被优化。SQL Server一般会尽量优化那些限制扫描的子句。例如,搜索和/或合并子句。但是不是所有合法的SQL语法都可以分成可优化的子句,如含有SQL不等关系符“<>”的子句。因为“<>”是1个排斥性的操作符,而不是1个包括性的操作符,所在扫描整个表之前无法确定子句的选择范围会有多大。当1个关系型查询中含有不可优化的子句时,执行计划用表扫描来访问查询的这个部分,对于查询树中可优化的SQL Server子句,则由优化器执行索引选择。

    2.索引选择

    对于每个可优化的子句,优化器都查看数据库系统表,以确定是否有相关的索引能用于访问数据。只有当索引中的列的1个前缀与查询子句中的列完全匹配时,这个索引才被认为是有用的。因为索引是根据列的顺序构造的,所以要求匹配是精确的匹配。对于分簇索引,原来的数据也是根据索引列顺序排序的。想用索引的次要列访问数据,就像想在电话本中查找所有姓为某个姓氏的条目一样,排序基本上没有什么用,因为你还是得查看每一行以确定它是否符合条件。如果1个子句有可用的索引,那么优化器就会为它确定选择性。

    所以在设计过程中,要根据查询设计准则仔细检查所有的查询,以查询的优化特点为基础设计索引。


    (1)比较窄的索引具有比较高的效率。对于比较窄的索引来说,每页上能存放较多的索引行,而且索引的级别也较少。所以,缓存中能放置更多的索引页,这样也减少了I/O操作。


    (2)SQL Server优化器能分析大量的索引和合并可能性。所以与较少的宽索引相比,较多的窄索引能向优化器提供更多的选择。但是不要保留不必要的索引,因为它们将增加存储和维护的开支。对于复合索引、组合索引或多列索引,SQL Server优化器只保留最重要的列的分布统计信息,这样,索引的第1列应该有很大的选择性。


    (3)表上的索引过多会影响UPDATE、INSERT和DELETE的性能,因为所有的索引都必须做相应的调整。另外,所有的分页操作都被记录在日志中,这也会增加I/O操作。


    (4)对1个经常被更新的列建立索引,会严重影响性能。


    (5)由于存储开支和I/O操作方面的原因,较小的自组索引比较大的索引性能更好一些。但它的缺点是要维护自组的列。


    (6)尽量分析出每一个重要查询的使用频度,这样可以找出使用最多的索引,然后可以先对这些索引进行适当的优化。


    (7)查询中的WHERE子句中的任何列都很可能是个索引列,因为优化器重点处理这个子句。


    (8)对小于1个范围的小型表进行索引是不划算的,因为对于小表来说表扫描往往更快而且费用低。


    (9)与“ORDER BY”或“GROUP BY”一起使用的列一般适于做分族索引。如果“ORDER BY”命令中用到的列上有分簇索引,那么就不会再生成1个工作表了,因为行已经排序了。“GROUP BY”命令则一定产生1个工作表。


    (10)分簇索引不应该构造在经常变化的列上,因为这会引起整行的移动。在实现大型交易处理系统时,尤其要注意这一点,因为这些系统中数据往往是频繁变化的。


    3.合并选择


    当索引选择结束,并且所有的子句都有了一个基于它们的访问计划的处理费用时,优化器开始执行合并选择。合并选择被用来找出一个用于合并子句访问计划的有效顺序。为了做到这一点,优化器比较子句的不同排序,然后选出从物理磁盘I/O的角度看处理费用最低的合并计划。因为子句组合的数量会随着查询的复杂度极快地增长,SQL Server查询优化器使用树剪枝技术来尽量减少这些比较所带来的开支。当这个合并选择阶段结束时,SQL Server查询优化器已经生成了1个基于费用的查询执行计划,这个计划充分利用了可用的索引,并以最小的系统开支和良好的执行性能访问原来的数据。


    3.2 高效的查询选择


    从以上查询优化的3个阶段不难看出,设计出物理I/O和逻辑I/O最少的方案并掌握好处理器时间和I/O时间的平衡,是高效查询设计的主要目标。也就是说,希望设计出这样的查询:充分利用索引、磁盘读写最少、最高效地利用了内存和CPU资源。


    以下建议是从SQL Server优化器的优化策略中总结出来的,对于设计高效的查询是很有帮助的。


    1.如果有独特的索引,那么带有“=”操作符的WHERE子句性能最好,其次是封闭的区间(范围),再其次是开放的区间。


    2.从数据库访问的角度看,含有不连续连接词(OR和IN)的WHERE子句一般来说性能不会太好。所以,优化器可能会采用R策略,这种策略会生成1个工作表,其中含有每个可能匹配的执行的标识符,优化器把这些行标志符(页号和行号)看做是指向1个表中匹配的行的“动态索引”。优化器只需扫描工作表,取出每一个行标志符,再从数据表中取得相应的行,所以R策略的代价是生成工作表。


    3.包含NOT、<>、或! =的WHERE子句对于优化器的索引选择来说没有什么用处。因为这样的子句是排斥性的,而不是包括性的,所以在扫描整个原来数据表之前无法确定子句的选择性。


    4.限制数据转换和串操作,优化器一般不会根据WHERE子句中的表达式和数据转换式生成索引选择。例如:


    paycheck * 12>36000 or substring(lastname,1,1)=“L”


    如果该表建立了针对paycheck和lastname的索引,就不能利用索引进行优化,可以改写上面的条件表达式为:


    paycheck<36000/12 or lastname like “L%”


    5.WHERE子句中的本地变量被认为是不被优化器知道和考虑的,例外的情况是定义为储备过程输入参数的变量。


    6.如果没有包含合并子句的索引,那么优化器构造1个工作表以存放合并中最小的表中的行。然后再在这个表上构造1个分簇索引以完成一个高效的合并。这种作法的代价是工作表的生成和随后的分族索引的生成,这个过程叫REFORMATTING。  所以应该注意RAM中或磁盘上的数据库tempdb的大小(除了SELECT INTO语句)。另外,如果这些类型的操作是很常见的,那么把tempdb放在RAM中对于提高性能是很有好处的。


    4 性能优化的其他考虑


    上面列出了影响SQL Server的一些主要因素,实际上远不止这些。操作系统的影响也很大,在Windows NT下,文件系统的选择、网络协议、开启的服务、SQL Server的优先级等选项也不同程度上影响了SQL Server的性能。


    影响性能的因素是如此的多,而应用又各不相同,找出1个通用的优化方案是不现实的,在系统开发和维护的过程中必须针对运行的情况,不断加以调整。事实上,绝大部分的优化和调整工作是在与客户端独立的服务器上进行的,因此也是现实可行的。

  • SQL Server数据库性能优化

    2007-01-06 12:41:09

    数据库是企业信息的核心,其应用水平的高低直接影响到企业管理水平。选择了 一个高性能的数据库产品不等于就有一个好的数据库应用系统,如果数据库系统 设计不合理,不仅会增加客户端和服务器端程序的编程和维护的难度,而且还会 影响系统实际运行的性能。一般来讲,在一个管理信息系统的分析、设计、测试 和试运行阶段,因为数据量较小,设计人员和测试人员往往只注意到功能的实 现,而很少会注意到性能的不足,等到系统投入实际运行一段时间后,才发现系 统的性能在降低,这时再来考虑提高系统性能则要花费更多的人力、物力,而其 最终结果就是给整个系统又打上了一个补丁,所以设计阶段是优化的重点。本文 以SQL Server数据库为例,从以下几个方面讨论如何实现数据库系统的性能优 化。 数据库设计 实现SQL Server数据库的优化,首先要有一个好的数据库设计方案。在实际工作 中,许多SQL Server方案往往是由于数据库设计得不好导致性能很差。实现良好 的数据库设计必须考虑这些问题: 1. 逻辑数据库规范化问题 一般来说,逻辑数据库设计会满足规范化的前3级标准: 第1规范:没有重复的组或多值的列; 第2规范: 每个非关键字段必须依赖于主关键字,不能依赖于一个组合式主关键字 的某些组成部分; 第3规范: 一个非关键字段不能依赖于另一个非关键字段。 遵守这些规则的数据库设计会产生较少的列和更多的表,因而也就减少了数据冗 余,也减少了用于存储数据的页。 2. 生成物理数据库 要想正确选择基本物理实现策略,必须了解和利用好数据库访问格式和硬件资源 的操作特点,特别是内存和磁盘子系统I/O。以下是一些常用技巧: 与每个表列相关的数据类型应该反映数据所需的最小存储空间,特别是对于被索 引的列更是如此。比如能使用smallint类型就不要用integer类型,这样索引字段 可以被更快地读取,而且可以在一个数据页上放置更多的数据行,因而也就减少 了I/O操作。 把一个表放在某个物理设备上,再通过SQL Server的段把它的不分簇索引放在一 个不同的物理设备上,这样能提高性能。尤其是系统采用了多个智能型磁盘控制 器和数据分离技术的情况下,这样做的好处更加明显。 用SQL Server段把一个频繁使用的大表分割开,并放在多个单独的智能型磁盘控 制器的数据库设备上,这样也可以提高性能。因为有多个磁头在查找,所以数据 分离也能提高性能。 用SQL Server段把文本或图像列的数据存放在一个单独的物理设备上可以提高性 能。一个专用的智能型的控制器能进一步提高性能。 应用系统设计 在应用系统的设计中,要着重考虑以下几点: 1.合理使用索引 索引是数据库中重要的数据结构,它的根本目的就是提高查询效率。索引的使用 要恰到好处,其使用原则如下: 在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则 由优化器自动生成索引;在频繁进行排序或分组(即进行group by或order by操 作)的列上建立索引;在条件表达式中经常用到的不同值较多的列上建立索引, 在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两 个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而 会严重降低更新速度。 如果待排序的列有多个,可以在这些列上建立复合索 引。 2. 避免或简化排序 应当尽量简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次 序产生输出时,优化器就避免了排序这个步骤。为了避免不必要的排序,就要正 确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于 效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序 的列的范围等。 3.消除对大型表行数据的顺序存取 在嵌套查询中,表的顺序存取对查询效率可能产生致命的影响。我们有时可以使 用并集来避免顺序存取。尽管也许在所有的检查列上都有索引,但某些形式的 where子句会强迫优化器使用顺序存取,这一点也应注意。 4. 避免相关子查询 如果一个列同时在主查询和where子句中出现,很可能当主查询中的列值改变之 后,子查询必须重新查询一次。而且查询嵌套层次越多,效率越低,因此应当尽 量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。 5.避免困难的正规表达式 Mathes和Like关键字支持通配符匹配,但这种匹配特别耗时。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”,即使在zipcode字段上已建立 了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为:SELECT * FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查 询,显然会大大提高速度。 6.使用临时表加速查询 把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排 序操作,而且在其他方面还能简化优化器的工作。临时表中的行要比主表中的行 少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得 到大幅减少。但要注意,临时表创建后不会反映主表的修改。在主表中数据频繁 修改的情况下,注意不要丢失数据。 操作系统相关优化 操作系统性能的好坏直接影响数据库的使用性能,如果操作系统存在问题,如 CPU过载、过度内存交换、磁盘I/O瓶颈等,在这种情况下,单纯进行数据库内部 性能调整是不会改善系统性能的。我们可以通过Windows NT的系统监视器 (System Monitor)来监控各种设备,发现性能瓶颈。 CPU 一种常见的性能问题就是缺乏处理能力。系统的处理能力是由系统的CPU数 量、类型和速度决定的。如果系统没有足够的CPU处理能力,它就不能足够快地 处理事务以满足需要。我们可以使用System Monitor确定CPU的使用率,如果以 75%或更高的速率长时间运行,就可能碰到了CPU瓶颈问题,这时应该升级 CPU。但是升级前必须监视系统的其他特性,如果是因为SQL语句效率非常低, 优化语句就有助于解决较低的CPU利用率。而当确定需要更强的处理能力,可以 添加CPU或者用更快的CPU 替换。 内存 SQL Server可使用的内存量是SQL Server性能最关键因素之一。而内存同 I/O子系统的关系也是一个非常重要的因素。例如,在I/O操作频繁的系统中, SQL Server用来缓存数据的可用内存越多,必须执行的物理I/O也就越少。这是 因为数据将从数据缓存中读取而不是从磁盘读取。同样,内存量的不足会引起明 显的磁盘读写瓶颈,因为系统缓存能力不足会引起更多的物理磁盘I/O。 可以利用System Monitor检查SQL Server的Buffer Cache Hit Ratio计数器,如果 命中率经常低于90%,就应该添加更多的内存。 I/O子系统 由I/O子系统发生的瓶颈问题是数据库系统可能遇到的最常见的同硬件 有关的问题。配置很差的I/O子系统引起性能问题的严重程度仅次于编写很差的 SQL语句。I/O子系统问题是这样产生的,一个磁盘驱动器能够执行的I/O操作是 有限的,一般一个普通的磁盘驱动器每秒只能处理85次I/O操作,如果磁盘驱动 器超载,到这些磁盘驱动器的I/O操作就要排队,SQL的I/O延迟将很长。这可能 会使锁持续的时间更长,或者使线程在等待资源的过程中保持空闲状态,其结果 就是整个系统的性能受到影响。 解决I/O子系统有关的问题也许是最容易的,多数情况下,增加磁盘驱动器就可 以解决这个性能问题。 当然,影响性能的因素很多,而应用又各不相同,找出一个通用的优化方案是很 困难的,只能是在系统开发和维护的过程中针对运行的具体情况,不断加以调 整
  • 数据库性能提升四要决

    2007-01-06 12:38:27

    数据库性能提升四要诀

      作者:黄财军           http://www.landiy.net/

    数据库性能提升四要诀
     
     
      这是一个常见错误:一家公司将一个性能不佳的数据库放到数量越来越多的服务器上,在投入越来越多的资金的同时犯同样的错误,但是数据库性能从未得到改善。许多性能问题源于一些基本问题。首先,雇用一位真正的DBA(数据库管理员)。如果你打算投入更多的钱来解决问题,那就将钱用在能对你有所帮助的地方。如果你承担不起雇用DBA的费用,那么请看看以下这些简单但却可以帮助你提升性能的极为有效的技术。
     
      将数据和日志文件分别保存在不同的硬盘上
     
      这些硬盘必须是物理硬盘(或磁盘阵列),而非只是逻辑分区。所有的数据库都具有数据和日志文件,并且没有一家厂商找到了解决将这些文件放在相同物理卷上而造成的硬盘争用问题的灵丹妙药。例如,如果你想在Windows环境中证实这点,可以调用Performance Monitor,查看“PhysicalDisk\Avg Disk Queue Length”(物理盘\平均硬盘队列长度)。这时的一个经验法则是每个处理器保持的队列长度不要超过两个。因此,如果服务器上有两个处理器,那么你保持的硬盘队列不应当超过4个。
     
      检查索引和查询
     
      数据库中90%的性能问题与索引/查询有关。开发人员常常编写一些可怕的查询,这些查询完全没有经过检查就被投入到生产应用中。一些最糟的查询包括:在只需要返回很少几列结果时却返回所有的列的查询、搜索标准逻辑过于复杂的查询、过多表格的查询(4个表格是合理的上限)。一些开发人员常常在建立生产数据库的索引时未经过深思熟虑。三种糟糕的索引是:没有足够的索引,过多的索引以及不正确的索引。一种分辨你是否使用有效索引的办法是将数据库的缓冲区缓存与过程缓存进行比较。如果过程缓存看起来越变越大,查询计划很可能没有被缓存。在这种情况下,就应当重新检查存储过程的重编译和执行计划的使用。另一个需要检查的指标是数据库的缓冲区管理器/页寿命期望值计数器。平均值越低,你就越可能遇到查询没有保存在缓存中的问题。
     
      掌握服务器的内存情况
     
      数据库服务器上的其他进程的内存泄漏也是常见问题。监测数据库的目标服务器内存计数器,将使你掌握从数据库中被偷走的内存量。当出现真正的内存泄漏时,其表现为目标服务器内存的不断减少。
     
      为数据库服务器建立基线和基准测试
     
      你必须全面掌握数据库的正常性能,这样才能知道它达没达到峰值。然后,将你的基准测试与基线进行比较,就会发现执行计划使用率、存储过程再编译、内存、硬盘与CPU队列以及空间使用率的变化。在检查基准测试后,你可能需要升级硬件,但是在没有获得支持你做出购买决定的可靠的数字前,不要购买任何硬件。否则,你会花很多钱,但仍没有解决问题。

  • 最大化J2EE和数据库交互操作的性能

    2007-01-06 12:35:38

    概述:大多数应用程序性能管理(APM)解决方案都只考虑和分析J2EE应用程序的某个层次的性能问题。这种方法不足以解决架构复杂的应用程序的性能问题。良好的APM工具应该能够让你从J2EE层深入到数据库层以确保性能问题被快速地解决。

    情况并非越来越好,公司的网站性能下降到了极低点,失落的客户开始寻找其它厂商了。IT调查机构开始调查并且认为J2EE应用程序是响应时间较差的罪魁祸首。这立即给J2EE开发小组带来了很大的压力,他们必须确定并解决这个问题。

    J2EE开发小组在进行了一些最初的调查之后,他们认为问题并不是出在J2EE层,而是一直可以跟踪到数据库中。但是数据库小组反驳说问题实际出在J2EE层。相互之间的责备不断增加,小组合作精神消失了,混乱开始流行,客户和收入持续减少。

    上面的这种情况突出了一个重大需求:为了支撑J2EE和数据库层之间更好的交互操作能力,IT部门必须能够快速和果断地做出决定。

    基本的挑战:找出问题的起因

    当响应时间的延迟赶走了Web站点的用户的时候,J2EE开发者就不得不加入这个相互责备的游戏中了。在中间层开发应用程序的程序员必须与数据库交互操作,当性能瓶颈出现的时候,如果数据库是下层的起因,问题也显示在J2EE层。其实真正的问题在于交互操作。如何最好地调节这两个层次之间的综合关系以获取应用程序的最佳性能?更深入一点,如何查看这些瓶颈、识别真正的问题起因,并尽可能快地处理这些问题呢?

    很多APM(应用程序性能管理)工具都可以辅助我们识别和解决这些性能问题。查找J2EE应用程序中的瓶颈的最常用的两种方法是:

    1、使用带不同颜色警报的仪表程序来监视系统的状态。绿色的意思是良好的,黄色或红色意味着你必须处理性能问题了。这个仪表程序还可以报告系统中不同的组件的响应时间。

    2、不是等待性能恶化到一定程度才去跟踪仪表程序的警告信息,而是采用预先防护的方法并试图识别出过多的响应时间或资源使用。你可以通过检查顶层服务请求(根据响应时间)并进一步分析它们调用了什么组件来实现这样的操作。

    假设有一个银行系统。一个查看帐户信息的顾客访问了你的Web站点以获取过去七天自己的帐户的概要信息。该顾客点击了"获取帐户概要信息"链接。

    获取帐户概要信息的过程是通过Web浏览器调用某个特定的URL来完成的。当然,在下层,它调用了很多组件,这些组件交互操作来提供正确的输出信息。在查找瓶颈的过程中,你从顶层的调用(可能是doGet()或doPost()方法)开始,循着调用树查看"获取帐户概要信息"服务调用的所有组件,接着查看这些组件所调用的组件,一直到最底层,在很多情形中,它可能是使用JDBC(Java数据库连接)调用数据库的SQL语句。

    你必须知道这些组件中哪些花费的时间过长了,但是采用这种方式逐步分析的时候会花费很多时间,经历很多烦心的过程,在你对它们中个别角色不是太熟悉的时候尤其如此。你必须查看每个组件,并询问自己它花费的时间是否太长?用10秒钟来生成输出信息以响应 "获取帐户概要信息" 是必须的吗?你也不是特别肯定,因为如果要了解这些信息的话,你必须知道下层的每个方法或程序组件是如何运行的细节信息。唯一知道这些信息的人恐怕只有某个特定组件的开发人员。如果你怀疑问题出在数据库的响应时间上,那么就需要联系数据库小组进一步研究这个问题。 隔离SQL语句

    假设检索帐户信息花费了太长的时间。每个请求帐户概要信息的用户需要等待15秒才会有响应。那么问题会出在数据库一方吗?有没有可能是应用程序代码的问题?网络的问题?甚至于可能是该用户的互联网连接太慢的问题呢?

    但是,在这种情况下你如果怀疑是数据库检索的问题就是应该受到责备的。查找起因的一个方法是让APM工具显示应用程序发出的所有SQL语句,按照响应时间进行排序,这样你就可以看到某个SQL语句是否因为出错的原因花费了太长时间(有些SQL语句会花费很长时间--例如按帐户检索一年内所有事务的列表)。

    现在你查看一下位于列表顶部的SQL语句。它进入数据库并花费了1秒钟响应。这样的性能不是太差;如果这是性能最差的SQL语句,那么问题可能根本不在SQL语句中。因此,接下来的问题是:是不是应用程序层出了什么问题呢?谁在调用这个语句?调用了多少次?如果某个应用程序调用SQL语句的次数超过了你的预期,你就有理由怀疑应用程序出了故障。

    APM工具这次又可以帮助你了。你可以简单地点击该SQL语句,会出现一个链接,显示出它的整个调用树,从顾客请求帐户概要信息开始,到进入数据库的SQL语句为止。现在你拥有了两部分信息:你能肯定自己在查看该服务请求的某个特定请求;你可以看到每个独立的组件对响应时间的影响。

    现在你可以查看调用该SQL语句的组件说明,并且你发现它的响应时间是9秒钟。很明显,它是造成客户等待15秒钟的主要因素。APM工具显示的列表同时显示出这个组件7次调用了该SQL语句。这就告诉你9秒中大部分是调用SQL语句消耗的。该组件不仅执行了过多的计算,还多次调用了SQL语句。这样的操作可能有些很好的原因,但是任何性能管理工具都不能说明其起因。最重要的是你已经指出了必须进行调查的程序组件。良好的APM工具还可以为解决这个问题提供一些建议。

      真的是数据库的问题吗?

      让我们从另一个角度来看这个问题。假设该组件并没有多次调用SQL语句,它只调用了一次,但是这次调用却消耗了15秒中的大部分。现在的问题是,为什么单个语句需要那么长时间执行呢?这个问题不在代码中,因此它可能在数据库那一端。

      你现在需要的是性能管理工具允许你对特定服务请求(获取帐户概要信息)的调查深入到数据库层。请返回你得到的SQL语句列表,点击你感兴趣的SQL语句的链接,它会把你从J2EE端带到数据库端。现在你在查看Oracle数据库或其它数据库产品环境中的SQL语句。该工具可能帮助你查明数据库端的问题,还可能提供一些专业的调整建议,数据库管理员(DBA)可以使用这些建议来提高数据库的性能。问题可能出在存放数据表空间的磁盘性能较差,建议把它移动到另一个磁盘上;也可能是丢失了某个索引,你可以通过建立新索引来提高速度;也许是数据库上并行运行了太多的线程,你必须对这些线程进行隔离以减少并发性问题。

      还有其它一些可能性。数据检索可能花费太多的时间,因为花费了很长时间等待获取数据库连接。代码是良好的,数据库运行也正常,但是这样的等待时间可能告诉你数据库连接池不够大,无法处理大量的甚至于正常的通讯。你可以查询应用程序服务器,了解已经定义了多少个连接,把这个数字与典型的并发请求数进行对比,很快就可以确定是否需要更多的连接了。

      提高交互操作能力

      你的性能管理工具不仅需要识别出J2EE层响应时间的构成因素。它还应该能够让你看到J2EE层和相邻的数据库层之间的交互操作情况,并为分析这两个层次上的性能问题提供方法。为了高效率地处理性能问题,J2EE开发者和DBA使用综合的APM产品是必要的。它同时还让J2EE和数据库小组"用同一种语言说话"。大多数APM解决方案的目标都是架构体系中的单个层次,为单个层次提供诊断信息。使用这种方法的时候,时间会浪费、相互的责备会形成风暴、而且经常还是无从解决问题。今天复杂的架构和老练的技术意味着某个层次与其它层次之间的交互操作所导致的性能问题用这种途径是无法定位的。现在我们能够使用的最主流的APM工具允许我们从J2EE层跟踪到数据库层,以确保及时地解决性能问题,而不论问题来自于哪个层次。

      结论

      提高J2EE层和数据库层之间的交互操作能力带来了明显的优势:加快最终用户的响应时间、增加顾客的忠诚度、提高士气、服务的底线也更高了。现在我们可以使用的高级工具填补了J2EE层和数据库层之间的裂痕,自动地搜索瓶颈,查明起因,并为解决问题提供专门的建议。每个J2EE开发小组都应该认真地考虑这些综合的APM工具给它们的生产带来的价值。
  • Oracle数据库性能优化技术

    2007-01-06 12:19:20

     摘要: Oracle数据库是当前应用最广泛的大型数据库之一,而其性优化直接关系到系统的运行效率。本文以数据库性能优化的基本原则为出发点,阐述了在数据库设计阶段如何避免竞争和如何优化数据访问,在数据库运行阶段如何从操作系统和数据库实例级别上调整内存和I/O来达到数据库性能优化的各种技术。

      关键词:Oracle数据库;性能优化;内存;I/O

      1. 引言

      随着网络应用和电子商务的不断发展,各个站点的访问量越来越大,数据库规模也随之不断的扩大,数据库系统的性能问题就越来越突出,因此,如何对数据库进行调优至关重要:如何使用有限的计算机系统资源为更多的用户服务?如何保证用户的响应速度和服务质量?这些问题都属于服务器性能优化的范畴。

      作为全球第一大数据库厂商,Oracle数据库在国内外获得了诸多成功应用,据统计,全球93%的上市.COM公司、65家"财富全球100强"企业不约而同地采用Oracle数据库来开展电子商务。我国很多企业、政府单位及电子商务网站也采用了Oracle作为数据库服务器。Oracle数据库服务器是高度可优化的软件产品,经常性的调整可以优化应用系统的性能,防止出现系统瓶颈。

      数据库性能优化的基本原则就是:通过尽可能少的磁盘访问获得所需要的数据。要评价数据库的性能,需要在数据库调节前后比较其评价指标:响应时间和吞吐量之间的权衡、数据库的可用性、数据库的命中率以及内存的使用效率,以此来衡量调节措施的效果和指导调整的方向。

      对Oracle数据库进行性能调整时,应当按照一定的顺序进行,因为系统在前面步骤中进行的调整可以避免后面的一些不必要调整或者代价很大的调整。一般来说可以从两个阶段入手:

      1、设计阶段:对其逻辑结构和物理结构进行优化设计,使之在满足需求条件的情况下,系统性能达到最佳,系统开销达到最小;

      2、数据库运行阶段:采取操作系统级、数据库级的一些优化措施来使系统性能最佳;
       2. 在系统设计开发阶段调整数据库

      为了充分利用Oracle数据库的功能特性,在设计信息系统时,数据库设计人员需要根据业务情况(如访问量或客户端数量)和现有资源状况(如数据库服务器的配置)考虑系统结构和数据库的逻辑结构的设计:

      2.1调整应用程序结构设计。

      即应用程序采用的是传统的C/S两层体系结构,还是B/W/D三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。

      2.2恰当使用分区、索引及存档功能。

      如果某种业务的数据量增长非常快,可以考虑存放该业务的数据库表是否使用Oracle数据库的分区功能;对于经常访问的数据库表是否需要建立索引;对于经常访问但是当业务流程完成后不再变动的数据可采用放入历史档案的方法来实现应用系统中访问尽可能少的数据量。

      2.3恰当编写访问数据的SQL语句。

      良好的SQL语句可以被数据库重复使用而减少分析时间;恰当的使用索引可使访问的数据块大大减少从而减少响应时间。应用程序的执行最终将归结为数据库中的SQL语句执行,因此SQL语句的执行效率决定了Oracle数据库的性能。Oracle公司推荐使用Oracle语句优化器(Oracle Optimizer)和行锁管理器(row-level manager)来调整优化SQL语句。

      2.4调整硬盘I/O

      这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上,做到硬盘之间I/O负载均衡。在磁盘比较富裕的情况下还应该遵循以下原则:

       将表和索引分开;

       创造用户表空间,与系统表空间(system)分开磁盘;

       创建表和索引时指定不同的表空间;

       创建回滚段专用的表空间,防止空间竞争影响事务的完成;

       创建临时表空间用于排序操作,尽可能的防止数据库碎片存在于多个表空间中。

      2.5确定数据块大小和存储参数。

      由于数据库的块大小在数据库创建以后就不能在修改(除非重建数据库),因此为了减少数据链接和行迁移,又提高磁盘空间的利用率,在设计数据库时要确定合适的数据块大小和存储参数。通常我们是根据样例数据确定数据块大小,而根据业务现状和未来发展趋势确定存储参数。

      3. 在数据库运行阶段调整数据库

      数据库运行阶段调整数据库包括两个方面:操作系统级的调整;数据库级的调整。

      3.1 操作系统级的调整

      实施操作系统级调整的主要目的是减少内存交换,减少分页,使SGA(System Globle Area)可留驻内存。

      3.1.1减少内存交换

      内存交换(swapping)可能会造成很大的内存开销,应将它最小化。运行在Solaris Unix操作系统上的Oracle数据库,可利用vmstat或sar命令来检查交换,查看到系统级内存和硬盘I/O的使用情况,调整unix数据缓冲池的大小、每个进程所能使用的内存大小等参数。

       vmstat命令

      它报告Solaris上的进程、虚拟内存、磁盘、分页和CPU的活动情况。下面命令将显示系统每5秒钟做的事情的概要:
    % vmstat 5

       sar命令

      用于监控交换、分页、磁盘和CPU活动。下面命令用于每10秒显示10次分页活动的概要:
    % sar -p 10 10

      若系统内存交换较多,且需要节省内存,可采用以下措施:

      1) 避免运行不必要的系统daemon进程或应用程序进程;

      2) 在不明显影响数据块命中率的前提下减少数据库缓冲区的数量,以释放一些内存;

      3) 减少UNIX文件缓冲区的数量(特别是在使用裸设备时)。

      3.1.2控制分页

      少量的内存分页不会太显著地影响系统的性能,因为应用程序不必全部放在内存中。但是分页过多将会造成系统性能下降。为了检测过多的分页,可在快速响应或空闲期间运行测量,并与响应迟缓时的测量进行比较。可通过以下办法来解决:

       使用vmstat或sar -p监控分页;

        安装更多的内存;

        将一些工作移到另一系统中;

        配置系统核心使用更少的内存;

        保持SGA在单个共享内存段中。

      3.1.3使SGA(System Globle Area)留驻内存

      SGA是对数据库数据进行快速访问的一个系统全局区,若SGA本身需要频繁地进行释放、分配,则不可能达到快速访问数据的目的,因此,要求SGA驻留内存。这时,我们可以重新配置UNIX核心,调整一些操作系统参数以达到增加共享内存的目的。

      3.2 数据库级的调整

      每一个Oracle实例都是由一组Oracle后台进程和SGA的一个内存区组成的。这组后台进程会自动的读写数据库的数据文件,因此,数据库性能可以被这些因素所影响:SGA各部分的分配是否合理,使用效率是否正常;I/O和锁竞争是否较多。

      3.2.1 SGA的分配及使用效率

      分配给每个实例的内存,即SGA的使用效率如何,会大大影响数据库系统的性能。SGA由下列部分组成:共享池、数据块缓冲区、重做日志缓冲区、大池组成。

      l 共享池(Shared pool)

      共享池存放库缓存(存储共享SQL和PL/SQL区)和数据字典缓存(数据库对象信息)以及会话期间信息(对于MTS)。由于这些信息是应用程序需要经常访问的,因此这些信息需要保持高的命中率。可以通过以下语句来确认共享池数据的命中率:

      库缓存:

    select gethitratio from v$librarycache 应大于90%
    select sum(reloads)/sum(pins) from v$librarycache 应小于1%

      数据字典缓存:

    select sum(getmisses)/sum(gets) from v$rowcache 应小于15%

      由于程序设计人员的水平参差不齐,可能存在大的匿名块,这会导致SQL不能重用,因此需要找出大的匿名块以转换为存储过程达到重用:

    select * from v$sqlarea where command_type=47 and length(sql_text)>500

      而对于一些应用系统非常频繁使用的SQL对象如存储过程、函数、包等,可以通过钉在内存中的方式来防止由于共享池太小被移出:

    exec dbms_shared_pool.keep(对象名)

       数据块缓冲区(Db block buffer):

      数据块缓冲区存放用户所经常访问的数据文件的数据块内容以及用户修改的数据内容。数据库把数据文件里的内容读到内存中,下次需要时直接从内存中读取,从而减少了磁盘的I/O和响应时间。当然,一般只在比较小的数据表(如常用代码表)才缓存到内存中。

      由于数据快缓冲区中不可能存放所有的数据,因此可使用LRU算法来确定移出哪些数据块,但又尽量保证有较高的数据命中率。

      查看数据块命中率的SQL语句为:

    select 1-(phy.value/(cur.value+con.value)) from v$sysstat cur,v$sysstat con,v$sysstat phy
    where cur.name='db block gets' and con.name='consistent gets'
    and phy.name='physical gets'

      如果这个命中率小于0.85,就要考虑为数据块缓冲区分配更多的内存了。

       重做日志缓冲区(Log buffer):

      重做日志缓冲区存放从用户内存区复制来的每个DML或DDL语句的重做条目。如果这个缓冲区分配太小会导致没有足够的空间来放重做条目而等待。

      3.2.2 I/O和资源竞争

      由于有众多的进程要写数据文件,因此需要通过I/O调整来解决I/O瓶颈问题。如果在设计阶段有效地考虑了表空间的合理分配,就能有效地在一定程度上减少I/O竞争。在数据库运行时,由于数据的动态增长,原来分配给表或索引的空间已经用完,Oracle会自动分配空间给这些数据库对象。而这个动态分配会对系统性能有所影响,所以要求:

       避免动态空间管理

       表空间的本地化管理,以减少与数据字典表空间的磁盘竞争。

      在系统设计和试运行阶段数据量相对较小,效率低下的SQL可能并不会影响系统响应时间,但当系统数据量增长到一定程度时,需要在系统运行时监控并找出是哪些SQL不能有效使用索引或缺少索引,并进行相应调整:建立索引;修改SQL写法。

      另外,在Oracle中,需要采用一些机制来保证数据库对象在使用期间的稳定性和数据的一致性,如使用锁存器(latch)、锁(lock)等。因此争用和这些机制相关的资源会影响数据库的性能。为了减少这种资源竞争,可以通过调整数据库的相关初始化参数(如db_block_lru_latches、dml_locks)来减少资源的争用,优化数据库性能。

      4. 一些常用的性能优化手段和工具

      Oracle数据库系统提供了一些工具和脚本来获取数据库的性能指标和优化的方法。如使用utlbstat.sql和utlestat.sql脚本获取一段时间内数据库的内存、磁盘I/O等的情况;使用动态性能视图和数据字典视图来获取命中率和系统等待事件等信息。当然,也可以使用Oracle Enterprise Manager图形化工具来监控。

      5. 结束语

      Oracle数据库的性能调整相当重要,但难度也较大。数据库管理员需要综合运用上面介绍的规律,在数据库建立时,就能根据应用的需要合理设计分配表空间以及存储参数、内存使用初始化参数,对以后的数据库性能有很大的益处。只有认真分析Oracle运行过程当中出现的各种性能问题,才能保证Oracle数据库高效可靠地运行。还需要指出的是:数据库的性能调整是一个系统工程,涉及的方面很多,不能仅仅根据一个时间点的情况就断定数据库运行性能的好与坏。如何有效地进行调整,数据库管理员需要经过反反复复的过程。这些都需要在大量的实践工作中不断地积累经验,从而更好地进行数据库的调优。


  • SQL Server与Oracle、DB2的性能比较

    2007-01-06 12:09:29

    http://www.itisedu.com   2006-8-16 9:25:47   中科永联

    开放性   
      
      
    SQL Server只能在Windows 上运行,没有丝毫的开放性,操作系统的系统的稳定对数据库是十分重要的。Windows9X系列产品是偏重于桌面应用,NT server只适合中小型企业。而且Windows平台的可靠性,安全性和伸缩性是非常有限的。它不象Unix那样久经考验,尤其是在处理大数据量的关键业务时。
      
      
    Oracle能在所有主流平台上运行(包括 Windows)。完全支持所有的工业标准。采用完全开放策略。可以使客户选择最适合的解决方案。对开发商全力支持。
      
      
    DB2能在所有主流平台上运行(包括Windows)。最适于海量数据。DB2在企业级的应用最为广泛,在全球的500家最大的企业中,几乎85%以上用DB2数据库服务器,而国内到97年约占5%。

      可伸缩性,并行性   
      
      
    SQL Server并行实施和共存模型并不成熟。很难处理日益增多的用户数和数据卷。伸缩性有限。

      Oracle平行服务器通过使一组结点共享同一簇中的工作来扩展Window NT的能力,提供高可用性和高伸缩性的簇的解决方案。如果WindowsNT不能满足需要, 用户可以把数据库移到UNIX中。
        
      DB2具有很好的并行性。DB2把数据库管理扩充到了并行的、多节点的环境。数据库分区是数据库的一部分,包含自己的数据、索引、配置文件、和事务日志。数据库分区有时被称为节点或数据库节点。

      安全性
      
      SQL server 没有获得任何安全证书。
      
      Oracle Server获得最高认证级别的ISO标准认证。
      
      DB2获得最高认证级别的ISO标准认证。

      性能
      
      SQL Server 多用户时性能不佳
      
      Oracle性能最高, 保持WindowsNT下的TPC-D和TPC-C的世界记录。
       
      DB2适用于数据仓库和在线事物处理,性能较高。

      客户端支持及应用模式
      
      SQL Server C/S结构,只支持Windows客户,可以用ADO,DAO,OLEDB,ODBC连接。
      
      Oracle多层次网络计算,支持多种工业标准,可以用ODBC,JDBC,OCI等网络客户连接。
      
      DB2跨平台,多层结构,支持ODBC,JDBC等客户。

      操作简便
      
      SQL Server 操作简单,但只有图形界面。
      
      Oracle较复杂, 同时提供GUI和命令行,在Windows NT和Unix下操作相同。
      
      DB2操作简单,同时提供GUI和命令行,在Windows NT和Unix下操作相同。

      使用风险

      SQL Server 完全重写的代码,经历了长期的测试,不断延迟,许多功能需要时间来证明。并不十分兼容早期产品。使用需要冒一定风险。
      
      Oracle长时间的开发经验,完全向下兼容。得到广泛的应用。完全没有风险。
      
      DB2在巨型企业得到广泛的应用,向下兼容性好。风险小。

  • Oracle安全全接触(完整版)

    2007-01-06 12:06:33

      出处:《黑客X档案》

     随着计算机的普及以及网络的发展,数据库已经不再仅仅是那些程序员所专有的话题。而Oracle数据库更是凭借其性能卓越,操作方便灵活的特点,在数据库的市场中已经占据了一席之地。但是同样随着网络技术的不断进步,数据信息的不断增加,数据安全已经不再是以前的“老生长谈”,也更不是以前书本上那些“可望不可及”的条条框框。

      或许很久以前,大家都觉得Oracle数据库的安全并不存在隐患,因为Oracle公司在去年11月份开始促销其数据库软件时提出的口号是“只有Oracle9i能够做到绝对安全”。但是不管它这么说是为了促销,还是为了扩大知名度,总之伴去年12 月份,英国的安全专家 David Litchfield 发现的9iAS 中存在的程序错误导致的缓冲溢出漏洞以及后来,PenTest Limited 和 eEye Digital Security 各自提出了一个小的漏洞,所有使用Oracle公司产品的人都不由地紧张了原本松弛的大脑--这个对于用户来说,毕竟关系到了自己的“身家性命”。

      下面笔者将带着大家走进Oracle数据安全的世界。由于笔者水平有限,所以不足之处在所难免,望大家不吝赐教。

      (一)Oracle数据库的一些基本常识

      这里仅仅是为了以后的安全奠定一些基础,因为我们后面要用到它们。

      1.Oracle所包含的组件:

      在 Oracle,数据库是指整个 Oracle RDBMS 环境,它包括以下组件:

      ·Oracle 数据库进程和缓冲(实例)。

      ·SYSTEM 表空间包含一个集中系统类目,它可以由一个或多个数据文件构成。

      ·其它由数据库管理员 (DBA)(可选)定义的表空间,每个都由一个或多个数据文件构成。

      ·两个以上的联机恢复日志。

      ·归档恢复日志(可选)。

      ·其它文件(控制文件、Init.ora、Config.ora 等)。

      每个 Oracle 数据库都在一个中央系统类目和数据字典上运行,它位于SYSTEM 表空间。

      2.关于“日志”

      Oracle数据库使用几种结构来保护数据:数据库后备、日志、回滚段和控制文件。下面我们将大体上了解一下作为主要结构之一的“日志”:

      每一个Oracle数据库实例都提供日志,记录数据库中所作的全部修改。每一个运行的Oracle数据库实例相应地有一个在线日志,它与Oracle后台进程LGWR一起工作,立即记录该实例所作的全部修改。归档(离线)日志是可选择的,一个Oracle数据库实例一旦在线日志填满后,可形成在线日志归档文件。归档的在线日志文件被唯一标识并合并成归档日志。

      ·关于在线日志:一个Oracle数据库的每一实例有一个相关联的在线日志。一个在线日志由多个在线日志文件组成。在线日志文件(online redo log file)填入日志项(redo entry),日志项记录的数据用于重构对数据库所作的全部修改。

      ·关于归档日志:Oracle要将填满的在线日志文件组归档时,则要建立归档日志(archived redo log)。其对数据库备份和恢复有下列用处:

      <1>数据库后备以及在线和归档日志文件,在操作系统和磁盘故障中可保证全部提交的事物可被恢复。

      <2>在数据库打开和正常系统使用下,如果归档日志是永久保存,在线后备可以进行和使用。

      数据库可运行在两种不同方式下:NOARCHIVELOG方式或ARCHIVELOG 方式。数据库在NOARCHIVELOG方式下使用时,不能进行在线日志的归档。如果数据库在ARCHIVELOG方式下运行,可实施在线日志的归档。

      3.物理和逻辑存储结构:

      Oracle RDBMS是由表空间组成的,而表空间又是由数据文件组成的。表空间数据文件被格式化为内部的块单位。块的大小,是由DBA在Oracle第一次创建的时候设置的,可以在512到8192个字节的范围内变动。当一个对象在Oracle表空间中创建的时候,用户用叫做长度的单位(初始长度((initial extent)、下一个长度(next extent)、最小长度(min extents)、以及最大长度(max extents))来标明该对象的空间大小。一个Oracle长度的大小可以变化,但是要包含一个由至少五个连续的块构成的链。

      4.Oracle与Microsoft SQL Server比较下的联网协议:

      (二)Oracle数据安全的维护

      记得某位哲学家说过:“事物的变化离不开内因和外因。”那么对于Oracle数据安全这个话题而言,也势必分为“内”和“外”两个部分。那么好,我们就先从“内”开始说起:

      §1.从Oracle系统本身说起

      我们先抛开令人闻风色变的“hacker”和其他一些外部的原因,先想一下我们的数据库。什么硬盘损坏,什么软件受损,什么操作事物……一系列由于我们的“疏忽”而造成的系统问题就完全可以让我们辛苦建立的数据库中的数据一去不复返。那么,我们就先从自己身上找找原因吧。

      【一】解决系统本身问题的方法--数据库的备份及恢复

      ·数据库的备份:

      关于Oracle数据库的备份,标准地有三中办法:导出/导入(Export/Import)、冷备份、热备份。导出备份是一种逻辑备份,冷备份和热备份是物理备份。

      <1>导出/导入(Export/Import)

      利用Export可将数据从数据库中提取出来,利用Import则可将提取出来的数据送回Oracle数据库中去。

      a.简单导出数据(Export)和导入数据(Import)

      Oracle支持三种类型的输出:

      (1)表方式(T方式),将指定表的数据导出。

      (2)用户方式(U方式),将指定用户的所有对象及数据导出。

      (3)全库方式(Full方式),将数据库中的所有对象导出。

      数据导出(Import)的过程是数据导入(Export)的逆过程,它们的数据流向不同。

      b.增量导出/导入

      增量导出是一种常用的数据备份方法,它只能对整个数据库来实施,并且必须作为SYSTEM来导出。在进行此种导出时,系统不要求回答任何问题。导出文件名缺省为export.dmp,如果不希望自己的输出文件定名为export.dmp,必须在命令行中指出要用的文件名。

      增量导出包括三个类型:

      (1)“完全”增量导出(Complete)

      即备份整个数据库,比如:

      $exp system/manager inctype=complete file=990702.dmp

      (2)“增量型”增量导出

      备份上一次备份后改变的数据。比如:

      $exp system/manager inctype=incremental file=990702.dmp

      (3)“累计型”增量导出(Cumulative)

      累计型导出方式只是导出自上次“完全” 导出之后数据库中变化了的信息。比如:

      $exp system/manager inctype=cumulative file=990702.dmp

      数据库管理员可以排定一个备份日程表,用数据导出的三个不同方式合理高效地完成。比如数据库的备份任务可作如下安排:

      ·星期一:完全导出(A)

      ·星期二:增量导出(B)

      ·星期三:增量导出(C)

      ·星期四:增量导出(D)

      ·星期五:累计导出(E)

      ·星期六:增量导出(F)

      ·星期日:增量导出(G)

      如果在星期日,数据库遭到意外破坏,数据库管理员可按以下步骤来恢复数据库:

      第一步:用命令CREATE DATABASE重新生成数据库结构;

      第二步:创建一个足够大的附加回段。

      第三步:完全增量导入A:

      $imp system./manager inctype= RECTORE FULL=Y FILE=A

      第四步:累计增量导入E:

      $imp system/manager inctype= RECTORE FULL=Y FILE =E

      第五步:最近增量导入F:

      $imp system/manager inctype=RESTORE FULL=Y FILE=F

      <2>冷备份

      冷备份发生在数据库已经正常关闭的情况下,当正常关闭时会提供给我们一个完整的数据库。冷备份是将关键性文件拷贝到另外位置的一种说法。对于备份Oracle信息而言,冷备份是最快和最安全的方法。冷备份的优点是:

      ·是非常快速的备份方法(只需拷贝文件)

      ·容易归档(简单拷贝即可)

      ·容易恢复到某个时间点上(只需将文件再拷贝回去)

      ·能与归档方法相结合,作数据库“最新状态”的恢复。

      ·低度维护,高度安全。

      但冷备份也有如下不足:

      ·单独使用时,只能提供到“某一时间点上”的恢复。

      ·在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。

      ·若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。

      ·不能按表或按用户恢复。

      如果可能的话(主要看效率),应将信息备份到磁盘上,然后启动数据库(使用户可以工作)并将所备份的信息拷贝到磁带上(拷贝的同时,数据库也可以工作)。冷备份中必须拷贝的文件包括:

      ·所有数据文件

      ·所有控制文件

      ·所有联机REDO LOG文件

      ·Init.ora文件(可选)

      值得注意的是冷备份必须在数据库关闭的情况下进行,当数据库处于打开状态时,执行数据库文件系统备份是无效的

      下面是做冷备份的完整例子:

      (1) 关闭数据库$sqldba lmode=y

      SQLDBA >connect internal;

      SQLDBA >shutdown normal;

      (2) 用拷贝命令备份全部的时间文件、重做日志文件、控制文件、初始化参数文件

      SQLDBA >! cp < file > < backup directory >

      (3) 重启Oracle数据库

      $sqldba lmode=y

      SQLDBA >connect internal;

      SQLDBA >startup;

      <3>热备份

      热备份是在数据库运行的情况下,采用archivelog mode方式备份数据的方法。所以,如果你有昨天夜里的一个冷备份而且又有今天的热备份文件,在发生问题时,就可以利用这些资料恢复更多的信息。热备份要求数据库在Archivelog方式下操作,并需要大量的档案空间。一旦数据库运行在archivelog状态下,就可以做备份了。热备份的命令文件由三部分组成:

      1.数据文件一个表空间一个表空间地备份。

      (1)设置表空间为备份状态

      (2)备份表空间的数据文件

      (3)恢复表空间为正常状态

      2.备份归档log文件。

      (1)临时停止归档进程

      (2)log下那些在archive redo log目标目录中的文件

      (3)重新启动archive进程

      (4)备份归档的redo log 文件

      3.用alter database backup controlfile命令来备份拷贝文件

      热备份的优点是:

      ·可在表空间或数据文件级备份,备份时间短。

      ·备份时数据库仍可使用。

      ·可达到秒级恢复(恢复到某一时间点上)。

      ·可对几乎所有数据库实体作恢复。

      ·恢复是快速的,在大多数情况下在数据库仍工作时恢复。

      热备份的不足是:

      ·不能出错,否则后果严重。

      ·若热备份不成功,所得结果不可用于时间点的恢复。

      ·因难于维护,所以要特别仔细小心,不允许“以失败而告终”。

      【二】来自内部的另外一个隐患--用户管理以及密码问题

      在这里,其实作为一个差不多点的数据库管理员都很清楚,Oracle数据库本身就使用了很多种手段来加强数据库的安全性,经常见到的就有密码,角色,权限等等。那么我们就从最简单的DBSNMP

      说起:

      Oralce数据库如果采用典型安装后,自动创建了一个叫做DBSNMP的用户,该用户负责运行Oracle系统的智能代理(Intelligent Agent),该用户的缺省密码也是“DBSNMP”。如果忘记修改该用户的口令,任何人都可以通过该用户存取数据库系统。现在我们来看一下该用户具有哪些权限和角色,然后来分析一下该用户对数据库系统可能造成的损失。

      启动SQL/PLUS程序,使用该用户登录进入:

      SQL> select * from session_privs;

      CREATE SESSION

      ALTER SESSION

      UNLIMITED TABLESPACE

      CREATE TABLE

      CREATE CLUSTER

      CREATE SYNONYM

      CREATE PUBLIC SYNONYM

      CREATE VIEW

      CREATE SEQUENCE

      CREATE DATABASE LINK

      CREATE PROCEDURE

      CREATE TRIGGER

      ANALYZE ANY

      CREATE TYPE

      CREATE OPERATOR

      CREATE INDEXTYPE

      可以看到该用户不是SYS或SYSTEM管理用户,然而,它却具有两个系统级权限:UNLIMITED TABLESPACE和CREATE PUBLIC SYNONYM。

      看到这两个权限你应该马上想到,这些都是安全隐患,尤其是UNLIMITED TABLESPACE,它是破坏数据库系统的攻击点之一。如果这时候你还依然认为,即使有人利用这个没有修改的口令登录进数据库也造成不了什么损失的话,我就不得不提醒你:该用户具有UNLIMITED TABLESPACE的系统权限,它可以写一个小的脚本,然后恶意将系统用垃圾数据填满,这样数据库系统也就无法运行,并将直接导致最终的瘫痪。目前很多数据库系统都要求7X24的工作,如果出现了系统用垃圾数据填满的情况,那么,等数据库系统恢复时,恐怕不可挽回的损失已经造成了。

      可是除了 DBSNMP 还有很多其他的用户,怎么办呢?让我们先看一下目前普遍存在于Oracle数据库中的用户管理问题:

      (1)权限过大:对ORACLE数据库编程和浏览的一般用户常常具有DBA (数据库管理员权限),

      能对数据库系统做任何修改或删除。

      (2)安全性差:很多ORACLE用户缺省存储位置都在系统表空间,这样不仅影响系统的正常工

      作,而且不同用户的数据信息互相影响、透明,保密性差。随着数据的不断加入,

      有可能使整个数据库系统崩溃。

      (3)密码有规律:在ORACLE调试初期形成的用户名和密码一致的不良习惯保留到现在;系统用户SYS和SYSTEM的密码也众所皆知。

      知道了这些普遍的“毛病”,我们怎么做呢?下面是我的一些建议:

      (1)ORACLE DBA (数据库管理员)的规范

      ·SUN Solaris操作系统下ORACLE用户密码应严格保密,绝不该把密码设成

      ORACLE;并指定专门的数据库管理员定期修改。

      ·ORACLE初始化建立的SYS和SYSTEM系统管理员用户密码应由原来MANAGER改成别的不易被记忆的字符串。

      ·ORACLE WEB SERVER的管理端口具备DBA浏览数据库的能力,因此其管理者

      ADMIN的密码也应保密,不该把密码设成MANAGER;并指定专门的数据库管理员定

      期修改。

      ·ORACLE DBA最好在SUN SPARC服务器控制台上用窗口式界面实现管理。前提

      是ORACLE用户启动服务器,然后在窗口式命令行下输入SVRMGRM,即启动了ORACLE SERVER MANAGER菜单式管理;用SYSDBA身份登录后,就可做数据库系统维护工作了

      (2)SQL*PLUS编程用户的规范

      ·存储结构的规范

      考虑到用SQL*PLUS编程可实现各行各业、各公司、各部门多种多样的应用需求,我们的SQL*PLUS编程用户也应该朝这个方向规范:不同种类的应用必须有不同的用户;不同种类的应用必须有不同的存储位置,包括物理文件、缺省表空间、临时表空间的创建和规划:当准备编写某一较大规模(从ORACLE数据量和面向用户量考虑)应用程序时,首先应该创建一个逻辑的存储位置-表空间,同时定义物理文件的存放路径和所占硬盘的大小。

      ①、物理文件缺省的存放路径在/oracle_home/dbs下,在命令行下用UNIX指令df -k 可查看硬盘资源分区的使用情况。如果oracle_home使用率达90‰以上,而且有一个或多个较为空闲的硬盘资源分区可以利用,我们最好把物理文件缺省的存放路径改到较为空闲的硬盘资源分区路径下。在此路径下我们可以这样规划资源物理文件的存储:

      xxx表空间

      xxx行业/ xxx公司/ xxx 部门/ xxx 服务.dbf

      DEMO表空间

      default_datafile_home1/col /elec/sys4/demo1.dbf

      default_datafile_home1/col /elec/sys4/demo2.dbf

      公司系统四部摹拟演示系统物理文件

      HUMAN表空间

      default_datafile_home1/col/elec/human/human.dbf

      公司人事部人事管理系统物理文件

      BOOK表空间

      default_datafile_home1/col/elec/book/book.dbf

      公司资料室图书管理系统物理文件

      QUESTION表空间

      default_datafile_home1/col/elec/client/question.dbf

      公司客户服务部问题库系统物理文件

      PC表空间

      default_datafile_home1/col/chaoxun/client/pc.dbf

      公司PC机售后服务系统物理文件

      ……表空间

      default_datafile_home2/……………………………

      等等

      说明:其中default_datafile_home1指oracle_home/dbs;

      default_datafile_home2指较为空闲的硬盘资源分区路径。

      ②、物理文件的大小根据应用系统的数据量、数据对象、程序包的多少来定。一般用于摹拟演示的小系统,表空间初始的物理文件为2M即能满足要求,如果信息量满,还可以增加物理文件,扩充表空间(每次扩充大小也可暂定为2M);一般实际运行的应用系统可适当增加表空间初始的物理文件大小,但也不要一次分配太大(因为不易回收空间,却易扩充空间),这也需要根据具体情况具体分析:信息量大、需长时间保存的应用在条件允许情况下,表空间可以大到几百M甚至上G;信息量小、短期经常刷新的应用,表空间可以控制在2M以下。

      ③、表空间的名称应该采用同系统应用相似的英文字符或字符缩写,表空间所对应的一个或多个物理文件名也应有相关性。不同用户所处的缺省表空间不同,存储的信息就不能互相访问。这比把所有用户信息都储存在系统表空间,安全性大大提高了。如果用ORACLE WEB SERVER管理端口创建的用户,其缺省和临时表空间一定是系统表空间,DBA切记要改变用户的缺省表空间。临时表空间存放临时数据段,处理一些排序、合并等中间操作,根据实际应用的需求可以把它们放在专门创建的表空间里;如果系统表空间大,也可以把它们放在系统表空间。用户创建的数据索引最好和数据文件分开存放在不同表空间,以减少数据争用和提高响应速度。

      ·密码和用户名的规范

      有相当数量的ORACLE用户名和密码一致,这是个很不安全的因素。我们建议ORACLE用户名和密码一定不要一样,密码最好在五,六位字符以上。不同用户间不应该使用相同的密码。用户名的定义可根据实际应用的英文名来设,而依据编程人员的姓名定义的用户名实际上不规范,可在日后的工作中结合上述有关存储结构规范的说明逐步改进。

      (3)特殊要求用户的规范

      在ORACLE数据库使用过程中,还会遇到一些有特殊要求的用户:非编程人员需要对某个表有查询、增加、删除、修改的权利。DBA应创建一个这样的用户,先确定用户名和密码,再规定相关应用所在缺省表空间(包含某个表)和临时表空间,最后TABLE属主给其授权:赋予CONNECT角色SELECT、INSERT、DELETE、UPDATE ON THE TABLE的对象级权限,这可根据实际需求自由取舍。

      举例:●给新用户授于对象级权限(命令行方式):

      假设新用户NEW2需要有查询、删除、修改DCD用户的表EMP。

      %svrmgrl

      SVRMGR>connect internal; 以系统管理员登录

      SVRMGR>create user new2 identified by new2345 default tablespace app;

      SVRMGR>connect dcd/dcdpwd; 以dcd用户登录

      SVRMGR>grant connect to new2;

      SVRMGR>grant select on emp to new2;

      SVRMGR>grant delete on emp to new2;

      SVRMGR>grant update on emp to new2;

      说了这么多关于用户的问题,那么接下来我们就详细得说一下关于密码文件的使用以及维护--在Oracle数据库系统中,用户如果要以特权用户身份(INTERNAL/SYSDBA/SYSOPER)登录Oracle数据库可以有两种身份验证的方法:即使用与操作系统集成的身份验证或使用Oracle数据库的密码文件进行身份验证。因此,管理好密码文件,对于控制授权用户从远端或本机登录Oracle数据库系统,执行数据库管理工作,具有重要的意义。

      Oracle数据库的密码文件存放有超级用户INTERNAL/SYS的口令及其他特权用户的用户名/口令,它一般存放在ORACLE_HOME\DATABASE目录下。

      ·密码文件的创建:

      在使用Oracle Instance Manager创建一数据库实例的时侯,在ORACLE_HOME\DATABASE目录下还自动创建了一个与之对应的密码文件,文件名为PWDSID.ORA,其中SID代表相应的Oracle数据库系统标识符。此密码文件是进行初始数据库管理工作的基础。在此之后,管理员也可以根据需要,使用工具ORAPWD.EXE手工创建密码文件,命令格式如下:

      C:\ >ORAPWD FILE=< FILENAME > PASSWORD =< PASSWORD > ENTRIES=< MAX_USERS >

      各命令参数的含义为:

      FILENAME:密码文件名;

      PASSWORD:设置INTERNAL/SYS帐号的口令;

      MAX_USERS:密码文件中可以存放的最大用户数,对应于允许以SYSDBA/SYSOPER权限登录数据库的最大用户数。由于在以后的维护中,若用户数超出了此限制,则需要重建密码文件,所以此参数可以根据需要设置得大一些。

      有了密码文件之后,需要设置初始化参数REMOTE_LOGIN_PASSWORDFILE来控制密码文件的使用状态。

      ·设置初始化参数REMOTE_LOGIN_PASSWORDFILE:

      在Oracle数据库实例的初始化参数文件中,此参数控制着密码文件的使用及其状态。它可以有以下几个选项:

      NONE:指示Oracle系统不使用密码文件,特权用户的登录通过操作系统进行身份验证;

      EXCLUSIVE:指示只有一个数据库实例可以使用此密码文件。只有在此设置下的密码文件可以包含有除INTERNAL/SYS以外的用户信息,即允许将系统权限SYSOPER/SYSDBA授予除INTERNAL/SYS以外的其他用户。

      SHARED:指示可有多个数据库实例可以使用此密码文件。在此设置下只有INTERNAL/SYS帐号能被密码文件识别,即使文件中存有其他用户的信息,也不允许他们以SYSOPER/SYSDBA的权限登录。此设置为缺省值。

      在REMOTE_LOGIN_PASSWORDFILE参数设置为EXCLUSIVE、SHARED情况下,Oracle系统搜索密码文件的次序为:在系统注册库中查找ORA_SID_PWFILE参数值(它为密码文件的全路径名);若未找到,则查找ORA_PWFILE参数值;若仍未找到,则使用缺省值ORACLE_HOME\DATABASE\PWDSID.ORA;其中的SID代表相应的Oracle数据库系统标识符。

      ·向密码文件中增加、删除用户:

      当初始化参数REMOTE_LOGIN_PASSWORDFILE设置为EXCLUSIVE时,系统允许除INTERNAL/SYS以外的其他用户以管理员身份从远端或本机登录到Oracle数据库系统,执行数据库管理工作;这些用户名必须存在于密码文件中,系统才能识别他们。由于不管是在创建数据库实例时自动创建的密码文件,还是使用工具ORAPWD.EXE手工创建的密码文件,都只包含INTERNAL/SYS用户的信息;为此,在实际操作中,可能需要向密码文件添加或删除其他用户帐号。

      由于仅被授予SYSOPER/SYSDBA系统权限的用户才存在于密码文件中,所以当向某一用户授予或收回SYSOPER/SYSDBA系统权限时,他们的帐号也将相应地被加入到密码文件或从密码文件中删除。由此,向密码文件中增加或删除某一用户,实际上也就是对某一用户授予或收回SYSOPER/SYSDBA系统权限。

      要进行此项授权操作,需使用SYSDBA权限(或INTERNAL帐号)连入数据库,且初始化参数REMOTE_LOGIN_PASSWORDFILE的设置必须为EXCLUSIVE。具体操作步骤如下:

      创建相应的密码文件;

      设置初始化参数REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE;

      使用SYSDBA权限登录: CONNECT SYS/internal_user_passsword AS SYSDBA;

      启动数据库实例并打开数据库;

      创建相应用户帐号,对其授权(包括SYSOPER和SYSDBA): 授予权限:GRANT SYSDBA TO user_name;

      收回权限:REVOKE SYSDBA FROM user_name;

      现在这些用户可以以管理员身份登录数据库系统了;

      ·使用密码文件登录:

      有了密码文件后,用户就可以使用密码文件以SYSOPER/SYSDBA权限登录Oracle数据库实例了,注意初始化参数REMOTE_LOGIN_PASSWORDFILE应设置为EXCLUSIVE或SHARED。任何用户以SYSOPER/SYSDBA的权限登录后,将位于SYS用户的Schema之下,以下为两个登录的例子:

      1. 以管理员身份登录:

      假设用户scott已被授予SYSDBA权限,则他可以使用以下命令登录:

      CONNECT scott/tiger AS SYSDBA

      2. 以INTERNAL身份登录:

      CONNECT INTERNAL/INTERNAL_PASSWORD

      ·密码文件的维护:

      1. 查看密码文件中的成员:

      可以通过查询视图V$PWFILE_USERS来获取拥有SYSOPER/SYSDBA系统权限的用户的信息,表中SYSOPER/SYSDBA列的取值TRUE/FALSE表示此用户是否拥有相应的权限。这些用户也就是相应地存在于密码文件中的成员。

      2. 扩展密码文件的用户数量:

      当向密码文件添加的帐号数目超过创建密码文件时所定的限制(即ORAPWD.EXE工具的MAX_USERS参数)时,为扩展密码文件的用户数限制,需重建密码文件,具体步骤如下:

      a) 查询视图V$PWFILE_USERS,记录下拥有SYSOPER/SYSDBA系统权限的用户信息;

      关闭数据库;

      c) 删除密码文件;

      d) 用ORAPWD.EXE新建一密码文件;

      e) 将步骤a中获取的用户添加到密码文件中。

      3. 修改密码文件的状态:

      密码文件的状态信息存放于此文件中,当它被创建时,它的缺省状态为SHARED。可以通过改变初始化参数REMOTE_LOGIN_PASSWORDFILE的设置改变密码文件的状态。当启动数据库事例时,Oracle系统从初始化参数文件中读取REMOTE_LOGIN_PASSWORDFILE参数的设置;当加载数据库时,系统将此参数与口令文件的状态进行比较,如果不同,则更新密码文件的状态。若计划允许从多台客户机上启动数据库实例,由于各客户机上必须有初始化参数文件,所以应确保各客户机上的初始化参数文件的一致性,以避免意外地改变了密码文件的状态,造成数据库登陆的失败。

      4. 修改密码文件的存储位置:

      密码文件的存放位置可以根据需要进行移动,但作此修改后,应相应修改系统注册库有关指向密码文件存放位置的参数或环境变量的设置。

      5. 删除密码文件:

      在删除密码文件前,应确保当前运行的各数据库实例的初始化参数REMOTE_LOGIN_PASSWORDFILE皆设置为NONE。在删除密码文件后,若想要以管理员身份连入数据库的话,则必须使用操作系统验证的方法进行登录。

      但是管理员都觉得乏味,因为在管理员中流行一种很简单的加密办法--就是经常,很频繁地修改自己的密码。可是,每次修改都跟打一次仗似的--因为更新程序并不是每个人都愿意做的事情。

      那么有没有什么简单点的办法呢?请往下看:

      模型:Oracle7.3;开发工具:Develope2000。收费系统(在数据库中的名称是SFYY),其Client端分散在市区的数个营业点,通过城域网与主机(小型 机)相连。

      过程:

      ·在收费小型机Oracle系统的system用户(DBA)下,创建新用户test;

      create user test

      identified by carton

      default tablespace dataspace1

      quota 100K

      ·对test用户授以权限;

      grant create session to test;

      grant resource to test;

      ·在test用户下建立一个存储函数mmtranslate,它其实是一个加密程序。下面是一个简 单的例子。

      function mmtranslate(m varchar2)

      return varchar2

      as

      i number(2);

      kk varchar2(10);

      begin

      kk:=′′;

      i:=1;

      loop

      if i<=length(m) then

      if instr(′1234567890′,substr(m,i,1),1,1)>0 then

      kk:=kk||chr(100+to_number(substr(m,i,1)));

      elseif instr(‘wxyz‘,substr(m,i,1),1,1)>0 then

      kk:=kk||chr(-8+ascii(substr(m,i,1)));

      else

      kk:=kk||chr(4+ascii(substr(m,i,1)));

      end if;

      else

      exit;

      end if;

      i:=i+1;

      end loop;

      return kk;

      exception

      when others then

      return ′-1′;

      end;

      ·在test用户下建表mmtest并插入记录:

      create table mmtest

      (usnamevarchar2(6),------用户名称

      mimavarchar2(6)------加密前的密码);

      insert into mmtest values( ‘sfyy‘,‘eds2‘);

      commit;

      ·执行以下语句

      SQL>select mmtranslate(‘eds2‘) from dual;

      MMTRANSLATE(‘EDS2‘)

      ----------------------------------------

      ihwf

      利用DBA权限更改sfyy的密码为上面语句的执行结果:

      alter user sffy

      identified by ihwf; ;

      ·修改应用程序,对于开发环境是Develope2000的程序来说,主要是修改主程序的on-lo gon触发器:

      declare

      mm varchar2(6);

      begin

      logon(‘test‘,‘carton‘);

      select mima into mm from mmtest where usname=‘sfyy‘;

      mm:=mmtranslate(mm);

      logout;

      logon(‘sfyy‘,mm);

      end;

      然后再利用触发器WHEN-NEW-FROM-INSTANCE执行Callfrom或Newform等 命令,进入业务处理程序。这个主程序应当仅仅由管理员来掌握,编译之后将执行文件下发 到各收费点的Clien端。

      ·在System用户下,利用Oracle提供的pupbld.sql,建立表Productuserprofile,执行下面这样的命令,限制在非开发状态Sql命令的使用,例如

      insert into productuserprofile

      (product,userid,attribute,charvalue) values

      (‘SQL*Plus‘,‘TEST‘,‘CONNECT‘,‘DISABLED‘);

      insert into productuserprofile

      (product,userid,attribute,charvalue) values

      (‘SQL*Plus‘,‘SFYY‘,‘DELETE‘,‘DISABLED‘);这样,在SQL状态下,根本无法连接到TEST用户,而在 sfyy用户下,delete命令将不能执行。当然,DBA可以改变这些设置。

      当然了,这个仅仅是属于一种“应用技巧”,但是足可以把那些每天忙于更新系统的管理员舒服好几天了。但是另一方面,还要加强对源程序的管理,在Client端只存放执行程序。加强审计,发现异常现象,及时处理。这样才可以做到更高一层的“安全”。

      在下面,我主要是向大家介绍一个REM对GHXXB制立数据库触发子,密码的加密程序。

      REM 对GHXXB制立数据库触发子(当INSERT OR UPDATE GHXXB时触发)

      drop trigger scjmmm;

      create or replace trigger scjmmm

      before insert or update of mm On ghxxb For each Row

      Begin

      :new.mm:=ENCRYPT(:new.mm,:NEW.GH,TO_CHAR(SYSDATE,‘SS‘));

      End;

      /

      ---------------------------密码的加密程序ENCRYPT----------------------

      Create or Replace

      Function ENCRYPT (Inpass In Varchar2,IN_GH In Varchar2,IN_SS In Varchar2)

      Return Varchar2 Is

      bcs varchar2(20);

      bcs1 number;

      cs number;

      jg number;

      m_gh VARCHAR2(4);

      m_mm VARCHAR2(20);

      Begin

      m_gh:=IN_GH;

      m_mm:=INPASS;

      cs:=TO_NUMBER(IN_SS);

      If cs<=1 then cs:=77 ;end if;

      bcs:=substr(to_char(ascii(substr(m_gh,1,1))),1,2);

      If bcs<‘1‘ then bcs:=‘7‘ ;end if;

      m_gh:=substr(m_gh,2);

      Loop EXIT WHEN nvl(length(m_gh),0)=0 ;

      bcs:=bcs||substr(to_char(ascii(substr(m_gh,1,1))),-1,1);

      m_gh:=substr(m_gh,2);

      End loop;

      Loop EXIT WHEN nvl(length(m_mm),0)=0 ;

      bcs:=bcs||substr(to_char(ascii(substr(m_mm,1,1))),-1,1);

      m_mm:=substr(m_mm,2);

      End loop;

      bcs1:=to_number(bcs);

      jg:=cs*bcs1;

      Loop EXIT WHEN length(to_char(jg))>13;

      jg:=jg*cs ;

      End loop;

      RETURN(IN_SS||substr(to_char(jg),1,14));

      End;

      /

      总结上面的东西,我们仅仅是从自身做起,知道了怎么维护Oracle数据库安全这个话题的“皮毛”。可是,对于这个似乎永远也说不完的话题,我们光知道怎么从内部“防御”就够了吗?不要忘了,在外面,还有一群虎视耽耽的“hacker”在盯着你的数据库--因为这里面有他们想要的东西。

      所以,请大家关注好下一个话题:

      §2.不被“hacker”入侵的几个建议

      我们的目标是:没有蛀牙!(开个玩笑~!呵呵)其实应该是:它应尽可能地堵住潜在的各种漏洞,防止非法用户利用它们侵入数据库系统。对于数据库数据的安全问题,数据库管理员可以参考有关系统双机热备份功能以及数据库的备份和恢复的资料。

      以下就数据库系统不被非法用户侵入这个问题作进一步的阐述。

      ·组和安全性:在操作系统下建立用户组也是保证数据库安全性的一种有效方法。Oracle程序为了安全性目的一般分为两类:一类所有的用户都可执行,另一类只DBA可执行。在Unix环境下组设置的配置文件是/etc/group,关于这个文件如何配置,请参阅Unix的有关手册,以下是保证安全性的几种方法:

      (1)在安装Oracle Server前,创建数据库管理员组(DBA)而且分配root和Oracle软件拥有者的用户ID给这个组。DBA能执行的程序只有710权限。在安装过程中SQL*DBA系统权限命令被自动分配给DBA组。

      (2)允许一部分Unix用户有限制地访问Oracle服务器系统,增加一个由授权用户组的Oracle组,确保给Oracle服务器实用例程Oracle组ID,公用的可执行程序,比如SQL*Plus,SQL*forms等,应该可被这组执行,然后该这个实用例程的权限为710,它将允许同组的用户执行,而其他用户不能。

      (3)改那些不会影响数据库安全性的程序的权限为711。(注:在我们的系统中为了安装和调试的方便,Oracle数据库中的两个具有DBA权限的用户Sys和System的缺省密码是manager。为了您数据库系统的安全,我们强烈建议您该掉这两个用户的密码,具体操作如下:

      在SQL*DBA下键入:

      alter user sys indentified by password;

      alter user system indentified by password;

      其中password为您为用户设置的密码。

      ·Oracle服务器实用例程的安全性:

      以下是保护Oracle服务器不被非法用户使用的几条建议:

      (1) 确保$ORACLE_HOME/bin目录下的所有程序的拥有权归Oracle软件拥有者所有;

      (2) 给所有用户实用便程(sqiplus,sqiforms,exp,imp等)711权限,使服务器上所有的用户都可访问Oracle服务器;

      (3) 给所有的DBA实用例程(比如SQL*DBA)700权限。Oracle服务器和Unix组当访问本地的服务时,您可以通过在操作系统下把Oracle服务器的角色映射到Unix的组的方式来使用Unix管理服务器的安全性,这种方法适应于本地访问。

      在Unix中指定Oracle服务器角色的格式如下:

      ora_sid_role[_dla]

      其中 sid 是您Oracle数据库的oracle_sid;

      role 是Oracle服务器中角色的名字;

      d (可选)表示这个角色是缺省值;a (可选)表示这个角色带有WITH ADMIN选项,您只可以把这个角色授予其他角色,不能是其他用户。

      以下是在/etc/group文件中设置的例子:

      ora_test_osoper_d:NONE:1:jim,narry,scott

      ora_test_osdba_a:NONE:3:pat

      ora_test_role1:NONE:4:bob,jane,tom,mary,jim

      bin: NONE:5:root,oracle,dba

      root:NONE:7:root

      词组“ora_test_osoper_d”表示组的名字;词组“NONE”表示这个组的密码;数字1表示这个组的ID;接下来的是这个组的成员。前两行是Oracle服务器角色的例子,使用test作为sid,osoper和osdba作为Oracle服务器角色的名字。osoper是分配给用户的缺省角色,osdba带有WITH ADMIN选项。为了使这些数据库角色起作用,您必须shutdown您的数据库系统,设置Oracle数据库参数文件initORACLE_SID.ora中os_roles参数为True,然后重新启动您的数据库。如果您想让这些角色有connect internal权限,运行orapwd为这些角色设置密码。当您尝试connect internal时,您键入的密码表示了角色所对应的权限。

      ·SQL*DBA命令的安全性:

      如果您没有SQL*PLUS应用程序,您也可以使用SQL*DBA作SQL查权限相关的命令只能分配给Oracle软件拥有者和DBA组的用户,因为这些命令被授予了特殊的系统权限。

      (1) startup

      (2) shutdown

      (3) connect internal

      ·数据库文件的安全性:

      Oracle软件的拥有者应该这些数据库文件($ORACLE_HOME/dbs/*.dbf)设置这些文件的使用权限为0600:文件的拥有者可读可写,同组的和其他组的用户没有写的权限。

      Oracle软件的拥有者应该拥有包含数据库文件的目录,为了增加安全性,建议收回同组和其他组用户对这些文件的可读权限。

      ·网络安全性:

      当处理网络安全性时,以下是额外要考虑的几个问题。

      (1) 在网络上使用密码在网上的远端用户可以通过加密或不加密方式键入密码,当您用不加密方式键入密码时,您的密码很有可能被非法用户截获,导致破坏了系统的安全性。

      (2) 网络上的DBA权限控制您可以通过下列两种方式对网络上的DBA权限进行控制:

      A 设置成拒绝远程DBA访问;

      B 通过orapwd给DBA设置特殊的密码。

      ·建立安全性策略:

      系统安全性策略

      (1)管理数据库用户:数据库用户是访问Oracle数据库信息的途径,因此,应该很好地维护管理数据库用户的安全性。按照数据库系统的大小和管理数据库用户所需的工作量,数据库安全性管理者可能只是拥有create,alter,或drop数据库用户的一个特殊用户,或者是拥有这些权限的一组用户,应注意的是,只有那些值得信任的个人才应该有管理数据库用户的权限。

      (2) 用户身份确认:数据库用户可以通过操作系统,网络服务,或数据库进行身份确认,通过主机操作系统进行用户身份认证的优点有:

      A 用户能更快,更方便地联入数据库;

      B 通过操作系统对用户身份确认进行集中控制:如果操作系统与数据库用户信息一致,Oracle无须存储和管理用户名以及密码;

      C 用户进入数据库和操作系统审计信息一致。

      (3) 操作系统安全性

      A 数据库管理员必须有create和delete文件的操作系统权限;

      B 一般数据库用户不应该有create或delete与数据库相关文件的操作系统权限;

      C 如果操作系统能为数据库用户分配角色,那么安全性管理者必须有修改操作系统帐户安全性区域的操作系统权限。

      ·数据的安全性策略:

      数据的生考虑应基于数据的重要性。如果数据不是很重要,那么数据的安全性策略可以稍稍放松一些。然而,如果数据很重要,那么应该有一谨慎的安全性策略,用它来维护对数据对象访问的有效控制。

      ·用户安全性策略:

      (1) 一般用户的安全性:

      A 密码的安全性:如果用户是通过数据库进行用户身份的确认,那么建议使用密码加密的方式与数据库进行连接。这种方式的设置方法如下:

      在客户端的oracle.ini文件中设置ora_encrypt_login数为true;

      在服务器端的initORACLE_SID.ora文件中设置dbling_encypt_login参数为true。

      B 权限管理:对于那些用户很多,应用程序和数据对象很丰富的数据库,应充分利用“角色”这个机制所带的方便性对权限进行有效管理。对于复杂的系统环境,“角色”能大大地简化权限的理。

      (2) 终端用户的安全性:

      您必须针对终端用户制定安全性策略。例如,对于一个有很多用户的大规模数据库,安全性管理者可以决定用户组分类为这些用户组创建用户角色,把所需的权限和应用程序角色授予每一个用户角色,以及为用户分配相应的用户角色。当处理特殊的应用要求时,安全性管理者也必须明确地把一些特定的权限要求授予给用户。您可以使用“角色”对终端用户进行权限管理。

      ·数据库管理者安全性策略:

      (1) 保护作为sys和system用户的连接:

      当数据库创建好以后,立即更改有管理权限的sys和system用户的密码,防止非法用户访问数据库。当作为sys和system用户连入数据库后,用户有强大的权限用各种方式对数据库进行改动。

      (2) 保护管理者与数据库的连接:

      应该只有数据库管理者能用管理权限连入数据库,当以sysdba或startup,shutdown,和recover或数据库对象(例如create,drop,和delete等)进行没有任何限制的操作。

      (3) 使用角色对管理者权限进行管理

      ·应用程序开发者的安全性策略:

      (1) 应用程序开发者和他们的权限数据库应用程序开发者是唯一一类需要特殊权限组完成自己工作的数据库用户。开发者需要诸如create table,create,procedure等系统权限,然而,为了限制开发者对数据库的操作,只应该把一些特定的系统权限授予开发者。

      (2) 应用程序开发者的环境:

      A 程序开发者不应与终端用户竞争数据库资源;

      B 用程序开发者不能损害数据库其他应用产品。

      (3) free和controlled应用程序开发应用程序开发者有一下两种权限:

      A free development

      应用程序开发者允许创建新的模式对象,包括table,index,procedure,package等,它允许应用程序开发者开发独立于其他对象的应用程序。

      B controlled development

      应用程序开发者不允许创建新的模式对象。所有需要table,indes procedure等都由数据库管理者创建,它保证了数据库管理者能完全控制数据空间的使用以及访问数据库信息的途径。但有时应用程序开发者也需这两种权限的混和。

      (4) 应用程序开发者的角色和权限数据库安全性管理者能创建角色来管理典型的应用程序开发者的权限要求。

      A create系统权限常常授予给应用程序开发者,以至于他们能创建他的数据对象。

      B 数据对象角色几乎不会授予给应用程序开发者使用的角色。

      (5) 加强应用程序开发者的空间限制作为数据库安全性管理者,您应该特别地为每个应用程序开发者设置以下的一些限制:

      A 开发者可以创建table或index的表空间;

      B 在每一个表空间中,开发者所拥有的空间份额。应用程序管理者的安全在有许多数据库应用程序的数据库系统中,您可能需要一应用程序管理者,应用程序管理者应负责起以下的任务:

      a)为每一个应用程序创建角色以及管理每一个应用程序的角色;

      b)创建和管理数据库应用程序使用的数据对象;

      c)需要的话,维护和更新应用程序代码和Oracle的存储过程和程序包。

      我相信有了以上的这些建议,作为一个Oracle的管理者绝对可以做好他本职的工作了。可是,我们再怎么努力,都始终得面对这样一个现实,那就是Oracle毕竟是其他人开发的,而我们却在使用。所以,Oracle到底有多少漏洞--我想这个不是你和我所能解决的。不过既然作为一篇讨论Oracle数据安全的文章,我认为有必要把漏洞这一块也写进去,毕竟这也是“安全”必不可少的一部分。呵呵!

      所以……

      【Oracle漏洞举例】:

      ·Oracle9iAS Web Cache远程拒绝服务攻击漏洞(2002-10-28)

      ·Oracle 8.1.6的oidldapd中的漏洞

      ·Oracle 9iAS OracleJSP 泄漏JSP文件信息漏洞

      ·Linux ORACLE 8.1.5漏洞

      想必我没有理由再往下举了,因为读者肯定已经从其他有效的途径得到了关于Oracle漏洞的最新情报。我这里就不再赘述了。

      总而言之一句话--“Oracle数据安全是一个博大而又精深的话题;如果你没有耐心,就永远不会得到它的精髓之所在。”

  • 数据库安全SQL胜出 Oracle比不过微软

    2007-01-06 12:00:01

     PCPOP.COM 2006年11月23日 类型:转载 作者:mydrivers 编辑:袁锋NGS Software的一个安全研究员David Litchfield发布了一份研究报告,报告中包含了过去六年以来微软和Oracle数据库漏洞的修补情况。

        在这段时间,微软为它的数据库产品SQL Server 7/2000/2005修复了59个漏洞,而Oracle 8/9/10g在同期却放出了233个补丁。自2003年中期以来,微软基本上没出现过太大的事故,而Oracle的补丁却一个接着一个发布。

        在一次会谈中,Litchfield将Microsoft SQL Server 2000 SP4与开源数据库PostgreSQL并列为最安全的数据库,相对地,Oracle 10g垫底。 Litchfield说:“我五分钟就能在Oracle 10g中发现一个新BUG,但是对于SQL Server 2005我做不到。”

        Litchfield向Oracle上报的漏洞中还有49个没有修复,另外一些安全研究员对Oracle的漏洞问题也是“随手拈来”,Argeniss安全公司甚至准备在十二月份开展一个“Oracle数据库BUG周”的活动来证明他们的数据库在安全方面有多么薄弱。

        除了NGS Software,另一家公司 Enterprise Management Group也对Oracle的数据库安全持相同的看法,正是ESG的报告,才有了Litchfield的调查。

Open Toolbar