Archive

Archive for the ‘程序学习’ Category

thinkPHP学习记录2-thinkPHP开发基础知识

八月 10th, 2011

如果要是开发应用程序的话,则需要对thinkPHP的开发流程有一个基本的认识才能开始进行开发,今天就对着使用thinkPHP框架开发应用系统的过程中会涉及到的一些内容进行简单的介绍

开始构建应用程序

thinkPHP框架开发的应用程序,一般都采用单一入口的方式,下面是在应用首页文件中实现的定义:
1.在首页定义thinkPHP框架路径
2.定义项目名称及路径,一般项目名称与项目文件夹名称保持一致
3.加载框架入口文件ThinkPHP.php
4.对网站进行实例化:App::run();

以上说明基本上就算是完成了首页index.php文件的定义实现。

常用公共路径定义

../Public         //项目公共目录
__PUBLIC__   //网站公共目录
__ROOT__     //网站根目录
__TMPL__      //当前模板目录
__APP__          //当前项目地址
__URL__         //当前模块地址
__ACTION__   //当前操作地址
__SELF__        //当前页面地址

快速信息输出

{var}  输出Session变量
{#var}  输出Cookie变量
{&var}  输出配置参数
{.var}  输出GET变量
{^var}  输出POST变量
{*var}  输出常量

单字符函数说明

M 快速高性能实例化模型
D 快速实例化Model类库
$user = D("User"); 等同于 $user = new UserModel();
C 配置参数存取方法
C('USER_AUTH_ON',true);
C('USER_AUTH_ON');
G 记录和统计时间
L 语言参数存取方法
A 快速实例化Action类库
F 快速简单文本数据存取方法
B 执行行为类
N 设置和获取统计数据
R 快速远程调用Action类方法
S 快速缓存存取方法
U URL动态生成和重定向方法
W 快速Widget输出方法

部分系统设置及定义

define('STRIP_RUNTIME_SPACE',false);     //对核心编译缓存和项目编译缓存保留空白和注释
defined('CACHE_RUNTIME',false);      //关闭核心编译缓存
'DEFAULT_MODULE'=>'Blog'   //更改网站默认访问位置
'DB_FIELDS_CACHE'=>false  //设置不缓存数据表字段信息
'TMPL_CACHE_TIME'=>3   //设置缓存的有效期(单位:秒,-1表示永久缓存)
'TMPL_ENGINE_TYPE'=>'php'  //配置直接在模板文件里使用php代码
'APP_DEBUG' => true    //开启调试模式
'DATA_CACHE_SUBDIR'=>True  //配置启用子目录缓存
TMPL_ACTION_ERROR' => 'Public:error' // 默认错误跳转对应的模板文件
'TMPL_ACTION_SUCCESS' => 'Public:success' //默认成功跳转对应的模板文件

加载外部文件

Vendor(‘custom’);    //加载自定义类文件custom.class.php(thinkPHP框架下的Vendor目录下)
<include file=”Public:header” /> //包含header头文件(Public目录下的header.html)
import(“@.ORG.Image”);  //加载ORG目录下的类文件Image.class.php
<load href=’__PUBLIC__/Css/common.css’ />       //加载css样式文件
<load href=”__PUBLIC__/Css/common.css,__PUBLIC__/Js/mootools.js,__PUBLIC__/Js/Ajax/ThinkAjax.js” />

以上只是我在学习的过程中整理出来的一部分内容,有时间的话以后会对其进行更加详细的介绍和说明。

 

来源:红心草博客
原文地址:http://www.hongxincao.com/archives/573.html

程序学习 ,

thinkPHP框架学习记录1-基本概念

八月 9th, 2011

自己做php开发也有很多年了,不过很少采用框架,最近做了一个项目,开始接触到thinkPHP框架,感觉thinkPHP框架还是挺不错的,也开始想逐步学习一下它的框架设计和开发思想,在这里做一下记录,希望自己能够坚持学习下去。

最开始看thinkPHP,觉得还是挺复杂的,特别是对刚接触PHP框架的我来说,首先需要学习的是thinkPHP框架的一些基础知识。下面是整理的thinkPHP开发手册上的一些内容。

thinkPHP基础概念

OOP:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构。OOP 的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成。OOP 达到了软件工程的三个主要目标:重用性、灵活性和扩展性。

MVC:MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型(M)、视图(V)、控制器(C),它们各自处理自己的任务。

ORM:对象-关系映射(Object/Relation Mapping,简称ORM),对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

CURD:对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

ActiveRecord:ActiveRecord也属于ORM层,由Rails最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。

ActiveRecord的主要思想是:

1. 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field;

2. ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;

单一入口:单一入口通常是指一个项目或者应用具有一个统一(但并不一定是唯一)的入口文件,也就是说项目的所有功能操作都是通过这个入口文件进行的,并且往往入口文件是第一步被执行的。

thinkPHP框架系统特性

类库导入:ThinkPHP是首先采用基于类库包和命名空间的方式导入类库,让类库导入看起来更加简单清晰,而且还支持冲突检测和别名导入。为了方便项目的跨平台移植,系统还可以严格检查加载文件的大小写。

URL模式:系统支持普通模式、PATHINFO模式、REWRITE模式和兼容模式的URL方式,支持不同的服务器和运行模式的部署,配合URL路由功能,让你随心所欲的构建需要的URL地址和进行SEO优化工作。

编译机制:独创的核心编译和项目的动态编译机制,有效减少OOP开发中文件加载的性能开销。ALLINONE模式更是让你体验飞一般的感觉。

ORM:简洁轻巧的ORM实现,配合简单的CURD以及AR模式,让开发效率无处不在。

查询语言:内建丰富的查询机制,包括组合查询、复合查询、区间查询、统计查询、定位查询、动态查询和原生查询,让你的数据查询简洁高效。

动态模型:无需创建任何对应的模型类,轻松完成CURD操作,支持多种模型之间的动态切换,让你领略数据操作的无比畅快和最佳体验。

高级模型:可以轻松支持序列化字段、文本字段、只读字段、延迟写入、乐观锁、数据分表等高级特性。

视图模型:轻松动态地创建数据库视图,多表查询不再烦恼。

关联模型:让你以出乎意料的简单、灵活的方式完成多表的关联操作。

分组模块:不用担心大项目的分工协调和部署问题,分组模块帮你解决跨项目的难题。

 模板引擎:系统内建了一款卓越的基于XML的编译型模板引擎,支持两种类型的模板标签,融合了Smarty和JSP标签库的思想,支持标签库扩展。通过驱动还可以支持Smarty、EaseTemplate、TemplateLite、Smart等第三方模板引擎。

 AJAX支持:内置AJAX数据返回方法,支持JSON、XML和EVAL格式返回客户端,并且系统不绑定任何AJAX类库,可随意使用自己熟悉的AJAX类库进行操作。

 多语言支持:系统支持语言包功能,项目和模块都可以有单独的语言包,并且可以自动检测浏览器语言自动载入对应的语言包。

 模式扩展:除了标准模式外,系统内置了Lite、Thin和Cli模式,针对不同级别的应用开发提供最佳核心框架,还可以自定义模式扩展。

自动验证和完成:自动完成表单数据的验证和过滤,生成安全的数据对象。

字段类型检测:字段类型强制转换,确保数据写入和查询更安全。

数据库特性:系统支持多数据库连接和动态切换机制,支持分布式数据库。犹如企业开发的一把利刃,跨数据库应用和分布式支持从此无忧。

缓存机制:系统支持包括文件方式、APC、Db、Memcache、Shmop、Eaccelerator和Xcache在内的多种动态数据缓存类型,以及可定制的静态缓存规则,并提供了快捷方法进行存取操作。

扩展机制:系统支持包括类库扩展、驱动扩展、应用扩展、模型扩展、控制器扩展、标签库扩展、模板引擎扩展、Widget扩展、行为扩展和模式扩展在内的强大灵活的扩展机制,让你不再受限于核心的不足和无所适从,随心DIY自己的框架和扩展应用。

以上的内容其实是摘自thinkPHP的开发手册,同时也是对thinkPHP框架进行了一个整体的说明,如有也在学习thinkPHP框架的朋友,可以和我一起学下去哦。

程序学习 , ,

Jquery常用表单操作整理记录

七月 29th, 2011

在Web开发过程中,经常会用到Jquery,来操作一些表单,每次用的时候都是去现查,可过不久就又忘记了,再用还得查,今天大概整理了一部分关于JQuery操作表单的代码,在这里记录和大家分享一下。

//利用JQuery获取文本框,单选框,下拉框的值
val = $("[name='tname']").val();	//文本框的name="tname"
val = $("#tid").val();				//文本框的id="tid"
val	= $("#tid").text();				//得到指定id的内容(可为tr,div等元素)
val = $('input[type=radio][name="phone"][checked]').val()	//得到单选框的值
rows = $("#tab_pro tr").size();		//得到id为tab_pro的表格的行数
var selval = $("#selval").find("option:selected").text();	//得到下拉框的

//设置表单的值
$("#select").empty();				//清空下拉框内容
$("[name='nid']").attr("disabled",true);	//设置元素是否可写
$("#val").remove();		//删除指定元素
$("#pro_list").append(tabs);	//追加参数到指定id中
$("#id").val('设置元素显示的内容');
$("[name='stoid']").val(sto_id);
$("#id").text('hello,world');
$("#id").html('<a href="http://www.hongxincao.com">红心草</a>');
//页面载入时执行
$("document").ready(function()
{
//页面载入时要执行的代码
});
//设置按钮或其他元素的点击事件
btn_obj= $("#btn");
btn_obj.click(function(){
	//点击事件
});
//异步提交
$.ajax({
	async:false,
	 type:"post",
	 url:"curpage.php",
	 data:{curAction: "submitapply",ID:""+ID+""},
//	 dataType:'json' ,
	 success:function(retdata)
	{
		alert(retdata);
	}
});

暂时整理这么多了,如果以后再遇到合适的代码,会持续更新上来的。

程序学习 , ,

PHP常用正则表达式(匹配电话和姓名)

七月 23rd, 2011

在做Web开发过程中,经常会遇到对用户名,邮箱和电话的正确性验证,这就需要我们使用正则表达式来进行匹配验证,邮箱,qq号等常用参数的正则匹配网上比较多,百度,谷歌一下就出来了,而对于电话还有姓名的完整匹配我找了一些,但还是都不够全面,于是我自己整理了一下电话和姓名的匹配函数,在这里与大家分享一下.

/**
验证正则匹配电话号码的函数,包括了固话和手机号码
**/
function check_tel($tel) {
if(empty($tel))
{
return false;
}
$telA	= explode(",",$tel);
$telReg		= '/\b(^010[1-9][0-9]{7}$)|\b(^02[0-9]{9}$)|\b(^85[2,3][0-9]{8}$)|\b(^0[3-9][0-9]{9,10}$)|\b([1-9][0-9]{7}$)|\b(^1[3,5,8][0-9]{9}$)/';
while(list(,$tels) = each($telA))
{
$tels	= trim($tels);
$tlen	= strlen($tels);
if($tlen < 7 || $tlen > 12 || $tlen == 9 || $tlen == 10)
{
return false;
}
else if(!preg_match_all($telReg,$tels,$match))
{
return false;
}
}
return true;
}
对于正则匹配姓名来说就有些麻烦了,因为网上的大多数匹配都匹配的是中文字符,而不完全是汉字,用户名应该是完全由汉字组成,不能包括中文的一些特殊字符,而正则匹配下来会包含一些特殊中文字符,这就需要我们去过滤掉,我采用了比较简单的方式进行实现.
function check_name($name) {
 $len = strlen($name);
 $ret = eregi("[^\x80-\xff]",$name);
 $partn = array('!','~','¥','*','(',')','——','【','】','『','』',';',':','‘','“','《','》',',','。','?','先生','女士','……');
 $ret1 = ereg($partn,$name,$matchs);
 if(!$ret)
 {
 if($len < 1 || $len > 8 || empty($name))
 {
 return false;
 }
 while(list(,$key) = each($partn))
 {
 if(strpos($name,$key) !== false)
 {
 return false;
 }
 }
 return true;
 }
 return false;
}
上面的两个正则匹配对于电话和姓名来说匹配的应该是比较全面了,如果你有更好的,欢迎分享哦.

程序学习 ,

利用JQuery实现遮罩层效果

七月 20th, 2011

最近在开发的过程中,常常会利用js及Jqueyr框架来实现一些功能,随着JQuery的使用深入,发现其真的是很好用,特别是在服务端代码实现不方便的时候,使用它可以很轻松的搞定,比如异步提交,数据跨域传递及实现遮罩层等效果,今天简单来介绍一下利用JQuery如何实现遮罩层效果。其他的内容有时间的话稍后进行说明。

为什么要实现遮罩层

在某些情况下,需要实现在页面上弹出窗口,能够输入数据,并返回到父窗口,虽然利用window.open可以实现,但它不仅看上去不美观,更是会在浏览器安全控制严格的情况下,导致无法弹出窗口,大量的数据传递也不方便,同时它还可以在不关闭子窗口的情况下返回对父窗口再进行操作,而我们可能希望它是类似alert()输出似的,在不关闭子窗口的情况下无法继续操作,这样对部分程序流程的顺序执行是很有帮助的。

JQuery实现遮罩层效果

首先我们除需要下载jquery主js文件为,还需要下载一个JQuery的插件,它就是jQuery BlockUI Plugin,然后在我们的页面中包含它们。

<SCRIPT Language="JavaScript" src="js/jquery.min.js"></SCRIPT>
<script type="text/javascript" src="js/jquery.blockUI.js"></script>

包含完成之后,我们就可以开始应用了,首先实现打开遮罩层的事件,可以是点击onclick事件或者其它事件都可以。我们在页面中需写一个div用于包含显示遮罩层效果,初始设置其为隐藏状态,待激活事件后再显示。

<div id="test" style="display:none; cursor: default;font-size:12px;padding:1px">
然后写下面的激活事件代码,大概根据代码内容,我想大家都知道什么意思吧。首先设置遮罩层的样式,然后给隐藏div追加一个div,然后把要显示和打开的页面载入到该div中,这样遮罩层的效果就出来了,它的显示实际上就是载入的文件test.php中的显示内容,如果需要传递参数的话你可以在后面添加上。
$.blockUI({ message: $('#test'), css: {width: '100px',height: '200px' ,left: '10px'},overlayCSS:{cursor:'pointer'} });
$("#test").empty().append("<div id='loadcheatechange'></div>");
$("#loadcheatechange").load(''test.php");

下面的代码是关闭遮罩层,你可以在遮罩层页面的外部隐藏部分进行点击就可以关闭遮罩层了。

$('.blockOverlay').attr('cursor','pointer').click($.unblockUI);
或者你可以直接在遮罩层页面上添加一个关闭按钮,其点击事件的代码很简单就能够关闭遮罩层了。
        $.unblockUI();
怎么样,简单吧,这在实现一些无需服务器提交传值的情况下很方便,且显示效果很好,扩展性和参数传递都十分方便,因为无论是页面还是遮罩层的显示其实质都是在一个页面上,因此可以直接通过js或jquery的取值和赋值来对数据进行操作。
稍后会给大家提供一个DEMO,有兴趣的朋友可以参考一下,效果很不错的哦。
来源:红心草博客

程序学习 , ,

15款免费IDE,推荐给开发者

三月 30th, 2011

由于前段时间博客内容丢失,再加上工作繁忙,搞得是一团糟,不过我是不会放弃这个博客的,今天再次转一篇来自PHPChina的文章,为大家推荐一些开源的方便进行代码编辑的工具,有的很不错哦,如果有你喜欢的,可以下载试试看。

本文为您推荐大量的开源、免费的IDE,精选15个免费IDE,推荐给大家。列表如下:

Komodo Edit(Windows, Mac, Linux)

Komodo Edit

Komodo IDE可以在Windows、Mac OS X 和 Linux上运行,并支持通用的开源语言——Perl、PHP和Ruby。代码智能引擎非常可靠。它扫描所有语言安装找到定制扩展,比如PEAR模块。在项目方面,它支持与CVS、Subversion和Perforce的集成,也允许直接向服务器FTP传递代码。

Aptana Studio(Windows, Mac, Linux)

Aptana Studio

Aptana是一个非常强大、开源的专注于Ajax开发的开发工具。

Code::Blocks(Windows, Mac,Linux)

Code::Blocks

Code::Blocks(codeblocks)是一个开源、免费、跨平台的c++IDE。官方网站上称其能满足最苛刻的用户的需求。虽有点夸张,但既然敢这样说,也说明它的功能肯定不差。可扩展插件,有插件向导功能,让你很方便的创建自己的插件。Code::Blocks是用c++编写的(用wxWidgets库),捆绑了MinGW编译器。

Eclipse(Windows, Mac, Linux)

Eclipse

Eclipse是著名的跨平台的自由集成开发环境(IDE)。最初主要用来Java语言开发,但是目前亦有人通过插件使其作为其他计算机语言比如C++和Python的开发工具。

CodeLite(Windows,Mac,Linux)

CodeLite

CodeLite IDE是一个强大的开源,跨平台的C/C++整合开发环境.支持包括 Windows、Linux和Mac系统下运行。

亮点:

1.代码自动完成功能很强大

2. 仿VS,很容易上手

3. 界面更友好

4. 与Subversion集成

5. 与wxFormBuilder集成

6. 函数跳转功能强大

Visual Studio Express(Windows)

Microsoft Visual Studio Express

VS的轻型版本,功能也很强大。

NetBeans(Windows, Mac, Linux)

NetBeans

NetBeans是Sun公司的开源软件开发集成环境,是一个开放框架,可扩展的开发平台,可以用于Java,C/C++,PHP等语言的开发,本身是一个开发平台,可以通过扩展插件来扩展功能。

Xcode(Mac)

Xcode

Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X的应用程序。

MochaCode(Mac)

MochaCode

MochaCode是一个Mac平台下的Java和Cocoa混合程序开发工具。

Geany(Windows, Mac, Linux)

Geany

Geany是一个小型的C代码编辑器,使用 GTK2 开发的开发环境。包括语法高亮、代码自动完成、调用提示以及支持其他类型语言的文件包括: C, Java, PHP, HTML, DocBook, Perl, LateX, and Bash), and symbol lists.

PSPad(Windows)

PSPad

PSPad是一个Windows平台上免费的适合程序员使用的编辑器。它可以让你保持上一次编辑状态,这样在你下次打开编辑器的时候可以直接显示原来的文件。此外它还支持通过FTP进行远程编辑,支持多文件的比较等。

Anjuta DevStudio(Linux)

Anjuta DevStudio

Anjuta是一个C/C++ IDE,它最大的特色是灵活,同时打开多个文件,内嵌代码级的调试器(调用gdb),应用程序向导(Application widzards)可以方便的帮助你创建GNOME程序而不需要你自己写一些与你兴趣无关的代码。

KDevelop(Windows, Mac, Linux)

KDevelop

KDevelop-Project诞生于1998年,其目的是为KDE提供一个易用的集成开发环境(Integrated Development Environment)。此后,KDevelop IDE采用GPL进行发布, 它支持很多程序设计语言,比如C, C++, Fortran, Java, Pascal, Perl, PHP, Python,以及Ruby等。

Notepad++(Windows)

Notepad++

Notepad++是在微软视窗环境下的一个免费的代码编辑器。

ConTEXT(Windows)

ConTEXT Editor

与Notepad++类似,ConTEXT是个高级文本编辑器。功能包括多语言界面、语法高亮,你可存储代码模板、比较文件等等。

程序学习 ,

Oracle数据导入导出方法介绍

三月 8th, 2011

我们在使用Oracle数据库中,可能经常会遇到Oracle数据导入导出的时候,如果直接操作Oracle数据库的话可能不太方便,因此就有了PL/SQL工具,利用PL/SQL我们可以很方便的对数据进行导入和导出,今天我就整理一下自己经常使用的导入导出方法。

对于pl sql developer不太了解到话,可以看一下我的另一篇文章:Oracle连接工具PL/SQL使用及下载

pl sql 导出数据

利用pl导出Oracle数据的话是比较方便的,pl直接登录你的数据库,然后选择相应的表,直接在表名上面点击右键,然后选择”Import Data”项,此时在打开的数据表列表窗口中你可以选择要导出的表,可以批量选择表进行导出,十分方便。

pl sql 导入数据

pl sql导入数据的话则有很多中方式,它支持直接导入表,导入文本数据,导入ODBC格式数据,直接导入表和ODBC格式数据的话比较简单,这里就不多说,主要说一下导入文本数据格式和Excel格式数据。其实在这里我最常用的就是直接导入CSV格式的数据,对于Excel也一样,你可以在Excel中直接把Excel格式的数据另存为CSV格式的文本数据,然后在导入PL/SQL,具体使用如下:

登录PL/SQL,点击”Tool” 打开并选择”Text Importer”。

选择左上角的”Open Data File”项,并选中要导入的数据文本打开。打开之后能看到对应的每一列及数据的预览。

选择”Data To Oracle”标签页,然后把左侧列出来的每一列和右侧Field列表中的字段进行对应并选择正确的数据类型。

然后点击”Import”按钮,根据数据量大小不同,等待的时间长短也不相同,执行时可能会有类似假死的情况,但不会有问题,等真正执行完成就好了。

其他Oracle数据导入导出方式
其他的方式也有一些,比如PL/SQL支持直接复制粘贴的方式导入数据,具体可参考一下我朋友的这篇文章:通过PL/SQL将excel表格数据导入到oracle表格里,还有如果数据量特别大而且对时间又没有太苛刻要求的话,还可以写程序进行导数据,其实我是比较喜欢写程序来导的,这样比较方便,你可以晚上跑一晚上或者利用空余电脑跑,很方便,又不耽误事,呵呵。
上面就是我常使用的Oracle数据导入导出的方法,如果你有更好的方式,欢迎共同交流哦。

程序学习 , ,

Oracle SQL语句优化2-sql语句优化

三月 6th, 2011

下面是的内容是紧接前面一篇,你可以通过这里来查看前面一篇的文章。

这篇文章的内容相对比较实用,我们自己在写sql语句的时候就可以参考一下它,对于其他的数据库sql而言同样有很不错的借鉴意义。

(1) 选择最有效率的表名顺序 ( 只在基于规则的优化器中有效 ) :
ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名, FROM 子句中写在最后的表 ( 基础表 driving table) 将被最先处理,在

FROM 子句中包含多个表的情况下 , 你必须选择记录条数最少的表作为基础表。如果有 3 个以上的表连接查询 , 那就需要选择交叉表

(intersection table) 作为基础表 , 交叉表是指那个被其他表所引用的表 .
(2) WHERE 子句中的连接顺序.:
ORACLE 采用自下而上的顺序解析 WHERE 子句 , 根据这个原理 , 表之间的连接必须写在其他 WHERE 条件之前 , 那些可以过滤掉最大数

量记录的条件必须写在 WHERE 子句的末尾 .
(3) SELECT 子句中避免使用 ‘ * ‘ :
ORACLE 在解析的过程中 , 会将 ‘*’ 依次转换成所有的列名 , 这个工作是通过查询数据字典完成的 , 这意味着将耗费更多的时间
(4) 减少访问数据库的次数:
ORACLE 在内部执行了许多工作 : 解析 SQL 语句 , 估算索引的利用率 , 绑定变量 , 读数据块等;
(5) 在 SQL*Plus , SQL*Forms 和 Pro*C 中重新设置 ARRAYSIZE 参数 , 可以增加每次数据库访问的检索数据量 , 建议值为 200
(6) 使用 DECODE 函数来减少处理时间:
使用 DECODE 函数可以避免重复扫描相同记录或重复连接相同的表 .
(7) 整合简单 , 无关联的数据库访问:
如果你有几个简单的数据库查询语句 , 你可以把它们整合到一个查询中 ( 即使它们之间没有关系 )
(8) 删除重复记录 :
最高效的删除重复记录方法 ( 因为使用了 ROWID) 例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(9) 用 TRUNCATE 替代 DELETE :
当删除表中的记录时 , 在通常情况下 , 回滚段 (rollback segments ) 用来存放可以被恢复的信息 . 如果你没有 COMMIT 事务 ,ORACLE 会

将数据恢复到删除之前的状态 ( 准确地说是 恢复到执行删除命令之前的状况 ) 而当运用 TRUNCATE 时 , 回滚段不再存放任何可被恢复的

信息 . 当命令运行后 , 数据不能被恢复 . 因此很少的资源被调用 , 执行时间也会很短 . ( 译者按 : TRUNCATE 只在删除全表适用

,TRUNCATE 是 DDL 不是 DML)
(10) 尽量多使用 COMMIT :
只要有可能 , 在程序中尽量多使用 COMMIT, 这样程序的性能得到提高 , 需求也会因为 COMMIT 所释放的资源而减少 :
COMMIT 所释放的资源 :
a. 回滚段上用于恢复数据的信息 .
b. 被程序语句获得的锁
c. redo log buffer 中的空间
d. ORACLE 为管理上述 3 种资源中的内部花费
(11) 用 Where 子句替换 HAVING 子句:
避免使用 HAVING 子句 , HAVING 只会在检索出所有记录之后才对结果集进行过滤 . 这个处理需要排序 , 总计等操作 . 如果能通过

WHERE 子句限制记录的数目 , 那就能减少这方面的开销 . ( 非 oracle 中 ) on 、 where 、 having 这三个都可以加条件的子句中, on 是

最先执行, where 次之, having 最后,因为 on 是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按

理说应该速度是最快的, where 也应该比 having 快点的,因为它过滤数据后才进行 sum ,在两个表联接时才用 on 的,所以在一个表的

时候,就剩下 where 跟 having 比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的

,只是 where 可以使用 rushmore 技术,而 having 就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字

段的值是不确定的,根据上篇写的工作流程, where 的作用时间是在计算之前就完成的,而 having 就是在计算后才起作用的,所以在这

种情况下,两者的结果会不同。在多表联接查询时, on 比 where 更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个

临时表后,再由 where 进行过滤,然后再计算,计算完后再由 having 进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白

这个条件应该在什么时候起作用,然后再决定放在那里
(12) 减少对表的查询:
在含有子查询的 SQL 语句中 , 要特别注意减少对表的查询 . 例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
(13) 通过内部函数提高 SQL 效率 . :
复杂的 SQL 往往牺牲了执行效率 . 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的
(14) 使用表的别名 (Alias) :
当在 SQL 语句中连接多个表时 , 请使用表的别名并把别名前缀于每个 Column 上 . 这样一来 , 就可以减少解析的时间并减少那些由

Column 歧义引起的语法错误 .
(15) 用 EXISTS 替代 I N 、 用 NOT EXISTS 替代 NOT IN :
在许多基于基础表的查询中 , 为了满足一个条件 , 往往需要对另一个表进行联接 . 在这种情况下 , 使用 EXISTS( 或 NOT EXISTS) 通常将

提高查询的效率 . 在子查询中 ,NOT IN 子句将执行一个内部的排序和合并 . 无论在哪种情况下 ,NOT IN 都是最低效的 ( 因为它对子查询

中的表执行了一个全表遍历 ). 为了避免使用 NOT IN , 我们可以把它改写成外连接 (Outer Joins) 或 NOT EXISTS.
例子:
( 高效 ) SELECT * FROM EMP ( 基础表 ) WHERE EMPNO > 0 AND EXISTS ( SELECT ‘X’ FROM DEPT WHERE

DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
( 低效 ) SELECT * FROM EMP ( 基础表 ) WHERE EMPNO > 0 AND DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC

= ‘MELB’ )
(16) 识别 ‘ 低效执行 ‘ 的 SQL 语句:
虽然目前各种关于 SQL 优化的图形化工具层出不穷 , 但是写出自己的 SQL 工具来解决问题始终是一个最好的方法:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND ((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2 ) Hit_radio,
ROUND (DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 ORDER BY 4 DESC ; (17) 用索引提高效率: 索引是表的一个概念部分 , 用来提高检索数据的效率, ORACLE 使用了一个复杂的自平衡 B-tree 结构 . 通常 , 通过索引查询数据比全表 扫描要快 . 当 ORACLE 找出执行查询和 Update 语句的最佳路径时 , ORACLE 优化器将使用索引 . 同样在联结多个表时使用索引也可以提 高效率 . 另一个使用索引的好处是 , 它提供了主键 (primary key) 的唯一性验证 . 。那些 LONG 或 LONG RAW 数据类型 , 你可以索引几 乎所有的列 . 通常 , 在大型表中使用索引特别有效 . 当然 , 你也会发现 , 在扫描小表时 , 使用索引同样能提高效率 . 虽然使用索引能得到 查询效率的提高 , 但是我们也必须注意到它的代价 . 索引需要空间来存储 , 也需要定期维护 , 每当有记录在表中增减或索引列被修改时 , 索引本身也会被修改 . 这意味着每条记录的 INSERT , DELETE , UPDATE 将为此多付出 4 , 5 次的磁盘 I/O . 因为索引需要额外的存储空 间和处理 , 那些不必要的索引反而会使查询反应时间变慢 . 。定期的重构索引是有必要的 . : ALTER INDEX REBUILD (18) 用 EXISTS 替换 DISTINCT : 当提交一个包含一对多表信息 ( 比如部门表和雇员表 ) 的查询时 , 避免在 SELECT 子句中使用 DISTINCT. 一般可以考虑用 EXIST 替换 , EXISTS 使查询更为迅速 , 因为 RDBMS 核心模块将在 子查询的条件一旦满足后 , 立刻返回结果 . 例子: ( 低效 ): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO ( 高效 ): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’ FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO ) ; (19) sql 语句用大写的 ;因为 oracle 总是先解析 sql 语句,把小写的字母转换成大写的再执行 (20) 在 java 代码中尽量少用连接符“+”连接字符串! (21) 避免在索引列上使用 NOT 通常 ,  我们要避免在索引列上使用 NOT, NOT 会产生在和在索引列上使用函数相同的 影响 . 当 ORACLE” 遇到 ”NOT, 他就会停止使用索引转而 执行全表扫描 . (22) 避免在索引列上使用计算. WHERE 子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 举例 : 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000;
高效 :
SELECT … FROM DEPT WHERE SAL > 25000/12;
(23) 用 >= 替代 >
高效 :
SELECT * FROM EMP WHERE DEPTNO >=4
低效 :
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于 , 前者 DBMS 将直接跳到第一个 DEPT 等于 4 的记录而后者将首先定位到 DEPTNO=3 的记录并且向前扫描到第一个

DEPT 大于 3 的记录 .
(24) 用 UNION 替换 OR ( 适用于索引列 )
通常情况下 , 用 UNION 替换 WHERE 子句中的 OR 将会起到较好的效果 . 对索引列使用 OR 将造成全表扫描 . 注意 , 以上规则只针对多

个索引列有效 . 如果有 column 没有被索引 , 查询效率可能会因为你没有选择 OR 而降低 . 在下面的例子中 , LOC_ID 和 REGION 上都建

有索引 .
高效 :

SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”

低效 :

SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”

如果你坚持要用 OR, 那就需要返回记录最少的索引列写在最前面 .
(25) 用 IN 来替换 OR
这是一条简单易记的规则,但是实际的执行效果还须检验,在 ORACLE8i 下,两者的执行路径似乎是相同的.
低效 :
SELECT …. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT … FROM LOCATION WHERE LOC_IN IN (10,20,30);
(26) 避免在索引列上使用 IS NULL 和 IS NOT NULL
避免在索引中使用任何可以为空的列, ORACLE 将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录 . 对于复合

索引,如果每个列都为空,索引中同样不存在此记录 .  如果至少有一个列不为空,则记录存在于索引中. 举例 : 如果唯一性索引建立在

表的 A 列和 B 列上 , 并且表中存在一条记录的 A,B 值为 (123,null) , ORACLE 将不接受下一条具有相同 A,B 值( 123,null )的记录 ( 插

入 ). 然而如果 所有的索引列都为空, ORACLE 将认为整个键值为空而空不等于空 . 因此你可以插入 1000 条具有相同键值的记录 , 当然

它们都是空 ! 因为空值不存在于索引列中 , 所以 WHERE 子句中对索引列进行空值比较将使 ORACLE 停用该索引 .
低效 : ( 索引失效 )
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL ;
高效 : ( 索引有效 )
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >= 0;
(27) 总是使用索引的第一个列 :
如果索引是建立在多个列上 , 只有在它的第一个列 (leading column) 被 where 子句引用时 , 优化器才会选择使用该索引 . 这也是一条简

单而重要的规则,当仅引用索引的第二个列时 , 优化器使用了全表扫描而忽略了索引
(28) 用 UNION-ALL 替换 UNION ( 如果有可能的话 ) :
当 SQL 语句需要 UNION 两个查询结果集合时 , 这两个结果集合会以 UNION-ALL 的方式被合并 , 然后在输出最终结果前进行排序 . 如果

用 UNION ALL 替代 UNION, 这样排序就不是必要了 . 效率就会因此得到提高 . 需要注意的是 , UNION ALL 将重复输出两个结果集合中

相同记录 . 因此各位还是 要从业务需求分析使用 UNION ALL 的可行性 . UNION 将对结果集合排序 , 这个操作会使用到

SORT_AREA_SIZE 这块内存 . 对于这 块内存的优化也是相当重要的 . 下面的 SQL 可以用来查询排序的消耗量
低效:

SELECT  ACCT_NUM, BALANCE_AMT
FROM  DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'

高效 :

SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'

(29) 用 WHERE 替代 ORDER BY :
ORDER BY 子句只在两种严格的条件下使用索引 .
ORDER BY 中所有的列必须包含在相同的索引中并保持在索引中的排列顺序 .
ORDER BY 中所有的列必须定义为非空 .
WHERE 子句使用的索引和 ORDER BY 子句中所使用的索引不能并列 .
例如 :
表 DEPT 包含以下列 :
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效 : ( 索引不被使用 )
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE
高效 : ( 使用索引 )
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0
(30) 避免改变索引列的类型 .:
当比较不同数据类型的数据时 , ORACLE 自动对列进行简单的类型转换 .
假设 EMPNO 是一个数值类型的索引列 .
SELECT … FROM EMP WHERE EMPNO = ‘123′
实际上 , 经过 ORACLE 类型转换 , 语句转化为 :
SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123′)
幸运的是 , 类型转换没有发生在索引列上 , 索引的用途没有被改变 .
现在 , 假设 EMP_TYPE 是一个字符类型的索引列 .
SELECT … FROM EMP WHERE EMP_TYPE = 123
这个语句被 ORACLE 转换为 :
SELECT … FROM EMP WHERE TO_NUMBER(EMP_TYPE)=123
因为内部发生的类型转换 , 这个索引将不会被用到 ! 为了避免 ORACLE 对你的 SQL 进行隐式的类型转换 , 最好把类型转换用显式表现出

来 . 注意当字符和数值比较时 , ORACLE 会优先转换数值类型到字符类型
(31) 需要当心的 WHERE 子句 :
某些 SELECT 语句中的 WHERE 子句不使用索引 . 这里有一些例子 .
在下面的例子里 , (1) ‘!=’ 将不使用索引 . 记住 , 索引只能告诉你什么存在于表中 , 而不能告诉你什么不存在于表中 . (2) ‘||’ 是 字符连接

函数 . 就象其他函数那样 , 停用了索引 . (3) ‘+’ 是数学函数 . 就象其他数学函数那样 , 停用了索引 . (4) 相同的索引列不能互相比较 , 这

将会启用全表扫描 .
(32) a. 如果检索数据量超过 30% 的表中记录数 . 使用索引将没有显著的效率提高 .
b. 在特定情况下 , 使用索引也许会比全表扫描慢 , 但这是同一个数量级上的区别 . 而通常情况下 , 使用索引比全表扫描要块几倍乃至几千

倍 !
(33) 避免使用耗费资源的操作 :
带有 DISTINCT,UNION,MINUS,INTERSECT,ORDER BY 的 SQL 语句会启动 SQL 引擎
执行耗费资源的排序 (SORT) 功能 . DISTINCT 需要一次排序操作 , 而其他的至少需要执行两次排序 . 通常 , 带有 UNION, MINUS ,

INTERSECT 的 SQL 语句都可以用其他方式重写 . 如果你的数据库的 SORT_AREA_SIZE 调配得好 , 使用 UNION , MINUS, INTERSECT

也是可以考虑的 , 毕竟它们的可读性很强
(34) 优化 GROUP BY:
提高 GROUP BY 语句的效率 , 可以通过将不需要的记录在 GROUP BY 之前过滤掉 . 下面两个查询返回相同结果但第二个明显就快了许多 .
低效 :

SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
高效 :
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
GROUP JOB

程序学习 ,

oracle sql语句优化1-Oracle操作符优化

三月 4th, 2011

在现在的大型软件工程中,很多都采用了Oracle来作为后台数据库保存数据,如何才能保证大用户量访问情况下的响应速度和服务质量呢?为了保证Oracle数据库运行在最佳的性能状态下,在软件开发之前就需要考虑数据库的优化。

数据库性能优化是包括很多方面的,如:服务器性能参数,数据库优化配置,网络性能,程序SQL语句优化设计等多个方面,今天仅从程序SQL语句优化方面简要分析一下。自己其实是刚开始接触Oracle的,不过由于工作需要,在网上找了一些关于Oracle SQL语句优化的资料,今天大概整理了一下。

SQL语句优化其实主要就是对SQL操作符及相关sql语句的优化处理过程,下面是我简单整理的一些内容,部分内容直接在网上转载,如有侵犯,请联系我。由于内容比较多,文章内容分为两篇。

Oracle操作符优化
IN 操作符

用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格,但是用IN的SQL性能总是比较低的,从ORACLE

执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多

个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不

能转换了。

推荐方案:在业务密集的SQL当中尽量不采用IN操作符。

NOT IN操作符

此操作是强列推荐不使用的,因为它不能应用表的索引。

推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替

<> 操作符(不等于)

不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

推荐方案:用其它相同功能的操作运算代替,如

a<>0 改为 a>0 or a<0

a<>’’ 改为 a>’’

IS NULL 或IS NOT NULL操作(判断字段是否为空)

判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。

推荐方案:

用其它相同功能的操作运算代替,如

a is not null 改为 a>0 或a>’’等。

不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。

建立位图索引(有分区的表不能建,位图索引比较难控制,如字段值太多索引会使性能下降,多人更新操作会增加数据块锁的现象)

> 及 < 操作符(大于或小于操作符)   大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100万 记录,一个数值型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大

的区别了,因为A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。

LIKE操作符

LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘

%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可

来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利

用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

程序学习 ,

Oracle Decode函数-超有用的条件赋值函数

三月 2nd, 2011

最近工作一直在接触Oracle数据库,经常需要写一些Oracle SQL语句,经过学习和实际使用,发现在Oracle里面有一个很好用的条件判断赋值函数decode()函数,它大大减少了sql代码的大小,非常适用,而且仅有Oracle数据库支持该函数,在这里记录一下,有需要的朋友可以看看哦。
DECODE有什么用途呢? 先构造一个例子,假设我们想给智星职员加工资,其标准是:工资在8000元以下的将加20%;工资在8000元以上的加15%,通常的做法是,先选出记录中的工资字段值? select salary into var-salary from employee,然后对变量var-salary用if-then-else或choose case之类的流控制语句进行判断。 如果用DECODE函数,那么我们就可以把这些流控制语句省略,通过SQL语句就可以直接完成。如下:select decode(sign(salary – 8000),1,salary*1.15,-1,salary*1.2,salary from employee 是不是很简洁? DECODE的语法:DECODE(value,if1,then1,if2,then2,if3,then3,…,else),表示如果value等于if1时,DECODE函数的结果返回then1,…,如果不等于任何一个if值,则返回else。初看一下,DECODE 只能做等于测试,但刚才也看到了,我们通过一些函数或计算替代value,是可以使DECODE函数具备大于、小于或等于功能。

decode()函数使用技巧

·软件环境:

1、Windows NT4.0+ORACLE 8.0.4

2、ORACLE安装路径为:C:\ORANT

·含义解释:

decode(条件,值1,翻译值1,值2,翻译值2,…值n,翻译值n,缺省值)

该函数的含义如下:

IF 条件=值1 THEN

RETURN(翻译值1)

ELSIF 条件=值2 THEN

RETURN(翻译值2)

......

ELSIF 条件=值n THEN

RETURN(翻译值n)

ELSE

RETURN(缺省值)

END IF

· 使用方法:

1、比较大小

select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; –取较小值

sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1

例如:

变量1=10,变量2=20

则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。

2、表、视图结构转化

现有一个商品销售表sale,表结构为:

month    char(6)      –月份

sell    number(10,2)   –月销售金额

现有数据为:

200001  1000

200002  1100

200003  1200

200004  1300

200005  1400

200006  1500

200007  1600

200101  1100

200202  1200

200301  1300

想要转化为以下结构的数据:

year   char(4)      --年份

month1  number(10,2)   --1月销售金额

month2  number(10,2)   --2月销售金额

month3  number(10,2)   --3月销售金额

month4  number(10,2)   --4月销售金额

month5  number(10,2)   --5月销售金额

month6  number(10,2)   --6月销售金额

month7  number(10,2)   --7月销售金额

month8  number(10,2)   --8月销售金额

month9  number(10,2)   --9月销售金额

month10  number(10,2)   --10月销售金额

month11  number(10,2)   --11月销售金额

month12  number(10,2)   --12月销售金额

结构转化的SQL语句为:

create or replace view

v_sale(year,month1,month2,month3,month4,month5,month6,month7,month8,month9,month10,month11,month12)

as

select

substrb(month,1,4),

sum(decode(substrb(month,5,2),'01',sell,0)),

sum(decode(substrb(month,5,2),'02',sell,0)),

sum(decode(substrb(month,5,2),'03',sell,0)),

sum(decode(substrb(month,5,2),'04',sell,0))

程序学习 , ,

网站地图(Baidu) | 给我留言 | 关于红心草 | |

Optimized by SEO Ultimate