<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ChenTaoqian&#039;s Blog &#187; 数据库</title>
	<atom:link href="http://www.chentaoqian.com/archives/category/compute/database/feed" rel="self" type="application/rss+xml" />
	<link>http://www.chentaoqian.com</link>
	<description>主机,企业邮箱,域名,空间,服务器,Java,Oracle,PHP,Linux,JS,MySQL,Apache</description>
	<lastBuildDate>Wed, 30 Nov 2011 14:35:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SAVEPOINT和ROLLBACK TO SAVEPOINT语法</title>
		<link>http://www.chentaoqian.com/archives/672</link>
		<comments>http://www.chentaoqian.com/archives/672#comments</comments>
		<pubDate>Wed, 26 May 2010 05:08:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[savepoint]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=672</guid>
		<description><![CDATA[SAVEPOINT和ROLLBACK TO SAVEPOINT语法：
SAVEPOINT identifier
ROLLBACK [WORK] TO  SAVEPOINT identifier
RELEASE SAVEPOINT  identifier
InnoDB支持SQL语句SAVEPOINT, ROLLBACK TO  SAVEPOINT, RELEASE SAVEPOINT和自选的用于ROLLBACK的WORK关键词。
SAVEPOINT语句用于设置一个事务保存点，带一个标识符名称。 如果当前事务有一个同样名称的保存点，则旧的保存点被删除，新的保存点被设置。
ROLLBACK TO SAVEPOINT语句会向以命名的保存点回滚一个事务。如果在保 存点被设置后，当前事务对行进行了更改，则这些更改会在 回滚中被撤销。但是，InnoDB不会释放被存储在保存点之后的存储器中的行锁定。（注意，对于新插入的行，锁定信息被存储在行中的事务ID承载；锁定没有被分开存储在存储器中。在这种情况 下，行锁定在撤销中被释放。）在被命名的保存点之后设置的保存点被删除。
如果语句返回以下错误，则意味着不存在带有指定 名称的保存点：
ERROR 1181: Got  error 153 during ROLLBACK
RELEASE SAVEPOINT语句会从当前事务的一组保存点中删除已命名的保 存点。不出现提交或 回滚。如果保存点不存在，会出现错误。
如果您执行COMMIT或执行不能命名保存点的ROLLBACK，则当前事务的所有保存点被删除
]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/672/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ORACLE中SAVEPOINT使用解析</title>
		<link>http://www.chentaoqian.com/archives/668</link>
		<comments>http://www.chentaoqian.com/archives/668#comments</comments>
		<pubDate>Wed, 26 May 2010 05:01:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[savepoint]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=668</guid>
		<description><![CDATA[Savepoints 在实际编程中用得比较广，学会它能让你在PL/SQL编程上获得很大提高。下面简单介绍一下Oracle中SavePoint的使用。
你可以在事务上下文中声明称为savepoint的中间标记。Savepoint将一个长事务分隔为较小的部分。
使用savepoint，你可以在长事务中任何点任意标记你的操作。然后你可以选择回滚在事务中当前点之前、声明的  savepoint之后执行的操作。比如，你可以在一长段复杂的更新中使用savepoint，如果犯了个错，你不需要重新提交所有语句。
Savepoints  在应用程序中同样有用。如果一个过程包含几个函数，那可以在每个函数前创建一个savepoint。如果一个函数失败，返回数据到函数开始前的状态并在修 改参数或执行一个恢复操作后重新运行函数就非常容易。
在回滚到一个savepoint后，Oracle释放由被回滚的语句持有的锁。其他等待之前被锁资源的事务可以进行了。其他要更新之前被锁行的事 务也可以执行。
当一个事务回滚到一个savepoint，发生下列事件：
1. Oracle仅回滚savepoint之后的语句。
2. Oracle保留这一savepoint，但所有建立于此后的savepoints丢失。
3. Oracle释放在该savepoint后获得的所有表、行锁，但保留之前获得的所有锁。
事务保持活动并可继续。
无论何时一个会话在等待事务，到savepoint的回滚不会释放行锁。为了确保事务如果无法获得锁也不会悬挂（hang），在执行UPDATE 或DELETE前使用FOR UPDATE &#8230;  NOWAIT。（这里指回滚的savepoint之前获得的锁。该savepoint后获得的行锁会被释放，之后执行的语句也会被彻底回滚。）
注意：
1.savepoint 名字保持唯一
2.如果后面新设置的一个savepoint的名字和前面的一个 savepoint名字重复，前一个savepoint将被取消
3.设置savepoint后，事务可以继续commit,全部回退或者回退到具体一个savepoints
4.撤销的处理必须是在没有发出commit命令的前提下才能有效。
代码示例：
SQL&#62; create table test (id number(7));
表已创建。
SQL&#62; insert into test values (3);
已创建 1 行。
SQL&#62; savepoint a;
保存点已创建。
SQL&#62; insert into test values (4);
已创建 1 行。
SQL&#62; select * from test;
ID&#8212;&#8212;&#8212;-
3
4
SQL&#62; rollback  to a;
回退已完成。
SQL&#62; select * from test;
ID
&#8212;&#8212;&#8212;-
3
SQL&#62; rollback;
回退已完成。
SQL&#62; select * from [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/668/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>360度全方位解读Oracle回滚段</title>
		<link>http://www.chentaoqian.com/archives/665</link>
		<comments>http://www.chentaoqian.com/archives/665#comments</comments>
		<pubDate>Wed, 26 May 2010 04:49:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[回滚段]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=665</guid>
		<description><![CDATA[最近开发中接触到Oracle回滚段的概念，对其不是很了解，查阅资料后记录下这篇文章。
1. 回滚段的作用 
回滚段用于对数据库修改时, 保存原有的数据, 以便稍后可以通过使用ROLLBACK来恢复到修改前的数据; 另外, 回滚段可以为数据库中的所有进程提供读一致性. 因此, 回滚段设置的合理与否, 直接影响到数据库的性能, 在更新密集的OLTP应用中,更是如此.
2. 回滚段的类型 
回滚段可分为系统回滚段和非系统回滚段,  其中非系统回滚段又分为PUBLIC回滚段和PRIVATE回滚段.
系统回滚段用于处理涉及系统的CATALOG的事物(比如大多数的DDL),  它位于SYSTEM表空间, 由于只有SYSTEM表空间可以随时保持可用, 因此, 不要把SYSTEM回滚段放在其他的表空间中.
*** 原则1: 系统回滚段应放在SYSTEM表空间中,  并且应该永远保持ONLINE状态.
PUBLIC回滚段对于数据库的所有实例(INSTANCE)都是可用的,  除非将其显式设置为OFFLINE.
PRIVATE回滚段是指对于数据库的某个实例是私有的, 为了使用PRIVATE回滚段, 某个实例应当在其INITsid.ORA的ROLLBACK_SEGMENTS中标明所有要使用的PRIVATE回滚段, 或通过使用ALTER ROLLBACK SEGMENT XXX ONLINE来使用某一个回滚段.
***  建议1: 在单实例系统中,建议将所有回滚段设为PUBLIC.
*** 建议2: 在多实例系统中(如OPS),  建议将每个实例的PRIVATE回滚段放置到访问比较快的本地设备上.
3. 回滚段的数量、大小及存储参数 
精确的回滚段的数量及大小的计算涉及很多方面: 应用的类型(OLTP/OLAP/BATCH), 同时进行的事物的数量, DML语句的类型, 每个事物处理的数据量等等. 精确的计算, 限于篇幅, 不在此提及, 朋友们可参考相关文档(参考文献4), 在此, 只提供几个原则及建议.
*** 原则2: OLTP系统应使用小但较多的回滚段,  [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/665/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>简单3招提高Oracle数据库性能</title>
		<link>http://www.chentaoqian.com/archives/644</link>
		<comments>http://www.chentaoqian.com/archives/644#comments</comments>
		<pubDate>Sat, 15 May 2010 10:40:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[提升]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=644</guid>
		<description><![CDATA[数据库优化的讨论可以说是一个永恒的主题。资深的Oracle优化人员通常会要求提出Oracle数据库性能问题的人对数据库做一个statspack，贴出数据库配置等等。还有的人认为要抓出执行最慢的语句来进行优化。
但实际情况是，提出疑问的人很可能根本不懂执行计划，更不要说statspack了。而我认为，数据库优化，应该首先从大的方面考虑：网络、服务器硬件配置、操作系统配置、Oracle服务器配置、数据结构组织、然后才是具体的调整。
实际上网络、硬件等往往无法决定更换，应用程序一般也无法修改，因此应该着重从数据库配置、数据结构上来下手，首先让数据库有一个良好的配置，然后再考虑具体优化某些过慢的语句。我在给我的用户系统进行优化的过程中，总结了一些基本的，简单易行的办法来优化数据库，算是我的三板斧，呵呵。
不过请注意，这些不一定普遍使用，甚至有的会有副作用，但是对OLTP系统、基于成本的数据库往往行之有效，不妨试试。（注：附件是Burleson写的用来报告Oracle数据库性能等信息的脚本，本文用到）
一．设置合适的SGA
常常有人抱怨服务器硬件很好，但是Oracle就是很慢。很可能是内存分配不合理造成的。(1)假设内存有512M，这通常是小型应用。建议Oracle的SGA大约240M，其中：共享池（SHARED_POOL_SIZE）可以设置60M到80M，根据实际的用户数、查询等来定。
数据块缓冲区可以大致分配120M-150M，8i下需要设置DB_BLOCK_BUFFERS，DB_BLOCK_BUFFER*DB_BLOCK_SIZE等于数据块缓冲区大小。9i 下的数据缓冲区可以用db_cache_size来直接分配。
(2)假设内存有1G，Oracle 的SGA可以考虑分配500M：共享池分配100M到150M，数据缓冲区分配300M到400M。
(3)内存2G，SGA可以考虑分配1.2G，共享池300M到500M，剩下的给数据块缓冲区。
(4)内存2G以上：共享池300M到500M就足够啦，再多也没有太大帮助；(Biti_rainy有专述)数据缓冲区是尽可能的大，但是一定要注意两个问题：一是要给操作系统和其他应用留够内存，二是对于32位的操作系统，Oracle的SGA有1.75G的限制。有的32位操作系统上可以突破这个限制，方法还请看Biti的大作吧。
二．分析表和索引，更改优化模式
Oracle数据库性能默认优化模式是CHOOSE，在这种情况下，如果表没有经过分析，经常导致查询使用全表扫描，而不使用索引。这通常导致磁盘I/O太多，而导致查询很慢。如果没有使用执行计划稳定性，则应该把表和索引都分析一下，这样可能直接会使查询速度大幅提升。
分析表命令可以用ANALYZE TABLE 分析索引可以用ANALYZE INDEX命令。对于少于100万的表，可以考虑分析整个表，对于很大的表，可以按百分比来分析，但是百分比不能过低，否则生成的统计信息可能不准确。可以通过DBA_TABLES的LAST_ANALYZED列来查看表是否经过分析或分析时间，索引可以通过DBA_INDEXES的LAST_ANALYZED列。
下面通过例子来说明分析前后的速度对比。（表CASE_GA_AJZLZ大约有35万数据，有主键）首先在SQLPLUS中打开自动查询执行计划功能。(第一次要执行\RDBMS\ADMIN\utlxplan.sql来创建PLAN_TABLE这个表)
1.SQL&#62; SET AUTOTRACE ON
2.SQL&#62;SET TIMING ON
通过SET AUTOTRACE ON 来查看语句的执行计划，通过SET TIMING ON 来查看语句运行时间。
1.SQL&#62; select count(*) from CASE_GA_AJZLZ;
2.COUNT(*)
3.346639
已用时间: 00: 00: 21.38
1.Execution Plan
2.0 SELECT STATEMENT Optimizer=CHOOSE
3.1 0 SORT (AGGREGATE)
4.2 1 TABLE ACCESS (FULL) OF &#8216;CASE_GA_AJZLZ&#8217;
5.……………………
请注意上面分析中的TABLE ACCESS(FULL)，这说明该语句执行了全表扫描。而且查询使用了21.38秒。这时表还没有经过分析。下面我们来对该表进行分析：
1.SQL&#62; analyze table CASE_GA_AJZLZ compute statistics;
表已分析。已用时间: 00: 05: 357.63。然后再来查询：
1.SQL&#62; select count(*) from CASE_GA_AJZLZ;
2.COUNT(*)
3.346639
已用时间: 00: 00: 00.71
1.Execution Plan
2.0 SELECT [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/644/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10步安全修改Oracle表字段类型</title>
		<link>http://www.chentaoqian.com/archives/640</link>
		<comments>http://www.chentaoqian.com/archives/640#comments</comments>
		<pubDate>Fri, 14 May 2010 10:06:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[字段]]></category>
		<category><![CDATA[类型]]></category>
		<category><![CDATA[表]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=640</guid>
		<description><![CDATA[我们大家都知道Oracle修改字段类型的实际应用中是较为常见的，了解其实际的操作步骤还是有一定好处的，下面就是文章的具体内容的介绍。
因为业务需要,修要修改某个字段数据类型有number(5),变为number(5,2)型
要是没有数据的话直接用以下语句即可
1.alter table tb_test modify permile number(5,2);
但是有数据的话 就不能用上面方法了,
1.alter table tb_test add permile_temp number(5,2)
2.update tb_test set permilepermile_temp=permile;
3.alter table drop column permile;
4.alter table test rename column permile_temp to permile;
Oracle修改字段类型这种方法会使列名发生变化,而且字段顺序增加 有可能发生行迁移,对应用程序会产生影响
以下方法是比较好的方法
不用使列名发生变化 也不会发生表迁移,但这个有个缺点是表要更新两次
如果数据量较大的话 产生的undo和redo更多 ,前提也是要停机做
要是不停机的话 ,也可以采用在线重定义方式来做
以下是脚本:
1.alter table tb_test add permile_temp number;
2.Add/modify columns
3.alter table tb_test modify PERMILE null;
4.update tb_test set permilepermile_temp=permile,permile=null;
5.commit;
6.alter table tb_test modify permile number(5,2);
7.update tb_test set permile=permile_temp,permile_temp=null;
8.commit;
9.alter table tb_test [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/640/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ORACLE基本概念和术语-8</title>
		<link>http://www.chentaoqian.com/archives/616</link>
		<comments>http://www.chentaoqian.com/archives/616#comments</comments>
		<pubDate>Thu, 13 May 2010 11:01:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[术语]]></category>
		<category><![CDATA[概念]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=616</guid>
		<description><![CDATA[§2.11 ORACLE系统的SYS和SYSTEM模式
SYS 和SYSTEM 是每个ORACLE 数据库系统缺省安装的两个帐户。SYS 是所有内部数据库表、结构、过程包、等拥有者，此外它还拥有 V$ 和数据字典视图，并创建所有封装的数据库角色(DBA，CONNECT，RESOURCE)。 Sys是一个唯一能访问特定内部数据字典的用户。 System 也是在安装ORACLE 时创建的用户，用于 DBA 任务的管理。
SYS 安装后的缺省口令为 change_on_install； SYSTEM 缺省口令为 manager。 为了安全，可在安装完成后。 用 ALTER USER sys IDENTIFIED BY password； 命令修改这两个特权帐户的口令。
§2.12 ORACLE系统跟踪文件
所有ORACLE 数据库都至少有一个文件用于记录系统信息，错误及主要事件.这个文件叫做ALERTsid.log(这里的sid 为 oracle 的系统标识)，存储位置由INITsid.ORA 文件的 BACKGROUND_DUMP_DEST 参数给出。
后台进程和用户进程都可以建立各自的跟踪文件，后台进程跟踪文件位置由BACKGROUND_DUMP_DEST 参数给出， 而用户跟踪文件位置由 USER_DUMP_DEST 参数给出. 如参数文件 initora8.ora 中给出：

# define directories to store trace and alert files
background_dump_dest=d:\oracle\admin\ora8\bdump
user_dump_dest=d:\oracle\admin\ora8\udump
后台跟踪文件被命名为 sidPROC.TRC
§2.13 ORACLE系统数据字典
数据字典(data dictionary)是存储在数据库中的所有对象信息的知识库，ORACLE数据库系统使用数据字典获取对象信息和安全信息，而用户和DBA用它来查阅数据库信息。数据字典保存数据对象和段的信息。如表、视图、索引、包、过程以及用户、权限、角色、审计等的信息。数据字典是只读对象，不允许任何人对其进行修改。
§2.14 其它数据对象
ORACLE [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/616/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ORACLE基本概念和术语-7</title>
		<link>http://www.chentaoqian.com/archives/614</link>
		<comments>http://www.chentaoqian.com/archives/614#comments</comments>
		<pubDate>Wed, 12 May 2010 16:40:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[术语]]></category>
		<category><![CDATA[概念]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=614</guid>
		<description><![CDATA[§2.8 Oracle实例
一个Oracle 实例（Instance） 是由SGA，后台进程以及数据文件组成，每个数据库有自己的SGA和独立的Oracle进程集。如图所示：
Oracle 实例和后台进程（instance图）
在分布情况下，为使不同的数据库系统的名字不致混淆，Oracle使用了一个SID（System Identifer）来标识每个Oracle Server的名字，在UNIX环境中以变量Oracle_Sid来区分。

§2.9 多线程服务器 (MTS)
Oracle多线程服务器（Multithreader Server ）允许对数据库进行多个连接以充分共享内存和资源，这使得可以用较少的内存来支持较多的用户。
连接到Oracle数据库的进程都需要占用一定的内存空间，这样如果有过多的进程连接到Oracle，则出现了一个性能瓶颈。
Oracle8 可以允许一万个以上用户同时连接到Oracle，但并不是所有的用户都使用MTS。目前的一些4GL工具并不支持MTS，象VB，PB等不支持MTS，象 VC/C++可以支持MTS。 Oracle多线程服务器有自己的连接池（即共享服务器进程）。由于用户共享开放连接，这比原来的专用方法快的多（消除瓶颈）。
多线程对于一些专用的应用系统来说是非常合适的，比如订单登记系统，顾客提交订单，录入员该订单的数据；另外的录入员在与顾客交涉，并不都在录入数据（专用服务器进程闲着）。单这些终端被迫与系统连着，占据了其他用户的资源。
多线程服务器则消除这些缺点。多线程服务器只维护一个连接池，当某个终端需和系统对话则给其分配一个连接即可。不需要则可以去掉。这样系统的资源被多个用户平摊。
改变参数文件中的相关参数来达到使系统成为多线程服务器配置（重新启动即可有效）。另外，数据库实例必须提供用户数目与所放置的一样才行。
§2.10 Oracle事务处理流程
银行取款业务处理流程：
1． 发出查询余款的SQL语句，如：
Select account_balance From banktable
Where account_number=&#8217;111222333&#8242;
And account_type=&#8217;SAVINGS&#8217;；
l SQL语句通过SGA得到服务器进程；
l 服务器进程检查共享池中有无该条语句，无该条语句则将放置共享池中并准备运行；
l 执行SQL语句，把存放有余款的数据块从数据文件中读到SGA的数据高速缓冲区；
l 显示结果，比如余款为$325。
2． 取款$25：SQL语句为：
Update Bank_table set account_balanct=300
Where account_number=&#8217;111222333&#8242;
And account_type=&#8217;SAVINGS&#8217;；
l 客户进程通过SGA把SQL语句传给服务器进程；
l 服务器进程查找有无该条语句，有执行(；
l 分析SQL语句并存入共享池；
l 执行SQL语句；
l 要处理的数据在数据高速缓冲区吗？是转7；
l 从数据文件中读数据块到数据高速缓冲区；
l 在回滚段中记录原来的数值（$325）；
l 在重做日志中生成该事务的一个拷贝；
l 将数据高速缓冲区中的余额改为$300；
l 银行柜员机通过SGA发出工作完成信号（提交）:
l 在重做日志中记录已完成事务；
l 清除回滚段中的恢复信息（Undo Information）；
l 顾客取钱完成。
]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/614/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>改进前序遍历树-无限分类</title>
		<link>http://www.chentaoqian.com/archives/630</link>
		<comments>http://www.chentaoqian.com/archives/630#comments</comments>
		<pubDate>Wed, 12 May 2010 16:20:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[二叉树]]></category>
		<category><![CDATA[前序遍历]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=630</guid>
		<description><![CDATA[现在，让我们看另一种存储树的方法。递归可能会很慢，所以我们就尽量不使用递归函数。我们也想尽量减少数据库查询的次数。最好是每次只需要查询一次。
我们先把树按照水平方式摆开。从根节点开始（“Food”），然后他的左边写上1。然后按照树的顺序（从上到下）给“Fruit”的左边写上2。这 样，你沿着树的边界走啊走（这就是“遍历”），然后同时在每个节点的左边和右边写上数字。最后，我们回到了根节点“Food”在右边写上18。下面是标上 了数字的树，同时把遍历的顺序用箭头标出来了。

我们称这些数字为左值和右值（如，“Food”的左值是1，右值是18）。正如你所见，这些数字按时了每个节点之间的关系。因为“Red”有3和6 两个值，所以，它是有拥有1-18值的“Food”节点的后续。同样的，我们可以推断所有左值大于2并且右值小于11的节点，都是有2-11的 “Food”节点的后续。这样，树的结构就通过左值和右值储存下来了。这种数遍整棵树算节点的方法叫做“改进前序遍历树”算法。
在继续前，我们先看看我们的表格里的这些值：

注意单词“left”和“right”在SQL中有特殊的含义。因此，我们只能用“lft”和“rgt”来表示这两个列。（译注——其实Mysql 中可以用“`”来表示，如“`left`”，MSSQL中可以用“[]”括出，如“[left]”，这样就不会和关键词冲突了。）同样注意这里我们已经不 需要“parent”列了。我们只需要使用lft和rgt就可以存储树的结构。
获取树
如果你要通过左值和右值来显示这个树的话，你要首先标识出你要获取的那些节点。例如，如果你想获得“Fruit”子树，你要选择那些左值在2到11的节点。用SQL语句表达：
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;
这个会返回：

好吧，现在整个树都在一个查询中了。现在就要像前面的递归函数那样显示这个树，我们要加入一个ORDER BY子句在这个查询中。如果你从表中添加和删除行，你的表可能就顺序不对了，我们因此需要按照他们的左值来进行排序。
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;
就只剩下缩进的问题了。
要显示树状结构，子节点应该比他们的父节点稍微缩进一些。我们可以通过保存一个右值的一个栈。每次你从一个节点的子节点开始时，你把这个节点的右值 添加到栈中。你也知道子节点的右值都比父节点的右值小，这样通过比较当前节点和栈中的前一个节点的右值，你可以判断你是不是在显示这个父节点的子节点。当 你显示完这个节点，你就要把他的右值从栈中删除。要获得当前节点的层数，只要数一下栈中的元素。
&#60;?php
function display_tree($root) {
// 获得$root节点的左边和右边的值
$result = mysql_query(&#8216;SELECT lft, rgt FROM tree &#8216;.&#8217;WHERE title=&#8221;&#8216;.$root.&#8217;&#8221;;&#8217;);
$row = mysql_fetch_array($result);
// 以一个空的$right栈开始
$right = array();
// 现在，获得$root节点的所有后序
$result = mysql_query(&#8216;SELECT title, lft, rgt FROM [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/630/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ORACLE基本概念和术语-6</title>
		<link>http://www.chentaoqian.com/archives/613</link>
		<comments>http://www.chentaoqian.com/archives/613#comments</comments>
		<pubDate>Wed, 12 May 2010 12:06:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[术语]]></category>
		<category><![CDATA[概念]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=613</guid>
		<description><![CDATA[§2.7 Oracle内存结构
前面提到过Oracle的数据库实例是一组后台进程和内存结构组成。而内存结构是包括：
l 系统全局区（System Global Area）
l 程序全局区（Program Global Area）
§2.7.1 系统全局区
Oracle 系统用于存放系统信息的一块存储区域，用户进程和Oracle后台进程都可以使用SGA。在SGA中含有许多组件（不同的部分）。

l 数据高速缓冲区（Data Buffer Cache）
在数据高速缓冲区中存放着Oracle系统最近使用过的数据块（即用户的高速缓冲区），当把数据写入数据库时，它以数据块为单位进行读写，当数据高速缓冲区填满时，则系统自动去掉一些不常被用访问的数据。如果用户要查的数据不在数据高速缓冲区时，Oracle自动从磁盘中去读取。数据高速缓冲区包括三个类型的区：
1) 脏的区（Dirty Buffers）：包含有已经改变过并需要写回数据文件的数据块。
2) 自由区(Free Buffers)：没有包含任何数据并可以再写入的区，Oracle可以从数据文件读数据块该区。
3) 保留区（Pinned Buffers）：此区包含有正在处理的或者明确保留用作将来用的区。
Oracle8i以后将缓冲池分为三个区（使用多个缓冲池特性时）：
1） KEEP 缓冲池（KEEP buffer pool）：在内存中保留数据块，它们不会被从内存中挤掉；
2） RECYCLE缓冲池从不需要的内存将数据移掉；
3） DEFAULT缓冲池包含有被分配的块。
l 重做日志缓冲区（Rado Log Buffer）
任何事务（Transaction）在记录到重做日志（恢复工作需要使用联机重做日志）之前都必须首先放到重做日志缓冲区（Redo Log Buffer）中。然后由日志写入进程（LGWR）定期将此缓冲区的内容写入重做日志中。
l 共享池（Shared Pool）
共享池是SGA保留的区，用于存储如SQL、PL/SQL存储过程及包、数据字典、锁、字符集信息、安全属性等。共享池包含有：
1) 库高速缓存（Library Cache）;
2) 字典高速缓冲区(Dictionary Cache )。
l 库高速缓存（Library Cache）
该区包含有：
1) 共享SQL区（Shared Pool Area）；
2) 私有SQL区(Private SQL Area)；
3) PL/SQL存储过程及包(PL/SQL Procedure and Package)；
4) 控制结构(Control Structure)。
也就是说该区存放有经过语法分析并且正确的SQL语句，并随时都准备被执行。
l 字典高速缓冲区（Data Dictionary Cache）
用于存放Oracle系统管理自身需要的所有信息，这些信息是登录到Oracle的用户名，这些用户有那些数据库对象以及这些数据库对象的位置等。
SVRMGR&#62; Show [...]]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/613/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ORACLE基本概念和术语-5</title>
		<link>http://www.chentaoqian.com/archives/611</link>
		<comments>http://www.chentaoqian.com/archives/611#comments</comments>
		<pubDate>Tue, 11 May 2010 17:07:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[术语]]></category>
		<category><![CDATA[概念]]></category>

		<guid isPermaLink="false">http://www.chentaoqian.com/?p=611</guid>
		<description><![CDATA[§2.6 Oracle数据库进程
一般情况，当数据库启动完成后（Instance 启动成功）就至少有六个后台进程在活动，这些进程根据数据库的需要而分工不同。他们分别是：
1)数据库写入器（DBWR）
数据库写入器（Database Writer）的任务是将修改后的(在内存)数据块写回数据库文件中。在某些操作系统中，Oracle可以有两个BDWR进程。
2)校验点（CKPT）
是一个可选进程。在系统运行中当出现查找数据请求时，系统从数据库中找出这些数据并存入内存区，这样用户就可以对这些内存区数据进行修改等。当需要对被修改的数据写回数据文件时就产生重做日志的交替写（Switch），这时就出现校验点。系统要把内存中灰数据（修改过）块中的信息写回磁盘的数据文件中，此外系统还将重做日志通知控制文件。DBA可以改变参数文件中CHECKPOINT_PROCESS TRUE来使能( 使有效或无效)该进程。

3)日志写入器（LGWR）
用于将SGA区中的日志信息写入日志文件的进程。一般是用户所作的修改值先记入日志文件。等到一定时才真正将修改结果写回数据文件。
4)系统监控器（SMON）
系统监控器（System monitor）是在数据库系统启动时执行恢复工作的强制性进程。比如在并行服务器模式下（两台服务器共用一磁盘组），SMON可以恢复另一台处于失败的数据库。使系统切换到另一台正常的服务器上。
5)进程监控器（PMON）
进程监控器（Process Monitor）用于终止那些失败的用户，释放该用户所占用的资源等。
6)归档器（ARCH）
可选进程，当数据库系统处于归档（ARCHIVELOG）模式时使用。
7)锁（LCKn）
可选进程，当在并行服务器模式可出现多个锁定进程以利于数据库通信。
恢复器（RDCO）
分布式数据库（不同地点有不同机器和不同的Oracle系统）模式下使用的可选进程，用于数据不一致时作的恢复工作。在RECO解决恢复前，所作的修改数据的标志均标为“可疑”。
9)调度（Dnnn）
可选进程，在多线程下使用，即对每个在用（D000，&#8230;，Dnnn）的通信协议至少创建一个调度进程，每个调度进程负责从所联接的用户进程到可用服务器进程的路由请求。把响应返回给合适的用户进程。
10)快照进程(SNPn)
快照进程处理数据库快照的自动刷新，并通过 DBMS_JOB 包运行预定的数据库过程. INITsid.ORA 参数 JOB_QUEUE_PROCESS 设置快照进程数， 参数 JOB_QUEUE_INTERVAL 决定快照进程在被唤醒以处理挂起的作业或事务之前休眠的秒数。
11）并行查询进程（Pnnn）
可根据数据库的活动并行查询选项的设置，ORACLE服务器起动或停止查询进程.这些进程涉及并行索引的创建，表的创建及查询。 启动的数量与参数 PARALLEL_MIN_SERVERS指定的数量相同，不能超出该参数指定的值。
]]></description>
		<wfw:commentRss>http://www.chentaoqian.com/archives/611/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

