﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-呐鹤西飞看春秋-文章分类-Oracle</title><link>http://www.blogjava.net/jnzgrass/category/18501.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 05 Jun 2007 04:08:49 GMT</lastBuildDate><pubDate>Tue, 05 Jun 2007 04:08:49 GMT</pubDate><ttl>60</ttl><item><title>Oracle数据导入导出imp/exp命令</title><link>http://www.blogjava.net/jnzgrass/articles/121834.html</link><dc:creator>东舟</dc:creator><author>东舟</author><pubDate>Mon, 04 Jun 2007 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/jnzgrass/articles/121834.html</guid><wfw:comment>http://www.blogjava.net/jnzgrass/comments/121834.html</wfw:comment><comments>http://www.blogjava.net/jnzgrass/articles/121834.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jnzgrass/comments/commentRss/121834.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jnzgrass/services/trackbacks/121834.html</trackback:ping><description><![CDATA[Oracle数据导入导出imp/exp就相当于oracle数据还原与备份。exp命令可以把数据从远程数据库服务器导出到本地的dmp文件，imp命令可以把dmp文件从本地导入到远处的数据库服务器中。 利用这个功能可以构建两个相同的数据库，一个用来测试，一个用来正式使用。<br /> <br />执行环境：可以在SQLPLUS.EXE或者DOS（命令行）中执行，<br /> DOS中可以执行时由于 在oracle 8i 中  安装目录ora81BIN被设置为全局路径，<br /> 该目录下有EXP.EXE与IMP.EXE文件被用来执行导入导出。<br /> oracle用java编写，SQLPLUS.EXE、EXP.EXE、IMP.EXE这两个文件有可能是被包装后的类文件。<br /> SQLPLUS.EXE调用EXP.EXE、IMP.EXE所包裹的类，完成导入导出功能。<br /> <br />下面介绍的是导入导出的实例。<br />数据导出：<br /> 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:daochu.dmp中<br />   exp system/manager@TEST file=d:daochu.dmp full=y<br /> 2 将数据库中system用户与sys用户的表导出<br />   exp system/manager@TEST file=d:daochu.dmp owner=(system,sys)<br /> 3 将数据库中的表inner_notify、notify_staff_relat导出<br />    exp aichannel/aichannel@TESTDB2 file= d:datanewsmgnt.dmp tables=(inner_notify,notify_staff_relat) <br /><br /> 4 将数据库中的表table1中的字段filed1以"00"打头的数据导出<br />   exp system/manager@TEST file=d:daochu.dmp tables=(table1) query=" where filed1 like '00%'"<br /> <br />  上面是常用的导出，对于压缩，既用winzip把dmp文件可以很好的压缩。<br />  也可以在上面命令后面 加上 compress=y 来实现。<br /><br />数据的导入<br /> 1 将D:daochu.dmp 中的数据导入 TEST数据库中。<br />   imp system/manager@TEST  file=d:daochu.dmp<br />   imp aichannel/aichannel@HUST full=y  file=d:datanewsmgnt.dmp ignore=y<br />   上面可能有点问题，因为有的表已经存在，然后它就报错，对该表就不进行导入。<br />   在后面加上 ignore=y 就可以了。<br /> 2 将d:daochu.dmp中的表table1 导入<br /> imp system/manager@TEST  file=d:daochu.dmp  tables=(table1)<br /> <br /> 基本上上面的导入导出够用了。不少情况要先是将表彻底删除，然后导入。<br /> <br />注意：<br /> 操作者要有足够的权限，权限不够它会提示。<br /> 数据库时可以连上的。可以用tnsping TEST 来获得数据库TEST能否连上。<br /><br />附录一：<br /> 给用户增加导入数据权限的操作<br /> 第一,启动sql*puls<br /> 第二，以system/manager登陆<br /> 第三，create user 用户名 IDENTIFIED BY 密码 （如果已经创建过用户，这步可以省略）<br /> 第四，GRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,<br />   DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,<br />      DBA,CONNECT,RESOURCE,CREATE SESSION  TO 用户名字<br /> 第五, 运行-cmd-进入dmp文件所在的目录,<br />      imp userid=system/manager full=y file=*.dmp<br />      或者 imp userid=system/manager full=y file=filename.dmp<br /><br /> 执行示例:<br /> F:WorkOracle_Databackup&gt;imp userid=test/test full=y file=inner_notify.dmp<br /><br />屏幕显示<br />Import: Release 8.1.7.0.0 - Production on 星期四 2月 16 16:50:05 2006<br />(c) Copyright 2000 Oracle Corporation.  All rights reserved.<br /><br />连接到: Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production<br />With the Partitioning option<br />JServer Release 8.1.7.0.0 - Production<br /><br />经由常规路径导出由EXPORT:V08.01.07创建的文件<br />已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导入<br />导出服务器使用UTF8 NCHAR 字符集 (可能的ncharset转换)<br />. 正在将AICHANNEL的对象导入到 AICHANNEL<br />. . 正在导入表                  "INNER_NOTIFY"          4行被导入<br />准备启用约束条件...<br />成功终止导入，但出现警告。<br /><br /> <br />附录二：<br /> Oracle 不允许直接改变表的拥有者, 利用Export/Import可以达到这一目的.<br />  先建立import9.par,<br />  然后，使用时命令如下：imp parfile=/filepath/import9.par<br />  例 import9.par 内容如下：<br />        FROMUSER=TGPMS       <br />        TOUSER=TGPMS2     （注：把表的拥有者由FROMUSER改为TOUSER，FROMUSER和TOUSER的用户可以不同）          <br />        ROWS=Y<br />        INDEXES=Y<br />        GRANTS=Y<br />        CONSTRAINTS=Y<br />        BUFFER=409600<br />        file==/backup/ctgpc_20030623.dmp<br />        log==/backup/import_20030623.log <br /><br />补充：<br />1.在导入导出命令中加上feedback=1000可以让过程显示一个不断增多的“...”，以改变以往的闪烁的光标<img src ="http://www.blogjava.net/jnzgrass/aggbug/121834.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jnzgrass/" target="_blank">东舟</a> 2007-06-04 14:45 <a href="http://www.blogjava.net/jnzgrass/articles/121834.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库主键设计之思考</title><link>http://www.blogjava.net/jnzgrass/articles/96521.html</link><dc:creator>东舟</dc:creator><author>东舟</author><pubDate>Mon, 29 Jan 2007 07:50:00 GMT</pubDate><guid>http://www.blogjava.net/jnzgrass/articles/96521.html</guid><wfw:comment>http://www.blogjava.net/jnzgrass/comments/96521.html</wfw:comment><comments>http://www.blogjava.net/jnzgrass/articles/96521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jnzgrass/comments/commentRss/96521.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jnzgrass/services/trackbacks/96521.html</trackback:ping><description><![CDATA[<p>主键的无意义性： <br />　我强调主键不应该具有实际的意义，这可能对于一些朋友来说不太认同，比如订单表吧，会有“订单编号”字段，而这个字段呢在业务实际中本身就是应该具有唯一性，具有唯一标识记录的功能，但我是不推荐采用订单编号字段作为主键的，因为具有实际意义的字段，具有“意义更改”的可能性，比如订单编号在刚开始的时候我们一切顺利，后来客户说“订单可以作废，并重新生成订单，而且订单号要保持原订单号一致”，这样原来的主键就面临危险了。因此，具有唯一性的实际字段也代表可以作为主键。因此，我推荐是新设一个字段专门用为主键，此主键本身在业务逻辑上不体现，不具有实际意义。而这种主键在一定程序增加了复杂度，所以要视实际系统的规模大小而定，对于小项目，以后扩展不会很大的话，也查允许用实际唯一的字段作主键的。   <br />　 <br />　主键的选择 <br />　我们现在在思考一下，应该采用什么来作表的主键比较合理，申明一下，主键的设计没有一个定论，各人有各人的方法，哪怕同一个，在不同的项目中，也会采用不同的主键设计原则。 <br /><br />　第一：编号作主键   <br />　此方法就是采用实际业务中的唯一字段的“编号”作为主键设计，这在小型的项目中是推荐这样做的，因为这可以使项目比较简单化，但在使用中却可能带来一些麻烦，比如要进行“编号修改”时，可能要涉及到很多相关联的其他表，就象黎叔说的“后果很严重”;还有就是上面提到的“业务要求允许编号重复时”，我们再那么先知，都无法知道业务将会修改成什么?   <br />　　 <br />　第二：自动编号主键   <br />　这种方法也是很多朋友在使用的，就是新建一个ID字段，自动增长，非常方便也满足主键的原则，优点是：数据库自动编号，速度快，而且是增量增长，聚集型主键按顺序存放，对于检索非常有利;数字型的，占用空间小，易排序，在程序中传递也方便;如果通过非系统增加记录（比如手动录入，或是用其他工具直接在表里插入新记录，或老系统数据导入）时，非常方便，不用担心主键重复问题。   <br /><br />　缺点：其实缺点也就是来自其优点，就是因为自动增长，在手动要插入指定ID的记录时会显得麻烦，尤其是当系统与其他系统集成时，需要数据导入时，很难保证原系统的ID不发生主键冲突（前提是老系统也是数字型的）;如果其他系统主键不是数字型那就麻烦更大了，会导致修改主键数据类型了，这也会导致其他相关表的修改，后果同样很严重;就算其他系统也是数字型的，在导入时，为了区分新老数据，可能想在老数据主键前统一加一个“o”(old)来表示这是老数据，那么自动增长的数字型又面临一个挑战。   <br />　　 <br />　第三：Max加一   <br />　由于自动编号存在那些问题，所以有些朋友就采用自己生成，同样是数字型的，只是把自动增长去掉了，采用在Insert时，读取Max值后加一，这种方法可以避免自动编号的问题，但也存在一个效率问题，如果记录非常大的话，那么Max()也会影响效率的;更严重的是并发性问题，如果同时有两人读到相同的Max后，加一后插入的ID值会重复，这已经是有经验教训的了。   <br />　第四：自制加一   <br />　考虑Max加一的效率后，有人采用自制加一，也就是建一个特别的表，字段为：表名，当前序列值。这样在往表中插入值时，先从此表中找到相应表的最大值后加一，进行插入，有人可能发现，也可能会存在并发处理，这个并发处理，我们可以采用lock线程的方式来避免，在生成此值的时，先Lock，取到值以后，再unLock出来，这样不会有两人同时生成了。这比Max加一的速度要快多了。但同样存在一个问题：在与其他系统集成时，脱离了系统中的生成方法后，很麻烦保证自制表中的最大值与导入后的保持一致，而且数字型都存在上面讲到的“o”老数据的导入问题。因此在“自制加一”中可以把主键设为字符型的。字符型的自制加一我倒是蛮推荐的，应该字符型主键可以应付很多我们意想不到的情况。 <br /><br />　第五：GUID主键   <br />　目前一个比较好的主键是采用GUID，当然我是推荐主键还是字符型的，但值由GUID生成，GUID是可以自动生成，也可以程序生成，而且键值不可能重复，可以解决系统集成问题，几个系统的GUID值导到一起时，也不会发生重复，就算有“o”老数据也可以区分，而且效率很高，在.NET里可以直接使用System.Guid.NewGuid()进行生成，在SQL里也可以使用   NewID()生成。 <br /><br />　优点是：   <br />　同   IDENTITY   列相比，uniqueidentifier   列可以通过   NewID()   函数提前得知新增加的行   ID，为应用程序的后续处理提供了很大方便。   <br /><br />　便于数据库移植，其它数据库中并不一定具有   IDENTITY   列，而   Guid   列可以作为字符型列转换到其它数据库中，同时将应用程序中产生的   GUID   值存入数据库，它不会对原有数据带来影响。   <br /><br />　便于数据库初始化，如果应用程序要加载一些初始数据，   IDENTITY   列的处理方式就比较麻烦，而   uniqueidentifier   列则无需任何处理，直接用   T-SQL   加载即可。   <br /><br />　便于对某些对象或常量进行永久标识，如类的   ClassID，对象的实例标识，UDDI   中的联系人、服务接口、tModel标识定义等。   <br />　　 <br />　缺点是：   <br />　GUID   值较长，不容易记忆和输入，而且这个值是随机、无顺序的。 <br />　GUID   的值有   16   个字节，与其它那些诸如   4   字节的整数相比要相对大一些。这意味着如果在数据库中使用   uniqueidentifier   键，可能会带来两方面的消极影响：存储空间增大；索引时间较慢。   <br /><br />　我也不是推荐GUID最好，其实在不同的情况，我们都可以采用上面的某一种方式，思考了一些利与弊，也方便大家在进行设计时参考。这些也只是我的一点思考而已，而且可能我知识面限制，会有一些误论在里面，希望大家有什么想法欢迎讨论。<br /></p>
		<a href="http://groups.csdn.net/DOTNET/topic/2ba4e27a-3e2d-4ddd-bdba-d02ca9c700fd.aspx">http://groups.csdn.net/DOTNET/topic/2ba4e27a-3e2d-4ddd-bdba-d02ca9c700fd.aspx</a><img src ="http://www.blogjava.net/jnzgrass/aggbug/96521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jnzgrass/" target="_blank">东舟</a> 2007-01-29 15:50 <a href="http://www.blogjava.net/jnzgrass/articles/96521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle中分区表的使用</title><link>http://www.blogjava.net/jnzgrass/articles/95944.html</link><dc:creator>东舟</dc:creator><author>东舟</author><pubDate>Thu, 25 Jan 2007 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/jnzgrass/articles/95944.html</guid><wfw:comment>http://www.blogjava.net/jnzgrass/comments/95944.html</wfw:comment><comments>http://www.blogjava.net/jnzgrass/articles/95944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jnzgrass/comments/commentRss/95944.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jnzgrass/services/trackbacks/95944.html</trackback:ping><description><![CDATA[<font size="2">在大型的企业应用或企业级的数据库应用中，要处理的数据量通常可以达到几十到几百GB，有的甚至可以到TB级。 虽然存储介质和数据处理技术的发展也很快，但是仍然不能满足用户的需求，为了使用户的大量的数据在读写操作和查询中速度更快，Oracle提供了对表和索引进行分区的技术，以改善大型应用系统的性能。<br /><br />使用分区的优点：<br /><br />    1、增强可用性：如果表的某个分区出现故障，表在其他分区的数据仍然可用；<br /><br />    2、维护方便：如果表的某个分区出现故障，需要修复数据，只修复该分区即可；<br /><br />    3、均衡I/O：可以把不同的分区映射到磁盘以平衡I/O，改善整个系统性能；<br /><br />    4、改善查询性能：对分区对象的查询可以仅搜索自己关心的分区，提高检索速度。<br /><br />    Oracle数据库提供对表或索引的分区方法有三种：<br /><br />        1、范围分区<br /><br />        2、Hash分区（散列分区）<br /><br />        3、复合分区<br /><br />    下面将以实例的方式分别对这三种分区方法来说明分区表的使用。为了测试方便，我们先建三个表空间。<br /><br />create tablespace dinya_space01<br />datafile '/test/demo/oracle/demodata/dinya01.dnf' size 50M<br /><br />create tablespace dinya_space01<br />datafile '/test/demo/oracle/demodata/dinya02.dnf' size 50M<br /><br />create tablespace dinya_space01<br />datafile '/test/demo/oracle/demodata/dinya03.dnf' size 50M<br /><br /> <br />1         分区表的创建：1.1     范围分区<br />    范围分区就是对数据表中的某个值的范围进行分区，根据某个值的范围，决定将该数据存储在哪个分区上。如根据序号分区，根据业务记录的创建日期进行分区等。<br /><br />    需求描述：有一个物料交易表，表名：material_transactions。该表将来可能有千万级的数据记录数。要求在建该表的时候使用分区表。这时候我们可以使用序号分区三个区，每个区中预计存储三千万的数据，也可以使用日期分区，如每五年的数据存储在一个分区上。<br /><br />根据交易记录的序号分区建表：<br /><br />SQL&gt; create table dinya_test<br />  2  (<br />  3      transaction_id number primary key,<br />  4      item_id number(8) not null,<br />  5      item_description varchar2(300),<br />  6      transaction_date date  not null<br />  7  )<br />  8  partition by range (transaction_id)<br />  9  (<br /> 10      partition part_01 values less than(30000000) tablespace dinya_space01,<br /> 11      partition part_02 values less than(60000000) tablespace dinya_space02,<br /> 12      partition part_03 values less than(maxvalue) tablespace dinya_space03<br /> 13  );<br /><br />Table created.<br /><br />SQL&gt;<br /><br />建表成功，根据交易的序号，交易ID在三千万以下的记录将存储在第一个表空间dinya_space01中，分区名为:par_01，在三千万到六千万之间的记录存储在第二个表空间：dinya_space02中，分区名为：par_02，而交易ID在六千万以上的记录存储在第三个表空间dinya_space03中，分区名为par_03.<br /><br />根据交易日期分区建表：<br /><br />SQL&gt; create table dinya_test<br />  2  (<br />  3      transaction_id number primary key,<br />  4      item_id number(8) not null,<br />  5      item_description varchar2(300),<br />  6      transaction_date date not null   <br />  7  )<br />  8  partition by range (transaction_date)<br />  9  (<br /> 10  partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')) tablespace dinya_space01,<br /> 11  partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd')) tablespace dinya_space02,<br /> 12  partition part_03 values less than(maxvalue) tablespace dinya_space03<br /> 13  );<br /><br />Table created.<br /><br />SQL&gt;<br /><br />这样我们就分别建了以交易序号和交易日期来分区的分区表。每次插入数据的时候，系统将根据指定的字段的值来自动将记录存储到制定的分区（表空间）中。<br /><br />    当然，我们还可以根据需求，使用两个字段的范围分布来分区，如partition by range ( transaction_id ,transaction_date),分区条件中的值也做相应的改变，请读者自行测试。<br /><br /> <br />1.2     Hash分区（散列分区）<br />    散列分区为通过指定分区编号来均匀分布数据的一种分区类型，因为通过在I/O设备上进行散列分区，使得这些分区大小一致。如将物料交易表的数据根据交易ID散列地存放在指定的三个表空间中：<br /><br />SQL&gt; create table dinya_test<br />  2  (<br />  3      transaction_id number primary key,<br />  4      item_id number(8) not null,<br />  5      item_description varchar2(300),<br />  6      transaction_date date<br />  7  )<br />  8  partition by hash(transaction_id)<br />  9  (<br /> 10      partition part_01 tablespace dinya_space01,<br /> 11      partition part_02 tablespace dinya_space02,<br /> 12      partition part_03 tablespace dinya_space03<br /> 13  );<br /><br />Table created.<br /><br />SQL&gt;<br /><br />    建表成功，此时插入数据，系统将按transaction_id将记录散列地插入三个分区中，这里也就是三个不同的表空间中。<br /><br /> <br />1.3        复合分区<br />    有时候我们需要根据范围分区后，每个分区内的数据再散列地分布在几个表空间中，这样我们就要使用复合分区。复合分区是先使用范围分区，然后在每个分区内再使用散列分区的一种分区方法，如将物料交易的记录按时间分区，然后每个分区中的数据分三个子分区，将数据散列地存储在三个指定的表空间中：<br /><br />SQL&gt; create table dinya_test<br />  2  (<br />  3      transaction_id number primary key,<br />  4      item_id number(8) not null,<br />  5      item_description varchar2(300),<br />  6      transaction_date date<br />  7  )<br />  8  partition by range(transaction_date)subpartition by hash(transaction_id)<br />  9      subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03)<br /> 10  (<br /> 11      partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')),<br /> 12      partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd')),<br /> 13      partition part_03 values less than(maxvalue)<br /> 14  );<br /><br />Table created.<br /><br />SQL&gt;<br /><br />    该例中，先是根据交易日期进行范围分区，然后根据交易的ID将记录散列地存储在三个表空间中。<br /><br /> <br />2         分区表操作<br />以上了解了三种分区表的建表方法，下面将使用实际的数据并针对按日期的范围分区来测试分区表的数据记录的操作。<br />2.1     插入记录：<br />SQL&gt; insert into dinya_test values(1,12,'BOOKS',sysdate);<br />1 row created.<br />SQL&gt; insert into dinya_test values(2,12, 'BOOKS',sysdate+30);<br />1 row created.<br />SQL&gt; insert into dinya_test values(3,12, 'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));<br />1 row created.<br />SQL&gt; insert into dinya_test values(4,12, 'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));<br />1 row created.<br />SQL&gt; insert into dinya_test values(5,12, 'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));<br />1 row created.<br />SQL&gt; insert into dinya_test values(6,12, 'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));<br />1 row created.<br />SQL&gt; commit;<br />Commit complete.<br />SQL&gt;<br /><br />    按上面的建表结果，2006年前的数据将存储在第一个分区part_01上，而2006年到2010年的交易数据将存储在第二个分区part_02上，2010年以后的记录存储在第三个分区part_03上。<br />2.2     查询分区表记录：<br />SQL&gt; select * from dinya_test partition(part_01);<br /><br />TRANSACTION_ID    ITEM_ID       ITEM_DESCRIPTION            TRANSACTION_DATE<br />-------------------------------------------------------------------------------- <br />             1     12            BOOKS                      2005-1-14 14:19:<br />             2     12            BOOKS                      2005-2-13 14:19:<br />SQL&gt;<br /><br />SQL&gt; select * from dinya_test partition(part_02);<br /><br />TRANSACTION_ID     ITEM_ID      ITEM_DESCRIPTION            TRANSACTION_DATE<br />-------------------------------------------------------------------------------- <br />             3      12            BOOKS                       2006-5-30<br />             4      12            BOOKS                       2007-6-23<br />SQL&gt;<br /><br />SQL&gt; select * from dinya_test partition(part_03);<br /><br />TRANSACTION_ID     ITEM_ID         ITEM_DESCRIPTION      TRANSACTION_DATE<br />-------------------------------------------------------------------------------- <br />             5      12               BOOKS                 2011-2-26<br />             6      12               BOOKS                 2011-4-30<br />SQL&gt;<br /><br />    从查询的结果可以看出，插入的数据已经根据交易时间范围存储在不同的分区中。这里是指定了分区的查询，当然也可以不指定分区，直接执行select * from dinya_test查询全部记录。在也检索的数据量很大的时候，指定分区会大大提高检索速度。<br /><br /> <br />2.3     更新分区表的记录：<br />SQL&gt; update dinya_test partition(part_01) t set t.item_description='DESK' where t.transaction_id=1;<br /><br />1 row updated.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />SQL&gt;<br /><br /> <br /><br />    这里将第一个分区中的交易ID=1的记录中的item_description字段更新为“DESK”，可以看到已经成功更新了一条记录。但是当更新的时候指定了分区，而根据查询的记录不在该分区中时，将不会更新数据，请看下面的例子：<br /><br /> <br /><br />SQL&gt; update dinya_test partition(part_01) t set t.item_description='DESK' where t.transaction_id=6;<br /><br />0 rows updated.<br /><br />SQL&gt; commit;<br /><br />Commit complete.<br /><br />SQL&gt;<br /><br />指定了在第一个分区中更新记录，但是条件中限制交易ID为6，而查询全表，交易ID为6的记录在第三个分区中，这样该条语句将不会更新记录。<br /><br /> <br />2.4     删除分区表记录：<br />SQL&gt; delete from dinya_test partition(part_02) t where t.transaction_id=4;<br /><br /> <br /><br />1 row deleted.<br /><br /> <br /><br />SQL&gt; commit;<br /><br /> <br /><br />Commit complete.<br /><br /> <br /><br />SQL&gt;<br /><br /> <br /><br />上面例子删除了第二个分区part_02中的交易记录ID为4的一条记录，和更新数据相同，如果指定了分区，而条件中的数据又不在该分区中时，将不会删除任何数据。<br /><br /> <br />3         分区表索引的使用：<br />分区表和一般表一样可以建立索引，分区表可以创建局部索引和全局索引。当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引。<br />3.1     局部索引分区的建立：<br />SQL&gt; create index dinya_idx_t on dinya_test(item_id)<br />  2  local<br />  3  (<br />  4     partition idx_1 tablespace dinya_space01,<br />  5     partition idx_2 tablespace dinya_space02,<br />  6     partition idx_3 tablespace dinya_space03<br />  7  );<br /><br />Index created.<br /><br />SQL&gt; <br /><br />看查询的执行计划，从下面的执行计划可以看出，系统已经使用了索引：<br /><br />SQL&gt; select * from dinya_test partition(part_01) t where t.item_id=12;<br /><br /> <br /><br />Execution Plan<br /><br />----------------------------------------------------------<br /><br />   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=187)<br /><br />   1    0   TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'DINYA_TEST' (Cost=<br /><br />          2 Card=1 Bytes=187)<br /><br />   2    1     INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1<br /><br />           Card=1)<br /><br />Statistics<br /><br />----------------------------------------------------------<br /><br />          0  recursive calls<br /><br />          0  db block gets<br /><br />          4  consistent gets<br /><br />          0  physical reads<br /><br />          0  redo size<br /><br />        334  bytes sent via SQL*Net to client<br /><br />        309  bytes received via SQL*Net from client<br /><br />          2  SQL*Net roundtrips to/from client<br /><br />          1  sorts (memory)<br /><br />          0  sorts (disk)<br /><br />          2  rows processed<br /><br /> <br /><br />SQL&gt;<br /><br /> <br />3.2     全局索引分区的建立。<br />全局索引建立时global 子句允许指定索引的范围值，这个范围值为索引字段的范围值：<br /><br />SQL&gt; create index dinya_idx_t on dinya_test(item_id)<br />  2  global partition by range(item_id)<br />  3  (<br />  4     partition idx_1 values less than (1000) tablespace dinya_space01,<br />  5     partition idx_2 values less than (10000) tablespace dinya_space02,<br />  6     partition idx_3 values less than (maxvalue) tablespace dinya_space03<br />  7  );<br /><br />Index created.<br /><br />SQL&gt; <br /><br />    本例中对表的item_id字段建立索引分区，当然也可以不指定索引分区名直接对整个表建立索引，如：<br /><br />SQL&gt; create index dinya_idx_t on dinya_test(item_id);<br /><br />Index created.<br /><br />SQL&gt; <br /><br />    同样的，对全局索引根据执行计划可以看出索引已经可以使用：<br /><br />SQL&gt; select * from dinya_test t where t.item_id=12;<br /><br /> <br /><br />Execution Plan<br /><br />----------------------------------------------------------<br /><br />   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=3 Bytes=561)<br /><br />   1    0   TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'DINYA_TEST' (Cost<br /><br />          =2 Card=3 Bytes=561)<br /><br /> <br /><br />   2    1     INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1<br /><br />           Card=3)<br /><br />Statistics<br /><br />----------------------------------------------------------<br /><br />          5  recursive calls<br /><br />          0  db block gets<br /><br />         10  consistent gets<br /><br />          0  physical reads<br /><br />          0  redo size<br /><br />        420  bytes sent via SQL*Net to client<br /><br />        309  bytes received via SQL*Net from client<br /><br />          2  SQL*Net roundtrips to/from client<br /><br />          3  sorts (memory)<br /><br />          0  sorts (disk)<br /><br />          5  rows processed<br /><br /> <br /><br />SQL&gt;<br /><br />    <br />4         分区表的维护：<br />    了解了分区表的建立、索引的建立、表和索引的使用后，在应用的还要经常对分区进行维护和管理。日常维护和管理的内容包括：增加一个分区，合并一个分区及删除分区等等。下面以范围分区为例说明增加、合并、删除分区的一般操作：<br />4.1     增加一个分区:<br />SQL&gt; alter table dinya_test <br />  2  add partition part_04 values less than(to_date('2012-01-01','yyyy-mm-dd')) tablespace dinya_spa<br />ce03;<br /><br />Table altered.<br /><br />SQL&gt;<br /><br /> <br /><br />    增加一个分区的时候，增加的分区的条件必须大于现有分区的最大值，否则系统将提示ORA-14074 partition bound must collate higher than that of the last partition 错误。<br /><br />    <br />4.2     合并一个分区：<br />SQL&gt; alter table dinya_test merge partitions part_01,part_02 into partition part_02;<br /><br />Table altered.<br /><br />SQL&gt; <br /><br />    在本例中将原有的表的part_01分区和part_02分区进行了合并，合并后的分区为part_02,如果在合并的时候把合并后的分区定为part_01的时候，系统将提示ORA-14275 cannot reuse lower-bound partition as resulting partition 错误。<br /><br /> <br />4.3     删除分区：<br />SQL&gt; alter table dinya_test drop partition part_01;<br /><br />Table altered.<br /><br />SQL&gt;<br /><br /> <br /><br />    删除分区表的一个分区后，查询该表的数据时显示，该分区中的数据已全部丢失，所以执行删除分区动作时要慎重，确保先备份数据后再执行，或将分区合并。<br /><br /> <br />5         总结：<br />    需要说明的是，本文在举例说名分区表事务操作的时候，都指定了分区，因为指定了分区，系统在执行的时候则只操作该分区的记录，提高了数据处理的速度。不要指定分区直接操作数据也是可以的。在分区表上建索引及多索引的使用和非分区表一样。此外，因为在维护分区的时候可能对分区的索引会产生一定的影响，可能需要在维护之后重建索引，相关内容请参考分区表索引部分的文档。</font><img src ="http://www.blogjava.net/jnzgrass/aggbug/95944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jnzgrass/" target="_blank">东舟</a> 2007-01-25 15:24 <a href="http://www.blogjava.net/jnzgrass/articles/95944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>查看ORACLE系统参数</title><link>http://www.blogjava.net/jnzgrass/articles/88568.html</link><dc:creator>东舟</dc:creator><author>东舟</author><pubDate>Mon, 18 Dec 2006 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/jnzgrass/articles/88568.html</guid><wfw:comment>http://www.blogjava.net/jnzgrass/comments/88568.html</wfw:comment><comments>http://www.blogjava.net/jnzgrass/articles/88568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jnzgrass/comments/commentRss/88568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jnzgrass/services/trackbacks/88568.html</trackback:ping><description><![CDATA[select   *   from   v$nls_parameters;<img src ="http://www.blogjava.net/jnzgrass/aggbug/88568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jnzgrass/" target="_blank">东舟</a> 2006-12-18 16:11 <a href="http://www.blogjava.net/jnzgrass/articles/88568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>