??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲大成色www永久网站,国产亚洲精品2021自在线,亚洲性线免费观看视频成熟http://www.tkk7.com/tinysun/category/37840.htmlzh-cnFri, 06 Aug 2010 19:59:17 GMTFri, 06 Aug 2010 19:59:17 GMT60?Hadoop q行分布式ƈ行编E??/title><link>http://www.tkk7.com/tinysun/archive/2010/08/06/328098.html</link><dc:creator>何克?/dc:creator><author>何克?/author><pubDate>Fri, 06 Aug 2010 01:42:00 GMT</pubDate><guid>http://www.tkk7.com/tinysun/archive/2010/08/06/328098.html</guid><wfw:comment>http://www.tkk7.com/tinysun/comments/328098.html</wfw:comment><comments>http://www.tkk7.com/tinysun/archive/2010/08/06/328098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tinysun/comments/commentRss/328098.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tinysun/services/trackbacks/328098.html</trackback:ping><description><![CDATA[Hadoop 是一个实C MapReduce 计算模型的开源分布式q行~程框架Q借助?Hadoop, E序员可以轻村֜~写分布式ƈ行程序,其q行于计机集群上,完成量数据的计。本文将介绍 MapReduce 计算模型Q分布式q行计算{基本概念,以及 Hadoop 的安装部|和基本q行Ҏ? <br /> Hadoop ? <br /> <br /> Hadoop 是一个开源的可运行于大规模集上的分布式q行~程框架Q由于分布式存储对于分布式编E来说是必不可少的,q个框架中还包含了一个分布式文gpȝ HDFS( Hadoop Distributed File System )。也许到目前为止QHadoop q不是那么广Zh知,其最新的版本号也仅仅?0.16Q距?1.0 g都还有很长的一D距,但提?Hadoop 一脉相承的另外两个开源项? Nutch ?Lucene ( 三者的创始人都?Doug Cutting ),那绝Ҏ大名鼎鼎。Lucene 是一个用 Java 开发的开源高性能全文索工具包Q它不是一个完整的应用E序Q而是一套简单易用的 API 。在全世界范围内Q已有无数的软gpȝQWeb |站Z Lucene 实现了全文检索功能,后来 Doug Cutting 又开创了W一个开源的 Web 搜烦引擎(<a target="_blank">http://www.nutch.org</a>) Nutch, 它在 Lucene 的基上增加了|络爬虫和一些和 Web 相关的功能,一些解析各cL档格式的插g{,此外QNutch 中还包含了一个分布式文gpȝ用于存储数据。从 Nutch 0.8.0 版本之后QDoug Cutting ?Nutch 中的分布式文件系l以及实?MapReduce 法的代码独立出来Ş成了一个新的开源项 Hadoop。Nutch 也演化ؓZ Lucene 全文索以?Hadoop 分布式计^台的一个开源搜索引擎? <br /> <br /> Z Hadoop,你可以轻村֜~写可处理v量数据的分布式ƈ行程序,q将其运行于由成百上千个l点l成的大规模计算机集上。从目前的情冉| 看,Hadoop 注定会有一个辉煌的未来Q?云计?是目前灸手可热的技术名词,全球各大 IT 公司都在投资和推q这U新一代的计算模式Q? Hadoop 又被其中几家主要的公司用作其"云计?环境中的重要基础软gQ如:雅虎正在借助 Hadoop 开源^台的力量Ҏ Google, 除了资助 Hadoop 开发团队外Q还在开发基?Hadoop 的开源项?Pig, q是一个专注于量数据集分析的分布式计程序。Amazon 公司Z Hadoop 推出?Amazon S3 ( Amazon Simple Storage Service )Q提供可靠,快速,可扩展的|络存储服务Q以及一个商用的云计^?Amazon EC2 ( Amazon Elastic Compute Cloud )。在 IBM 公司的云计算目--"蓝云计划"中,Hadoop 也是其中重要的基软g。Google 正在跟IBM合作Q共同推q基?Hadoop 的云计算? <br /> <br /> <br /> q接~程方式的变? <br /> <br /> 在摩定律的作用下,以前E序员根本不用考虑计算机的性能会跟不上软g的发展,因ؓU每?18 个月QCPU 的主频就会增加一倍,性能也将提升一倍,软gҎ不用做Q何改变,可以n受免费的性能提升。然而,׃晶体电路已l逐渐接近其物理上的性能极限Q摩? 定律?2005 q左叛_始失效了Qhcd也不能期待单?CPU 的速度每隔 18 个月q一倍,为我们提供越来越快的计算性能。Intel, AMD, IBM {芯片厂商开始从多核q个角度来挖?CPU 的性能潜力Q多核时代以及互联网时代的到来,软g~程方式发生重大变革Q基于多核的多线Eƈ发编E以及基于大规模计算机集的分布式ƈ行编E是来? 件性能提升的主要途径? <br /> <br /> 许多U编E方式的重大变化带来一ơY件的q发危机Q因为我们传l的软g方式基本上是单指令单数据的序执行Q这U顺序执行十分符合h cȝ思考习惯,却与q发q行~程格格不入。基于集的分布式ƈ行编E能够让软g与数据同时运行在q成一个网l的许多台计机?q里的每一台计机均可? 是一台普通的 PC 机。这L分布式ƈ行环境的最大优Ҏ可以很容易的通过增加计算机来扩充新的计算l点Qƈ由此获得不可思议的v量计能? 同时又具有相当强的容错能力,一批计结点失效也不会影响计算的正常进行以及结果的正确性。Google 是q么做的Q他们用了叫做 MapReduce 的ƈ行编E模型进行分布式q行~程Q运行在叫做 GFS ( Google File System )的分布式文gpȝ上,为全球亿万用h供搜索服务? <br /> <br /> Hadoop 实现?Google ?MapReduce ~程模型Q提供了单易用的~程接口Q也提供了它自己的分布式文gpȝ HDFS,?Google 不同的是QHadoop 是开源的QQ何h都可以用这个框架来q行q行~程。如果说分布式ƈ行编E的隑ֺ以让普通程序员望而生畏的话,开源的 Hadoop 的出现极大的降低了它的门槛,d本文Q你会发现基?Hadoop ~程非常单,无须Mq行开发经验,你也可以L的开发出分布式的q行E序Qƈ让其令h难以|信地同时运行在数百台机器上Q然后在短时间内完成量数据 的计。你可能会觉得你不可能会拥有数百台机器来q行你的q行E序Q而事实上Q随着"云计?的普及,M人都可以L获得q样的v量计能力。例如现? Amazon 公司的云计算q_ Amazon EC2 已经提供了这U按需计算的租用服务,有兴的读者可以去了解一下,q篇pd文章的第三部分将有所介绍? <br /> <br /> 掌握一点分布式q行~程的知识对来的程序员是必不可的QHadoop 是如此的便好用,何不试一下呢Q也怽已经急不可耐的惌一下基? Hadoop 的编E是怎么回事了,但毕竟这U编E模型与传统的顺序程序大不相同,掌握一点基知识才能更好地理解基?Hadoop 的分布式q行E序是如何编写和q行的。因此本文会先介l一?MapReduce 的计模型,Hadoop 中的分布式文件系l?HDFS, Hadoop 是如何实现ƈ行计的Q然后才介绍如何安装和部|?Hadoop 框架Q以及如何运?Hadoop E序? <br /> <br /> MapReduce 计算模型 <br /> <br /> MapReduce ?Google 公司的核心计模型,它将复杂的运行于大规模集上的ƈ行计过E高度的抽象C两个函数QMap ? Reduce, q是一个o人惊讶的单却又威力巨大的模型。适合?MapReduce 来处理的数据?或Q?有一个基本要? 待处理的数据集可以分解成许多的数据集,而且每一个小数据集都可以完全q行地进行处理? <br /> <br /> <br /> ?1. MapReduce 计算程 <br /> <img src="http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop1/figure1.jpg" alt="" /> <br /> 图一说明了用 MapReduce 来处理大数据集的q程, q个 MapReduce 的计过E简而言之,是大数据集分解ؓ成百上千的小数据集,每个(或若q个)数据集分别由集群中的一个结?一般就是一台普通的计算?q行处理q生 成中间结果,然后q些中间l果又由大量的结点进行合q? 形成最l结果? <br /> <br /> 计算模型的核心是 Map ?Reduce 两个函数Q这两个函数q戯责实玎ͼ功能是按一定的映射规则输入的 <key, value> 对{换成另一个或一?<key, value> 对输出? <br /> <br /> <br /> 表一 Map ?Reduce 函数 <br /> 函数 输入 输出 说明 <br /> Map <k1, v1> List(<k2,v2>) 1. 小数据集进一步解析成一?<key,value> 对,输入 Map 函数中进行处理? <br /> 2. 每一个输入的 <k1,v1> 会输Z?<k2,v2>?<k2,v2> 是计的中间l果?nbsp; <br /> Reduce <k2,List(v2)> <k3,v3> 输入的中间结?<k2,List(v2)> 中的 List(v2) 表示是一批属于同一?k2 ?value <br /> <br /> 以一个计文本文件中每个单词出现的次数的E序ZQ?lt;k1,v1> 可以?<行在文g中的偏移位置, 文g中的一?gt;Q经 Map 函数映射之后QŞ成一批中间结?<单词Q出现次?gt;, ?Reduce 函数则可以对中间l果q行处理Q将相同单词的出现次数进行篏加,得到每个单词的ȝ出现ơ数? <br /> <br /> Z MapReduce 计算模型~写分布式ƈ行程序非常简单,E序员的主要~码工作是实现 Map ?Reduce 函数Q其它的q行~程中的U种复杂问题Q如分布式存储,工作调度Q负载^衡,定w处理Q网l通信{,均由 MapReduce 框架(比如 Hadoop )负责处理Q程序员完全不用操心? <br /> <br /> ?集群上的q行计算 <br /> <br /> MapReduce 计算模型非常适合在大量计机l成的大规模集群上ƈ行运行。图一中的每一?Map d和每一?Reduce d均可以同时运行于一个单独的计算l点上,可想而知其运效率是很高的,那么q样的ƈ行计是如何做到的呢Q? <br /> <br /> 数据分布存储 <br /> <br /> Hadoop 中的分布式文件系l?HDFS ׃个管理结?( NameNode )和N个数据结?( DataNode )l成Q每个结点均是一台普通的计算机。在使用上同我们熟悉的单Z的文件系l非常类|一样可以徏目录Q创建,复制Q删除文Ӟ查看文g内容{。但其底 层实C是把文g切割?BlockQ然后这?Block 分散地存储于不同?DataNode 上,每个 Block q可以复制数份存储于不同? DataNode 上,辑ֈ定w容灾之目的。NameNode 则是整个 HDFS 的核心,它通过l护一些数据结构,记录了每一个文件被切割成了多少?BlockQ这?Block 可以从哪?DataNode 中获得,各个 DataNode 的状态等重要信息。如果你想了解更多的关于 HDFS 的信息,可进一步阅d考资料: [url]The Hadoop Distributed File System:Architecture and Design [/url] <br /> 分布式ƈ行计? <br /> <br /> Hadoop 中有一个作Z控的 JobTrackerQ用于调度和理其它?TaskTracker, JobTracker 可以q行于集中M台计机上。TaskTracker 负责执行dQ必运行于 DataNode 上,?DataNode 既是数据存储l点Q也是计结炏V?JobTracker ?Map d?Reduce d分发l空闲的 TaskTracker, 让这些Q务ƈ行运行,q负责监控Q务的q行情况。如果某一?TaskTracker 出故障了QJobTracker 会将其负责的d转交l另一个空闲的 TaskTracker 重新q行? <br /> <br /> 本地计算 <br /> <br /> 数据存储在哪一台计机上,qq台计算行这部分数据的计,q样可以减少数据在网l上的传输,降低对网l带宽的需求。在 Hadoop q样的基于集的分布式ƈ行系l中Q计结点可以很方便地扩充,而因它所能够提供的计能力近乎是无限的,但是由是数据需要在不同的计机之间动Q故|? l带宽变成了瓉Q是非常宝贵的,“本地计算”是最有效的一U节U网l带宽的手段Q业界把qŞ容ؓ“Ud计算比移动数据更l济”? <br /> <br /> ?2. 分布存储与ƈ行计? <br /> <img src="http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop1/figure2.jpg" alt="" /> <br /> <br /> d_度 <br /> <br /> 把原始大数据集切割成数据集Ӟ通常让小数据集小于或{于 HDFS 中一?Block 的大?~省? 64M)Q这栯够保证一个小数据集位于一台计机上,便于本地计算。有 M 个小数据集待处理Q就启动 M ?Map dQ注意这 M ?Map d分布?N 台计机上ƈ行运行,Reduce d的数?R 则可qh定? <br /> <br /> Partition <br /> <br /> ?Map d输出的中间结果按 key 的范围划分成 R ? R 是预先定义的 Reduce d的个?Q划分时通常使用 hash 函数? hash(key) mod RQ这样可以保证某一D范围内?keyQ一定是׃?Reduce d来处理,可以?Reduce 的过E? <br /> <br /> Combine <br /> <br /> ?partition 之前Q还可以对中间结果先?combineQ即中间结果中有相?key?<key, value> 对合q成一寏Vcombine 的过E与 Reduce 的过E类|很多情况下就可以直接使用 Reduce 函数Q但 combine 是作? Map d的一部分Q在执行?Map 函数后紧接着执行的。Combine 能够减少中间l果?<key, value> 对的数目Q从而减网l流量? <br /> <br /> Reduce d?Map dl点取中间结? <br /> <br /> Map d的中间结果在做完 Combine ?Partition 之后Q以文g形式存于本地盘。中间结果文件的位置会通知L JobTracker, JobTracker 再通知 Reduce d到哪一?DataNode 上去取中间结果。注意所有的 Map d产生中间l果均按?Key 用同一?Hash 函数划分成了 R 份,R ?Reduce d各自负责一D?Key 区间。每? Reduce 需要向许多?Map dl点取得落在其负责的 Key 区间内的中间l果Q然后执?Reduce 函数QŞ成一个最l的l果文g? <br /> <br /> d道 <br /> <br /> ?R ?Reduce dQ就会有 R 个最l结果,很多情况下这 R 个最l结果ƈ不需要合q成一个最l结果。因 R 个最l结果又可以做ؓ另一个计Q务的输入Q开始另一个ƈ行计Q务? <br /> <br /> ?Hadoop 初体? <br /> <br /> Hadoop 支持 Linux ?Windows 操作pȝ, 但其官方|站声明 Hadoop 的分布式操作?Windows 上未做严格测试,只把 Windows 作ؓ Hadoop 的开发^台。在 Windows 环境上的安装步骤如下( Linux q_cMQ且更简单一?: <br /> <br /> (1)?Windows 下,需要先安装 Cgywin, 安装 Cgywin 时注意一定要选择安装 openssh (?Net category )。安装完成之后,?Cgywin 的安装目录如 c:\cygwin\bin 加到pȝ环境变量 PATH 中,q是因ؓq行 Hadoop 要执行一?linux 环境下的脚本和命令? <br /> <br /> (2)安装 Java 1.5.xQƈ?JAVA_HOME 环境变量讄?Java 的安装根目录?C:\Program Files\Java\jdk1.5.0_01? <br /> <br /> (3)?Hadoop 官方|站[url] http://hadoop.apache.org[/url]下蝲Hadoop Core, 最新的E_版本?0.16.0. 下载后的安装包解压C个目录,本文假定解压?c:\hadoop-0.16.0? <br /> <br /> 4)修改 conf/hadoop-env.sh 文gQ在其中讄 JAVA_HOME 环境变量Q?export JAVA_HOME="C:\Program Files\Java\jdk1.5.0_01” (因ؓ路径?Program Files 中间有空|一定要用双引号\径引h) <br /> <br /> xQ一切就l,可以q行 Hadoop 了。以下的q行q程Q需要启?cygwin, q入模拟 Linux 环境。在下蝲?Hadoop Core 包中Q带有几个示例程序ƈ且已l打包成?hadoop-0.16.0-examples.jar。其中有一?WordCount E序Q功能是l计一Ҏ本文件中各个单词出现的次敎ͼ我们先来看看怎么q行q个E序。Hadoop 共有三种q行模式: 单机(非分布式)模式Q伪分布式运行模式,分布式运行模式,其中前两U运行模式体C?Hadoop 分布式计的优势Qƈ没有什么实际意义,但对E序的测试及调试很有帮助Q我们先从这两种模式入手Q了解基?Hadoop 的分布式q行E序是如何编写和q行的? <br /> <br /> 单机(非分布式)模式 <br /> <br /> q种模式在一台单Zq行Q没有分布式文gpȝQ而是直接d本地操作pȝ的文件系l? <br /> <br /> <br /> 代码清单1 <br /> <div id="hr7hn9f" class="dp-highlighter"> <div id="bj9txzn" class="bar"> <div id="9p99bx9" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%24%20cd%20%2Fcygdrive%2Fc%2Fhadoop-0.16.0%0A%24%20mkdir%20test-in%20%20%0A%24%20cd%20test-in%0A%23%E5%9C%A8%20test-in%20%E7%9B%AE%E5%BD%95%E4%B8%8B%E5%88%9B%E5%BB%BA%E4%B8%A4%E4%B8%AA%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%2C%20WordCount%20%E7%A8%8B%E5%BA%8F%E5%B0%86%E7%BB%9F%E8%AE%A1%E5%85%B6%E4%B8%AD%E5%90%84%E4%B8%AA%E5%8D%95%E8%AF%8D%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%0A%24%20echo%20%22hello%20world%20bye%20world%22%20%3Efile1.txt%20%20%20%0A%24%20echo%20%22hello%20hadoop%20goodbye%20hadoop%22%20%3Efile2.txt%0A%24%20cd%20..%0A%24%20bin%2Fhadoop%20jar%20hadoop-0.16.0-examples.jar%20wordcount%20test-in%20test-out%0A%23%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%EF%BC%8C%E4%B8%8B%E9%9D%A2%E6%9F%A5%E7%9C%8B%E6%89%A7%E8%A1%8C%E7%BB%93%E6%9E%9C%EF%BC%9A%0A%24%20cd%20test-out%0A%24%20cat%20part-00000%0Abye%20%20%20%20%201%0Agoodbye%20%201%0Ahadoop%20%202%0Ahello%20%20%20%202%0Aworld%20%20%202" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span>$ cd /cygdrive/c/hadoop-</span><span id="nz9rld7" class="number">0.16</span><span>.</span><span id="zhv9lz9" class="number">0</span><span>  </span></span></li> <li><span>$ mkdir test-in    </span></li> <li><span>$ cd test-in  </span></li> <li><span>#?nbsp;test-in 目录下创Z个文本文? WordCount E序统计其中各个单词出现次?nbsp; </span></li> <li><span>$ echo <span id="ld7frrd" class="string">"hello world bye world"</span><span> >file1.txt     </span></span></li> <li><span>$ echo <span id="79fht7p" class="string">"hello hadoop goodbye hadoop"</span><span> >file2.txt  </span></span></li> <li><span>$ cd ..  </span></li> <li><span>$ bin/hadoop jar hadoop-<span id="77l7pnx" class="number">0.16</span><span>.</span><span id="zthfz9t" class="number">0</span><span>-examples.jar wordcount test-in test-out  </span></span></li> <li><span>#执行完毕Q下面查看执行结果:  </span></li> <li><span>$ cd test-out  </span></li> <li><span>$ cat part-<span id="9v99pnv" class="number">00000</span><span>  </span></span></li> <li><span>bye     <span id="llhj7r9" class="number">1</span><span>  </span></span></li> <li><span>goodbye  <span id="x9bhd9x" class="number">1</span><span>  </span></span></li> <li><span>hadoop  <span id="1j9d9rb" class="number">2</span><span>  </span></span></li> <li><span>hello    <span id="97h9tpx" class="number">2</span><span>  </span></span></li> <li><span>world   <span id="7tzbdf9" class="number">2</span><span>  </span></span></li> </ol> </div> <pre style="display: none;" name="code" class="java">$ cd /cygdrive/c/hadoop-0.16.0 $ mkdir test-in $ cd test-in #?test-in 目录下创Z个文本文? WordCount E序统计其中各个单词出现次? $ echo "hello world bye world" >file1.txt $ echo "hello hadoop goodbye hadoop" >file2.txt $ cd .. $ bin/hadoop jar hadoop-0.16.0-examples.jar wordcount test-in test-out #执行完毕Q下面查看执行结果: $ cd test-out $ cat part-00000 bye 1 goodbye 1 hadoop 2 hello 2 world 2</pre> <br /> <br /> 注意事项Q运?bin/hadoop jar hadoop-0.16.0-examples.jar wordcount test-in test-out Ӟ务必注意W一个参数是 jar, 不是 -jar, 当你?-jar Ӟ不会告诉你是参数错了Q报告出来的错误信息是:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/util/ProgramDriver, W者当时以为是 classpath 的设|问题,费了不时间。通过分析 bin/hadoop 脚本可知Q?jar q不?bin/hadoop 脚本定义的参敎ͼ此脚本会?-jar 作ؓ Java 的参敎ͼJava ?jar 参数表示执行一?Jar 文g(q个 Jar 文g必须是一个可执行?Jar,卛_ MANIFEST 中定义了ȝ), 此时外部定义?classpath 是不起作用的Q因而会抛出 java.lang.NoClassDefFoundError 异常。?jar ?bin/hadoop 脚本定义的参敎ͼ会调?Hadoop 自己的一个工L RunJarQ这个工L也能够执行一?Jar 文gQƈ且外部定义的 classpath 有效? <br /> <br /> 伪分布式q行模式 <br /> <br /> q种模式也是在一台单Zq行Q但用不同的 Java q程模仿分布式运行中的各cȝ?( NameNode, DataNode, JobTracker, TaskTracker, Secondary NameNode )Q请注意分布式运行中的这几个l点的区别: <br /> <br /> 从分布式存储的角度来_集群中的l点׃?NameNode 和若q个 DataNode l成, 另有一?Secondary NameNode 作ؓ NameNode 的备份。从分布式应用的角度来说Q集中的结点由一?JobTracker 和若q个 TaskTracker l成QJobTracker 负责d的调度,TaskTracker 负责q行执行d。TaskTracker 必须q行? DataNode 上,q样便于数据的本地计。JobTracker ?NameNode 则无d同一台机器上? <br /> <br /> (1) 按代码清?修改 conf/hadoop-site.xml。注?conf/hadoop-default.xml 中是 Hadoop ~省的参敎ͼ你可以通过L文g了解 Hadoop 中有哪些参数可供配置Q但不要修改此文件。可通过修改 conf/hadoop-site.xml 改变~省参数|此文件中讄的参数g覆盖 conf/hadoop-default.xml 的同名参数? <br /> <br /> <br /> 代码清单 2 <br /> <div id="7zxptzp" class="dp-highlighter"> <div id="llhr9p7" class="bar"> <div id="7vvf99h" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%3Cconfiguration%3E%0A%20%20%3Cproperty%3E%0A%20%20%20%20%3Cname%3Efs.default.name%3C%2Fname%3E%0A%20%20%20%20%3Cvalue%3Elocalhost%3A9000%3C%2Fvalue%3E%0A%20%20%3C%2Fproperty%3E%0A%20%20%3Cproperty%3E%0A%20%20%20%20%3Cname%3Emapred.job.tracker%3C%2Fname%3E%0A%20%20%20%20%3Cvalue%3Elocalhost%3A9001%3C%2Fvalue%3E%0A%20%20%3C%2Fproperty%3E%0A%20%20%3Cproperty%3E%0A%20%20%20%20%3Cname%3Edfs.replication%3C%2Fname%3E%0A%20%20%20%20%3Cvalue%3E1%3C%2Fvalue%3E%0A%20%20%3C%2Fproperty%3E%0A%3C%2Fconfiguration%3E" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span><configuration>  </span></span></li> <li><span>  <property>  </span></li> <li><span>    <name>fs.<span id="rbdxzxv" class="keyword">default</span><span>.name</name>  </span></span></li> <li><span>    <value>localhost:<span id="179xzv9" class="number">9000</span><span></value>  </span></span></li> <li><span>  </property>  </span></li> <li><span>  <property>  </span></li> <li><span>    <name>mapred.job.tracker</name>  </span></li> <li><span>    <value>localhost:<span id="r9vf99v" class="number">9001</span><span></value>  </span></span></li> <li><span>  </property>  </span></li> <li><span>  <property>  </span></li> <li><span>    <name>dfs.replication</name>  </span></li> <li><span>    <value><span id="b19pp9j" class="number">1</span><span></value>  </span></span></li> <li><span>  </property>  </span></li> <li><span></configuration>  </span></li> </ol> </div> <pre style="display: none;" name="code" class="java"><configuration> <property> <name>fs.default.name</name> <value>localhost:9000</value> </property> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> </property> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration></pre> <br /> <br /> 参数 fs.default.name 指定 NameNode ?IP 地址和端口号。缺省值是 file:///, 表示使用本地文gpȝ, 用于单机非分布式模式。此处我们指定用运行于本机 localhost 上的 NameNode? <br /> <br /> 参数 mapred.job.tracker 指定 JobTracker ?IP 地址和端口号。缺省值是 local, 表示在本地同一 Java q程内执?JobTracker ?TaskTracker, 用于单机非分布式模式。此处我们指定用运行于本机 localhost 上的 JobTracker ( 用一个单独的 Java q程?JobTracker )? <br /> <br /> 参数 dfs.replication 指定 HDFS 中每?Block 被复制的ơ数Qv数据冗余备䆾的作用。在典型的生产系l中Q这个数常常讄?? <br /> <br /> (2)配置 SSH,如代码清?所C? <br /> <br /> <br /> 代码清单 3 <br /> <div id="vhj7z99" class="dp-highlighter"> <div id="bpjjllj" class="bar"> <div id="7lr999f" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%24%20ssh-keygen%20-t%20dsa%20-P%20''%20-f%20~%2F.ssh%2Fid_dsa%20%0A%24%20cat%20~%2F.ssh%2Fid_dsa.pub%20%3E%3E%20~%2F.ssh%2Fauthorized_keys" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span>$ ssh-keygen -t dsa -P </span><span id="zl7f9xp" class="string">''</span><span> -f ~/.ssh/id_dsa   </span></span></li> <li><span>$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys  </span></li> </ol> </div> <pre style="display: none;" name="code" class="java">$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa $ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys</pre> <br /> <br /> 配置完后Q执行一?ssh localhost, 认你的机器可以?SSH q接Qƈ且连接时不需要手工输入密码? <br /> <br /> (3)格式化一个新的分布式文gpȝ, 如代码清?所C? <br /> <br /> <br /> 代码清单 4 <br /> <div id="fp9r9pv" class="dp-highlighter"> <div id="h9hjlhp" class="bar"> <div id="1z9lvtj" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%24%20cd%20%2Fcygdrive%2Fc%2Fhadoop-0.16.0%0A%24%20bin%2Fhadoop%20namenode%20%E2%80%93format%20" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span>$ cd /cygdrive/c/hadoop-</span><span id="ppr79rp" class="number">0.16</span><span>.</span><span id="npzt7rn" class="number">0</span><span>  </span></span></li> <li><span>$ bin/hadoop namenode –format   </span></li> </ol> </div> <pre style="display: none;" name="code" class="java">$ cd /cygdrive/c/hadoop-0.16.0 $ bin/hadoop namenode –format </pre> <br /> <br /> (4) 启动 hadoop q程, 如代码清?所C。控制台上的输出信息应该昄启动?namenode, datanode, secondary namenode, jobtracker, tasktracker。启动完成之后,通过 ps –ef 应该可以看到启动?个新?java q程? <br /> <br /> 代码清单 5 <br /> <div id="nx999xl" class="dp-highlighter"> <div id="1l79v9p" class="bar"> <div id="xh79nvd" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%24%20bin%2Fstart-all.sh%20%20%0A%24%20ps%20%E2%80%93ef" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span>$ bin/start-all.sh    </span></span></li> <li><span>$ ps –ef  </span></li> </ol> </div> <pre style="display: none;" name="code" class="java">$ bin/start-all.sh $ ps –ef</pre> <br /> <br /> (5) q行 wordcount 应用, 如代码清?所C? <br /> <br /> 代码清单 6 <br /> <div id="n7xp9hd" class="dp-highlighter"> <div id="7nd9dlh" class="bar"> <div id="9799px9" class="tools">Java代码 <embed src="http://mintelong.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%24%20bin%2Fhadoop%20dfs%20-put%20.%2Ftest-in%20input%20%20%0A%23%E5%B0%86%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E4%B8%8A%E7%9A%84%20.%2Ftest-in%20%E7%9B%AE%E5%BD%95%E6%8B%B7%E5%88%B0%20HDFS%20%E7%9A%84%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8A%EF%BC%8C%E7%9B%AE%E5%BD%95%E5%90%8D%E6%94%B9%E4%B8%BA%20input%0A%23%E6%89%A7%E8%A1%8C%20bin%2Fhadoop%20dfs%20%E2%80%93help%20%E5%8F%AF%E4%BB%A5%E5%AD%A6%E4%B9%A0%E5%90%84%E7%A7%8D%20HDFS%20%E5%91%BD%E4%BB%A4%E7%9A%84%E4%BD%BF%E7%94%A8%E3%80%82%0A%24%20bin%2Fhadoop%20jar%20hadoop-0.16.0-examples.jar%20wordcount%20input%20output%0A%23%E6%9F%A5%E7%9C%8B%E6%89%A7%E8%A1%8C%E7%BB%93%E6%9E%9C%3A%0A%23%E5%B0%86%E6%96%87%E4%BB%B6%E4%BB%8E%20HDFS%20%E6%8B%B7%E5%88%B0%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%86%8D%E6%9F%A5%E7%9C%8B%EF%BC%9A%0A%24%20bin%2Fhadoop%20dfs%20-get%20output%20output%20%0A%24%20cat%20output%2F*%0A%23%E4%B9%9F%E5%8F%AF%E4%BB%A5%E7%9B%B4%E6%8E%A5%E6%9F%A5%E7%9C%8B%0A%24%20bin%2Fhadoop%20dfs%20-cat%20output%2F*%0A%24%20bin%2Fstop-all.sh%20%23%E5%81%9C%E6%AD%A2%20hadoop%20%E8%BF%9B%E7%A8%8B" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="14" height="15"></div> </div> <ol class="dp-j" start="1"> <li><span><span>$ bin/hadoop dfs -put ./test-in input    </span></span></li> <li><span>#本地文件系l上?nbsp;./test-in 目录拷到 HDFS 的根目录上,目录名改?nbsp;input  </span></li> <li><span>#执行 bin/hadoop dfs –help 可以学习各种 HDFS 命o的用?nbsp; </span></li> <li><span>$ bin/hadoop jar hadoop-<span id="hjjnnvv" class="number">0.16</span><span>.</span><span id="f799djh" class="number">0</span><span>-examples.jar wordcount input output  </span></span></li> <li><span>#查看执行l果:  </span></li> <li><span>#文件从 HDFS 拷到本地文gpȝ中再查看Q?nbsp; </span></li> <li><span>$ bin/hadoop dfs -get output output   </span></li> <li><span>$ cat output/*  </span></li> <li><span>#也可以直接查?nbsp; </span></li> <li><span>$ bin/hadoop dfs -cat output/*  </span></li> <li><span>$ bin/stop-all.sh #停止 hadoop q程  </span></li> </ol> </div> <pre style="display: none;" name="code" class="java">$ bin/hadoop dfs -put ./test-in input #本地文件系l上?./test-in 目录拷到 HDFS 的根目录上,目录名改?input #执行 bin/hadoop dfs –help 可以学习各种 HDFS 命o的用? $ bin/hadoop jar hadoop-0.16.0-examples.jar wordcount input output #查看执行l果: #文件从 HDFS 拷到本地文gpȝ中再查看Q? $ bin/hadoop dfs -get output output $ cat output/* #也可以直接查? $ bin/hadoop dfs -cat output/* $ bin/stop-all.sh #停止 hadoop q程</pre> <br /> <br /> 故障诊断 <br /> <br /> (1) 执行 $ bin/start-all.sh 启动 Hadoop q程后,会启??java q程, 同时会在 /tmp 目录下创Z?pid 文g记录q些q程 ID 受通过q五个文Ӟ可以得知 namenode, datanode, secondary namenode, jobtracker, tasktracker 分别对应于哪一?Java q程。当你觉?Hadoop 工作不正常时Q可以首先查看这5?java q程是否在正常运行? <br /> <br /> (2) 使用 web 接口。访?http://localhost:50030 可以查看 JobTracker 的运行状态。访? http://localhost:50060 可以查看 TaskTracker 的运行状态。访?http://localhost:50070 可以查看 NameNode 以及整个分布式文件系l的状态,览分布式文件系l中的文件以?log {? <br /> <br /> (3) 查看 ${HADOOP_HOME}/logs 目录下的 log 文gQnamenode, datanode, secondary namenode, jobtracker, tasktracker 各有一个对应的 log 文gQ每一ơ运行的计算d也有对应?log 文g。分析这?log 文g有助于找到故障原因? <br /> <br /> <br /> l束? <br /> <br /> 现在Q你已经了解?MapReduce 计算模型Q分布式文gpȝ HDFSQ分布式q行计算{的基本原理, q且有了一个可以运行的 Hadoop 环境Q运行了一个基?Hadoop 的ƈ行程序? <img src ="http://www.tkk7.com/tinysun/aggbug/328098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tinysun/" target="_blank">何克?/a> 2010-08-06 09:42 <a href="http://www.tkk7.com/tinysun/archive/2010/08/06/328098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解SQL Server执行计划 http://www.tkk7.com/tinysun/archive/2010/04/15/318438.html何克?/dc:creator>何克?/author>Thu, 15 Apr 2010 09:12:00 GMThttp://www.tkk7.com/tinysun/archive/2010/04/15/318438.htmlhttp://www.tkk7.com/tinysun/comments/318438.htmlhttp://www.tkk7.com/tinysun/archive/2010/04/15/318438.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/318438.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/318438.html如果在执行计划中看到如下所C的M一,应该将它们视作警告信号q调查它们以扑և潜在的性能问题。从性能斚w来说Q下面所C的每一w是不理想的?/p>

 Index or table scans(索引或者表扫描)Q可能意味着需要更好的或者额外的索引?/p>

Bookmark Lookups(书签查找)Q考虑修改当前的聚集烦引,使用复盖索引Q限制SELECT语句中的字段数量?/p>

Filter(qo)Q在WHERE从句中移除用到的M函数Q不要在SQL语句中包含视图,可能需要额外的索引?/p>

Sort(排序)Q数据是否真的需要排序?可否使用索引来避免排序?在客L排序是否会更加有效率Q?/p>

 

查看SQL Server囑Ş执行计划Ӟ可以查找的非常有用的一个东西就是查询优化器如何为给定的查询使用索引来从表中获取数据。通过查看是否有用到烦引,以及索引如何被用,都有助于判断当前的烦引是否得查询执行得可能的快?/p>

鼠标移到图形执行计划上的表?以及它的图标)上面Q就会弹Z个窗口,从它上面可以看到一些信息。这些信息让你知道是否有用到索引来从表中获取数据Q以及它是如何用的。这些信息包括:

·     Table Scan(表扫?Q如果看到这个信息,p明数据表上没有聚集烦引,或者查询优化器没有使用索引来查找。意卌料表的每一行都被检查到。如果资料表相对较小的话Q表扫描可以非常快速,有时甚至快过使用索引?/p>

因此Q当看到有执行表扫描ӞW一件要做的事就是看看数据表有多数据行。如果不是太多的话,那么表扫描可能提供了最好的M效能。但如果数据表大的话Q表扫描极可能需要长旉来完成,查询效能大受媄响。在q种情况下,需要仔l研IӞ为数据表增加一个适当的烦引用于这个查询?/p>

假设你发现某查询使用了表扫描Q有一个合适的非聚集烦引,但它没有用到。这意味着什么呢Qؓ什么这个烦引没有用到呢Q如果需要获得的数据量相Ҏ据表大小来说非常大,或者数据选择性不?意味着同一个字D中重复的值很?Q表扫描l常会比索引扫描快。例如,如果一个数据表?0000个数据行Q查询返?000行,如果q个表没有聚集烦引的话,那么表扫描将比用一个非聚集索引更快。或者如果数据表?0000个数据行Q且同一个字D?WHERE条g句有用到q个字段)上有1000W重复的数据Q表扫描也会比用非聚集索引更快?/p>

查看囑Ş执行计划上的数据表上的弹出式H口Ӟh?#8221;预估的资料行?Estimated Row Count)”。这个数字是查询优化器作出的多少个数据行会被q回的最x。如果执行了表扫描且”预估的数据行?#8221;数值很高的话,意味着q回的记录数很多Q查询优化器认ؓ执行表扫描比使用可用的非聚集索引更快?/p>

·     Index Seek(索引查找)Q烦引查找意味着查询优化器用了数据表上的非聚集索引来查找数据。性能通常会很快,其是当只有数的数据行被返回时?/p>

·     Clustered Index Seek(聚集索引查找)Q这指查询优化器使用了数据表上的聚集索引来查找数据,性能很快。实际上Q这是SQL Server能做的最快的索引查找cd?/p>

·     Clustered Index Scan(聚集索引扫描)Q聚集烦引扫描与表扫描相|不同的是聚集索引扫描是在一个徏有聚集烦引的数据表上执行的。和一般的表扫描一P聚集索引扫描可能表明存在效能问题。一般来_有两U原因会引此聚集索引扫描的执行。第一个原因,相对于数据表上的整体数据行数目,可能需要获取太多的数据行。查?#8221;预估的数据行数量(Estimated Row Count)”可以Ҏ加以验证。第二个原因Q可能是׃WHERE条g句中用到的字D选择性不高。在M情况下,与标准的表扫描不同,聚集索引扫描q不会LL找数据表中的所有数据,所以聚集烦引扫描一般都会比标准的表扫描要快。通常来说Q要聚集烦引扫描改成聚集烦引查找,你唯一能做的是重写查询语句Q让语句限制性更多,从而返回更的数据行?/p>

 

l大多数情况下,查询优化器会对连接进行分析,按最有效率的序Q用最有效率的q接cd来对数据表进行连接。但q不L如此。在囑Ş执行计划中你可以看到代表查询所使用到的各种不同q接cd的图标。此外,每个q接图标都有两个头指向它。指向连接图标的上面的箭头代表该q接的外部表Q下面的头则代表这个连接的内部表。箭头的另一头则指向被连接的数据表名?/p>

 


有时在多表连接的查询中,头的另一头指向的q不是一个数据表Q而是另一个连接。如果将鼠标Ud指向外部q接与内部连接的头上,可以看C个弹出式H口Q告诉你有多数据行被发送至q个q接来进行处理。外部表应该L比内部表含有更少的数据行。如果不是,则说明查询优化器所选择的连接顺序可能不正确(下面是关于这个话题的更多信息)?/p>

 


首先Q让我们来看看连接类型。SQL Server可以使用三种不同的技术来q接资料表:嵌套循环(nested loop)Q散?hash)Q以及合q?merge)。一般来_嵌套循环是最快的q接cdQ但如果不可能用嵌套@环的话,则会用到散列或者合q作为合适的q接cd。两者都比嵌套@环连接慢?/p>

 


当连接大表时Q则合ƈq接可能是最佳选项Q而非嵌套循环q接。唯一的明这一点的方式是对两者都q行试以查看哪一个最有效率?/p>

 


如果你怀疑某个查询速度慢的原因可能是因为它所使用的连接类型不理想Q那么你可以使用q接提示来复盖查询优化器的选择。在使用q接提示之前Q你需要花费一些时间去了解一下每U连接类型以及它们的工作方式。这是一个复杂的话题Q超Z本文的讨围?/p>

 


查询优化器选择最有效率的q接cd来连接数据表。例如,嵌套循环q接的外部表应该是连接的两个表中较小的那个表。散列连接也是一P它的外部表应该是较小的那个表。如果你觉得查询优化器选择的连接顺序是错误的,可以使用q接提示来复盖它?/p>

 

你常怼在图形执行计划上看到标识?#8221;书签查找(Bookmark Lookup)”的图标。书{查扄当常见。书{查扄本质是告诉你查询处理器必M数据表或者聚集烦引中来查扑֮所需要的数据行,而不是从非聚集烦引中直接d?/p>

 


打比方说Q如果一个查询语句的SELECT,JOIN以及WHERE子句中的所有字D,都不存在于那个用来定位符合查询条件的数据行的非聚集烦引中Q那么查询优化器׃得不做额外的工作在数据表或聚集烦引中查找那些满q个查询语句的字Dc?/p>

 


另一U引起书{查扄原因是用了SELECT *。由于在l大多情况下它会q回比你实际所需更多的数据,所以应该永不用SELECT *.

 


从性能斚w来说Q书{查找是不理想的。因为它会请求额外的I/O开销在字D中查找以返回所需的数据行?/p>

 


如果认ؓ书签查找防碍了查询的性能Q那么有四种选择可以用来避免它:可以建立WHERE子句会用到的聚集索引Q利用烦引交集的优势Q徏立覆盖的非聚集烦引,或?如果是SQL Server 2000/2005企业版的?可以建立索引视图。如果这些都不可能,或者用它们中的Q何一个都会耗用比书{查找更多的资源Q那么书{查扑ְ是最佳的选择了。[


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/xiao_hn/archive/2009/06/11/4259628.aspx



]]>
SQLserver锁和事务隔离U别的比较与使用http://www.tkk7.com/tinysun/archive/2010/02/04/311962.html何克?/dc:creator>何克?/author>Thu, 04 Feb 2010 07:01:00 GMThttp://www.tkk7.com/tinysun/archive/2010/02/04/311962.htmlhttp://www.tkk7.com/tinysun/comments/311962.htmlhttp://www.tkk7.com/tinysun/archive/2010/02/04/311962.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/311962.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/311962.html对象

?span style="font: 7pt Times New Roman">     ?/strong>Q每?/span>SQL语句

?span style="font: 7pt Times New Roman">     隔离Q事?/span>

?/strong>

?/span>

q发问题

丢失更新

未确认的dQ脏读)

不一致的分析Q非重复读)Q多ơ读取相同的数据Q行Q不一_其他用户更改updateQ?/span>

qd读:多次d有不存在和新增的数据Q其他用h?/span>insert或删?/span>deleteQ?/span>

隔离U别

隔离U别

脏读

不可重复d

qd

说明

未提交读(read uncommitted)

?/span>

?/span>

?/span>

如果其他事务更新Q不是否提交,立即执行

提交?span>(read committed默认)

?/span>

?/span>

?/span>

d提交q的数据。如果其他事务更新没提交Q则{待

可重复读(repeatable read)

?/span>

?/span>

?/span>

查询期间Q不允许其他事务update

可串行读(serializable)

?/span>

?/span>

?/span>

查询期间Q不允许其他事务insert或delete

提交?/span>

假设存在?/span>AQ如下所C?/span>

A1

A2

A3

11

21

31

12

22

32

打开查询分析器ƈ打开两个q接Q分别输入如下两个事务:

--事务?/span>

SET TRANSACTION ISOLATION LEVEL READ Committed

begin tran

update A set A2 = 20 where A1 = 11

waitfor delay '00:00:10'

rollback tran

--事务?/span>

SET TRANSACTION ISOLATION LEVEL READ Committed

select * from A where A1 = 11

如果先运行事务ⅠQ然后紧接着q行事务Ⅱ,则事务Ⅱ要等?/span>10U钟Q?/span>一个连接在修改数据块时别的q接也不能查询这个数据块Q直到解?/strong>。反之亦Ӟȝ时候不能写和修?/span>Q?/span>

如果把事务Ⅱ改ؓ如下

SET TRANSACTION ISOLATION LEVEL READ UNCommitted

select * from A where A1 = 11

那么事务Ⅱ不需{待Q立x行(可以看出READ UNCommitted事务select不对数据发出׃n?/strong>Q?/span>

?/strong>Q?/span>(q里主要讲解 ׃n?/strong> ?/span> 排他?/strong> 两种l常用到?strong style="background-color: #99ff99; color: black">?/strong>)

׃n?/strong>主要是ؓ了共享读Q?/span>selectQ,如果存在事务Q一个或多个Q拥有对表中数据Q关?strong style="background-color: #99ff99; color: black">?/strong>数据的多,?strong style="background-color: #99ff99; color: black">?/strong>的粒度而定Q的׃n?/strong>Q不允许?strong style="background-color: #99ff99; color: black">?/strong>定的数据q行更新(update)Q从?/strong>的角度讲Q即不允怺务获取排?strong style="background-color: #99ff99; color: black">?/strong>Q要{到所有的׃n?/strong>都释放掉Q。反之,如果事务Ҏ据已l具有排?strong style="background-color: #99ff99; color: black">?/strong>Q只能有一个)Q其他的事务׃能对?/strong>定的数据获取׃n?/strong>和排?strong style="background-color: #99ff99; color: black">?/strong>Q即排他?/strong>与共?strong style="background-color: #99ff99; color: black">?/strong>不能兼容Q更多信息请查看?/strong>兼容?/span>Q,在此特别一?/span> ?/strong>定的数据 Q因为有的资料上讲解?/span>“一个连接写的时候,另一个连接可以写”Q实际上写的q种情况是各个连接的d的数据不是相同的行,也就是说各个q接?/strong>定的数据不同?/span>

Ҏ以上分析Q我们ȝ为六个字?#8220;׃n读,排他?/span>”?/span>

了解?strong style="background-color: #99ff99; color: black">?/strong>的情况之后,又涉及到一个问题。事务究竟要保持?/strong>多久?/span>?

一般来_׃n?/strong>?strong style="background-color: #99ff99; color: black">?/strong>定时间与事务?strong style="background-color: #ffff66; color: black">隔离U别有关Q如?strong style="background-color: #ffff66; color: black">隔离U别?/span>Read Committed的默认别,只在d(select)的期间保?strong style="background-color: #99ff99; color: black">?/strong>定,卛_查询出数据以后就释放?strong style="background-color: #99ff99; color: black">?/strong>Q如?strong style="background-color: #ffff66; color: black">隔离U别为更高的Repeatable read?/span>SerializableQ直C务结束才释放?/strong>。另说明Q如?/span>select语句中指定了HoldLock提示Q则也要{到事务l束才释?strong style="background-color: #99ff99; color: black">?/strong>?/span>

排他?/strong>直到事务l束才释放?/span>

做出了以上分析,现在我们可能会存在这L疑问Q到底在执行SQL语句的时候发Z么样?strong style="background-color: #99ff99; color: black">?/strong>呢,q就׃务的隔离U别军_了。一般情况,读语?/span>(select)发出׃n?/strong>Q写语句(update,insert,delete)发出排他?/strong>。但是,如果q样不能满我们的要求怎么办呢Q有没有更多选择呢,别急,SQLserver为我们提供了?/strong>定提C的概念?/span>

       ?/strong>定提C对SQL语句q行特别指定Q这个指定将覆盖事务?strong style="background-color: #ffff66; color: black">隔离U别。下面对各个?/strong>定提C分别予以介l(更多资料h?/span>SQLserver的联机帮助)Q笔者做Z以下分类?/span>

cd1

?span style="font: 7pt Times New Roman">     READUNCOMMITTEDQ不发出?/strong>

?span style="font: 7pt Times New Roman">     READCOMMITTEDQ发出共?strong style="background-color: #99ff99; color: black">?/strong>Q保持到dl束

?span style="font: 7pt Times New Roman">     REPEATABLEREADQ发出共?strong style="background-color: #99ff99; color: black">?/strong>Q保持到事务l束

?span style="font: 7pt Times New Roman">     SERIALIZABLEQ发出共?strong style="background-color: #99ff99; color: black">?/strong>Q保持到事务l束

cd2

?span style="font: 7pt Times New Roman">     NOLOCKQ不发出?/strong>。等同于READUNCOMMITTED

?span style="font: 7pt Times New Roman">     HOLDLOCKQ发出共?strong style="background-color: #99ff99; color: black">?/strong>Q保持到事务l束。等同于SERIALIZABLE

?span style="font: 7pt Times New Roman">     XLOCKQ发出排?strong style="background-color: #99ff99; color: black">?/strong>Q保持到事务l束?/span>

?span style="font: 7pt Times New Roman">     UPDLOCKQ发出更?strong style="background-color: #99ff99; color: black">?/strong>Q保持到事务事务l束。(更新?/strong>Q不d别的事物Q允许别的事物读数据Q即更新?/strong>可与׃n?/strong>兼容Q,但他保自上ơ读取数据后数据没有被更?/span>Q?/span>

?span style="font: 7pt Times New Roman">     READPASTQ发出共?strong style="background-color: #99ff99; color: black">?/strong>Q但跌?/strong>定行Q它不会被阻塞?span style="color: red">适用条gQ提交读?strong style="background-color: #ffff66; color: black">隔离U别Q行U?strong style="background-color: #99ff99; color: black">?/strong>Q?/span>select语句中?/span>

cd3

?span style="font: 7pt Times New Roman">     ROWLOCKQ行U?strong style="background-color: #99ff99; color: black">?/strong>

?span style="font: 7pt Times New Roman">     PAGLOCKQ页U?strong style="background-color: #99ff99; color: black">?/strong>

?span style="font: 7pt Times New Roman">     TABLOCKQ表?/strong>

?span style="font: 7pt Times New Roman">     TABLOCKXQ表排他?/strong>

讲解?strong style="background-color: #99ff99; color: black">?/strong>后,下面l合一个具体实例,具体看一?strong style="background-color: #99ff99; color: black">?/strong>的用?/span>

       在很多系l中Q经怼遇到q种情况Q要保持一个编L唯一Q如会计软g中的凭证的编受一U编L处理是这LQ把表中的最大编号保存到表中Q然后在q个~号上篏加,形成新的~号。这个过E对q发处理要求非常高,下面我们来模拟q个q程Q看如何保持~号的唯一性?/span>

       新徏一张表code来保存凭证的最大编受字D如下:~号:bh(numeric(18,0)),凭证表名pinzheng(varchar(50))

假设表中有这L一条记录:

Bh

Pinzheng

18000

会计凭证

 

新徏一个存储过E来生成新的凭证~号Q如下:

CREATE PROCEDURE up_getbh  AS

       Begin Tran

              Declare @numnewbh numeric(18,0)

              select  @numnewbh = bh FROM code  WITH (UPDLOCK,ROWLOCK) where pinzheng = '会计凭证'

              set @numnewbh = @numnewbh + 1

              update code set  bh = @numnewbh where pinzheng = '会计凭证'

              print @numnewbh

       Commit tran

GO

然后Q打开查询分析器,q多开几个q接Q笔者开?/span>8个连接,模拟?/span>8个h同时q发Q读者可以开更多的连接进行试验)Q把cM以下q样的语句复制到每个q接H口中,

declare @i numeric(18,0)

set @i = 1

while @i = 1

Begin

       if getdate() > '2004-07-22 14:23'  --讑֮一个时_到此旉同时执行upgetbh存储q程

              set @i = 0      

end

exec up_getbh

然后Q接q运行各个连接,?/span>2004-7-22 14Q?/span>23 q一刻,各个q接同时q行up_getbh。从q行l果可以看出q接序出现18001开始个数字Qƈ没有重号或丢L现象?/span>

分析Q由?/span>up_getbh中的select语句使用了更?strong style="background-color: #99ff99; color: black">?/strong>Q因更新?/strong>之间不能兼容Q所以各个连接要{到所有其他的q接释放?strong style="background-color: #99ff99; color: black">?/strong>才能执行Q而更?strong style="background-color: #99ff99; color: black">?/strong>的释放要{到事务l束Q这样就不会发生号出错的现象了?/span>



]]>
Sql Server 锁机?http://www.tkk7.com/tinysun/archive/2010/02/04/311956.html何克?/dc:creator>何克?/author>Thu, 04 Feb 2010 06:38:00 GMThttp://www.tkk7.com/tinysun/archive/2010/02/04/311956.htmlhttp://www.tkk7.com/tinysun/comments/311956.htmlhttp://www.tkk7.com/tinysun/archive/2010/02/04/311956.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/311956.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/311956.html转自Q?a >http://blog.csdn.net/missmecn/archive/2008/10/06/3019798.aspx
 
?span class="hilite3">锁机?/font>的研I要具备两个条gQ?
1Q数据量?
2Q多个用户同时ƈ?
如果~少q两个条Ӟ数据库不Ҏ产生死锁问题。研Iv来可能会事倍功半。如果这两个条g都有Q但你还是按数据库缺省设|来处理数据Q则会带来很多的问题Q比如:
1Q丢失更?
A,B两个用户d一数据q进行修?其中一个用L修改l果破坏了另一个修改的l果
2Q脏?
A用户修改了数据时,B用户也在读该数据,但A用户因ؓ某些原因取消了对数据的修?数据恢复原?此时B得到的数据就与数据库内的数据产生了不一?
3Q不可重复读
B用户d该数据ƈ修改,同时QA用户也在d数据Q此时A用户再读取数据时发现前后两次的g一?
SQL SERVER 作ؓ多用h据库pȝQ以事务为单位,使用锁来实现q发控制?span class="hilite1">SQLSERVER使用“?#8221;保事务完整性和数据一致性?

一、锁的概?/strong>
锁(LOCKINGQ是最常用的ƈ发控制机构。是防止其他事务讉K指定的资源控制、实现ƈ发控制的一U主要手Dc锁是事务对某个数据库中的资源(如表和记录)存取前,先向pȝ提出hQ封锁该资源Q事务获得锁后,卛_得对数据的控制权Q在事务释放它的锁之前,其他事务不能更新此数据。当事务撤消后,释放被锁定的资源?
当一个用户锁住数据库中的某个对象Ӟ其他用户׃能再讉K该对?

二、锁的粒?/strong>
SQL Server 2000 h多粒度锁定,允许一个事务锁定不同类型的的资源。ؓ了锁定的成本减x,SQL Server 自动资源锁定在适合d的别。锁定在较小的粒度(例如行)可以增加q发但需要较大的开销Q因为如果锁定了许多行,则需要控制更多的锁。锁定在较大的粒度(例如表)ƈ发而言是相当昂늚Q因为锁定整个表限制了其它事务对表中L部分q行讉KQ但要求的开销较低Q因为需要维护的锁较?span class="hilite1">SQL Server 可以锁定行、页、扩展盘区、表、库{资源?
  • 资源 U别 描述
  • RID 行锁 表中的单个行
  • Key 行?索引中的?
  • Page ?一个数据页或者烦引页
  • Extent ?一l数据页或者烦引页
  • Table 表?整个?
  • Database 数据库?整个数据?

选择多大的粒度,ҎҎ据的操作而定。如果是更新表中所有的行,则用表?如果是更新表中的某一行,则用行锁?
行锁是一U最优锁Q因U锁不可能出现数据既被占用又没有使用的浪费现象。但是,如果用户事务中频J对某个表中的多条记录操作,导致对该表的许多记录行都加上了行锁,数据库系l中锁的数目会急剧增加Q这样就加重了系l负P影响pȝ性能。因此,?span class="hilite1">SQL Server中,q支持锁升(lock escalation)?
所谓锁升是指调整锁的_度Q将多个低粒度的锁替换成数的更高粒度的锁,以此来降低系l负荗在SQL Server中当一个事务中的锁较多Q达到锁升门限Ӟpȝ自动行U锁和页面锁升U锁?
特别值得注意的是Q在SQL Server中,锁的升门限以及锁升U是ql自动来定的,不需要用戯|?

三、锁的模?/strong>
锁模式以及描q表

    锁模?描述
  • ׃nQSQ?用于不更Ҏ不更新数据(只读操作Q,如SELECT语句
  • 更新QUQ?用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见Ş式的死锁?
  • 排它QXQ?用于数据修改操作Q例?INSERT、UPDATE或DELETE。确保不会同时对同一资源q行多重更新
  • 意向 ?Microsoft SQL Server 数据库引擎获取低U别的锁Ӟ它还在包含更低U别对象的对象上攄意向?例如Q?当锁定行或烦引键范围Ӟ数据库引擎将在包含行或键的页上放|意向锁。当锁定|Q数据库引擎在包含늚更高U别的对象上攄意向锁?
    意向锁的cd为:意向׃nQISQ、意向排它(IXQ以及意向排它共享(SIXQ?
  • 架构 在执行依赖于表架构的操作时用。架构锁的类型ؓQ架构修改(Sch-MQ和架构E_QSch-SQ?
  • 大容量更斎ͼBUQ?向表中大定w复制数据q指定了TABLOCK提示时?



?SQL Server 中锁的设|?/strong>
1 处理死锁和设|死锁优先
死锁是多个用户甌不同锁,׃甌者均拥有一部分锁权而又{待其他用户拥有的部分封锁而引L无休止的{待
可以使用SET DEADLOCK_PRIORITY控制在发生死锁情冉|会话的反应方式?
Syntax:
SET DEADLOCK_PRIORITY { LOW | NORMAL}
其中LOW说明该进E会话的优先U较低,在出现死锁时Q可以首先中断该q程的事务?
2 处理时和设|锁时持箋旉?
@@LOCK_TIMEOUT q回当前会话的当前锁时讄Q单位ؓ毫秒
SET LOCK_TIMEOUT 讄允许应用E序讄语句{待d资源的最长时间。当语句{待的时间大?LOCK_TIMEOUT 讄Ӟpȝ自动取消阻塞的语句Qƈl应用程序返?已超q了锁请求超时时D??1222 号错误信?
CZ
1Q将锁超时期限设|ؓ 1,800 毫秒?
SET LOCK_TIMEOUT 1800
2) 配置索引的锁定粒?
可以使用 sp_indexoption pȝ存储q程来设|用于烦引的锁定_度
3Q设|事务隔ȝ?
SET   TRANSACTION   ISOLATION   LEVEL

?查看锁的信息
1 执行 EXEC SP_LOCK 报告有关锁的信息
2 查询分析器中按Ctrl+2可以看到锁的信息

六、奇怪的sql语句
Java代码 复制代码
  1. begin tran   
  2. update titles set title_ididQtitle_id  where 1Q?/font>2  
  3. if (selectavg(price)fromtitles)>$15  
  4. begin   
  5. update titles set priceQprice*1.10  
  6. where price<(select avg(price)from titles)   
  7. end   
  8. commit tran  


update titles set title_ididQtitle_id  where 1Q?Q这个条件是永远也不会成立的Q如此写的含义是什么呢Q?
q里的where子句看v来很奇怪,管计算出的l果Lfalse。当优化器处理此查询Ӟ因ؓ它找不到M有效的SARGQ它的查询规划就会强制用一个独占锁定来q行表扫描。此事务执行Ӟwhere子句立即得到一个false|于是不会执行实际上的扫描Q但此进E仍得到了一个独占的表锁定?
因ؓ此进E现在已有一个独占的表锁Q所以可以保证没有其他事务会修改M数据行,能进行重复读Q且避免了由于holdlock所引v的潜在性死锁?
但是Q在使用表锁定来可能地减少死锁的同Ӟ也增加了对表锁定的争用。因此,在实现这U方法之前,你需要权衡一下:避免死锁是否比允许ƈ发地对表q行讉K更重要?
所以,在这个事务中Q没有其他进E修改表中Q何行的price?

?如何避免死锁
1 使用事务Ӟ量~短事务的逻辑处理q程Q及早提交或回滚事务Q?
2 讄死锁时参数为合理范_如:3分钟-10分种Q超q时_自动攑ּ本次操作Q避免进E悬挂;
3 所有的SP都要有错误处理(通过@errorQ?
4 一般不要修?span class="hilite1">SQL SERVER事务的默认别。不推荐加锁
5 优化E序Q检查ƈ避免死锁现象出现Q?
1Q合理安排表讉K序
2Q在事务中尽量避免用户干预,量使一个事务处理的d些?
3Q采用脏L术。脏ȝ于不对被讉K的表加锁Q而避免了锁冲H。在客户?服务器应用环境中Q有些事务往往不允许读脏数据,但在特定的条件下Q我们可以用脏读?
4Q数据访问时域离散法。数据访问时域离散法是指在客h/服务器结构中Q采取各U控制手D|制对数据库或数据库中的对象访问时间段。主要通过以下方式实现: 合理安排后台事务的执行时_采用工作对后台事务q行l一理。工作流在管理Q务时Q一斚w限制同一cMQ务的U程敎ͼ往往限制?个)Q防止资源过多占? 另一斚w合理安排不同d执行时序、时_量避免多个后台d同时执行Q另外,避免在前C易高峰时间运行后CQ?
5Q数据存储空间离散法。数据存储空间离散法是指采取各种手段Q将逻辑上在一个表中的数据分散到若q离散的I间上去Q以便改善对表的讉K性能。主要通过以下Ҏ实现: W一Q将大表按行或列分解q小? W二Q按不同的用L分解?
6Q用尽可能低的隔离性别。隔L别是指ؓ保证数据库数据的完整性和一致性而多用户事务隔ȝE度Q?span class="hilite1">SQL92定义?U隔L别:未提交读、提交读、可重复d可串行。如果选择q高的隔L别,如可串行Q虽然系l可以因实现更好隔离性而更大程度上保证数据的完整性和一致性,但各事务间冲H而死锁的Z大大增加Q大大媄响了pȝ性能?
7Q用Bound Connections。Bound connections 允许两个或多个事务连接共享事务和锁,而且M一个事务连接要甌锁如同另外一个事务要甌锁一P因此可以允许q些事务׃n数据而不会有加锁的冲H?
8Q考虑使用乐观锁定或事务首先获得一个独占锁定?nbsp;

八如何对行?表、数据库加锁
1 如何锁一个表的某一?
Java代码 复制代码
  1. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED   
  2. SELECT * FROM table1 ROWLOCK WHERE A = 'a1'  

2 锁定数据库的一个表
select col1 from ?(tablockx) where 1=1 ;
加锁后其它h不可操作Q直到加锁用戯锁,用commit或rollback解锁
3.实例

Java代码 复制代码
  1. create table table1(A varchar(50)  not  null, B varchar(50) ,C varchar(50));   
  2. create table table2(D varchar(50),E varchar(50))   
  3. insert table1 (A,B,C) values(‘a1’,’b1’,’c1’);   
  4. insert table1 (A,B,C) values(‘a2’,’b2’,’c2’);   
  5. insert table1 (A,B,C) values(‘a3’,’b3’,’c3’);   
  6. insert table2 (D,E) values(‘d1’,’e1’);   
  7. insert table2 (D,E) values(‘d2’,’e2’);  

1Q排它锁
Java代码 复制代码
  1. -- A事务先更新table1表,在更新时Q对其他事务q行排他   
  2. begin tran   
  3. update table1 set A='aa' where B='b2'Q?  
  4. waitfor delay '00:00:30'Q?nbsp;--{待30U?  
  5. commit tran   
  6. -- A事务先更新table2?  
  7. begin tran   
  8. select * from table1 where B='b2';   
  9. commit tran  
若同时执行上qC个事务,则select查询必须{待update执行完毕才能执行卌{待30U?
2Q共享锁
Java代码 复制代码
  1. -- A事务先查询table1表,在查询时Q加׃n锁,防止其他事务对该表进行修Ҏ?  
  2. begin tran   
  3. select * from table1 holdlock where B='b2' ;   
  4.  -holdlockZؓ加锁   
  5. waitfor delay '00:00:30';--{待30U?  
  6. commit tran   
  7. -- A事务先查询table1表,后更改table1?  
  8. begin tran   
  9. select A,C from table1 where B='b2';   
  10. update table1 set A='aa' where B='b2';   
  11. commit tran  
若ƈ发执行上qC个事务,则B事务中的select查询可以执行,而update必须{待W一个事务释攑օ享锁转ؓ排它锁后才能执行卌{待30U?
3Q死?
Java代码 复制代码
  1. -- A事务先更新table1表,然后延时30U,再更新table2表;   
  2. begin tran   
  3. update table1 set A='aa' where B='b2';   
  4. --q将?nbsp;Table1 中生成排他行锁,直到事务完成后才会释放该锁?  
  5. waitfor delay '00:00:30';   
  6. --q入延时   
  7. update table2 set D='d5' where E='e1' ;   
  8. commit tran   
  9. -- B事务先更新table2表,然后延时10U,再更新table1表;   
  10. begin tran   
  11. update table2 set D='d5' where E='e1';   
  12. --q将?nbsp;Table2 中生成排他行锁,直到事务完成后才会释放该?  
  13. waitfor delay '00:00:10'  
  14. --q入延时   
  15. update table1 set A='aa' where B='b2' ;   
  16. commit tran  
若ƈ发执行上qC个事务,A,B两事务都要等待对斚w放排他锁Q这样便形成了死锁?

九?span class="hilite1">sqlserver提供的表U锁
sqlserver所指定的表U锁定提C有如下几种
1Q?HOLDLOCK: 在该表上保持׃n锁,直到整个事务l束Q而不是在语句执行完立即释放所d的锁?nbsp;
2Q?NOLOCKQ不d׃n锁和排它锁,当这个选项生效后,可能d未提交读的数据或“脏数?#8221;Q这个选项仅仅应用于SELECT语句?nbsp; 
3Q?PAGLOCKQ指定添加页锁(否则通常可能d表锁Q?
4Q?READCOMMITTED用与q行在提交读隔离U别的事务相同的锁语义执行扫描。默认情况下Q?span class="hilite1">SQL Server 2000 在此隔离U别上操作?
5Q?READPAST: 跌已经加锁的数据行Q这个选项事务d数据时蟩q那些已l被其他事务锁定的数据行Q而不是阻塞直到其他事务释NQREADPAST仅仅应用于READ COMMITTED隔离性别下事务操作中的SELECT语句操作
6Q?READUNCOMMITTEDQ等同于NOLOCK?nbsp;  
7Q?REPEATABLEREADQ设|事务ؓ可重复读隔离性别?nbsp;
8Q?ROWLOCKQ用行U锁Q而不使用_度更粗的页U锁和表U锁?
9Q?SERIALIZABLEQ用与运行在可串行读隔离U别的事务相同的锁语义执行扫描。等同于 HOLDLOCK?
  10Q?TABLOCKQ指定用表U锁Q而不是用行U或面U的锁,SQL Server在该语句执行完后释放q个锁,而如果同时指定了HOLDLOCKQ该锁一直保持到q个事务l束?
11Q?TABLOCKXQ指定在表上使用排它锁,q个锁可以阻止其他事务读或更新这个表的数据,直到q个语句或整个事务结束?
12Q?UPDLOCK Q指定在读表中数据时讄更新锁(update lockQ而不是设|共享锁Q该锁一直保持到q个语句或整个事务结束,使用UPDLOCK的作用是允许用户先读取数据(而且不阻塞其他用戯数据Q,q且保证在后来再更新数据Ӟq一D|间内q些数据没有被其他用户修?
SELECT * FROM table WITH (HOLDLOCK) 其他事务可以d表,但不能更新删?
SELECT * FROM table WITH (TABLOCKX) 其他事务不能d?更新和删?

十、应用程序锁

应用E序锁就是客L代码生成的锁Q而不?span class="hilite1">sql server本n生成的锁处理应用E序锁的两个pȝ存储q程
sp_getapplockQ?锁定应用E序资源
sp_releaseapplockQ?为应用程序资源解?

]]>
sqlserver乐观锁与悲观锁实?/title><link>http://www.tkk7.com/tinysun/archive/2010/02/04/311952.html</link><dc:creator>何克?/dc:creator><author>何克?/author><pubDate>Thu, 04 Feb 2010 06:22:00 GMT</pubDate><guid>http://www.tkk7.com/tinysun/archive/2010/02/04/311952.html</guid><wfw:comment>http://www.tkk7.com/tinysun/comments/311952.html</wfw:comment><comments>http://www.tkk7.com/tinysun/archive/2010/02/04/311952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tinysun/comments/commentRss/311952.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tinysun/services/trackbacks/311952.html</trackback:ping><description><![CDATA[<p>在实际的多用户ƈ发访问的生环境里边Q我们经常要可能的保持数据的一致性。而其中最典型的例子就是我们从表里边读取数据,查验证后Ҏ据进行修改,然后写回到数据库中。在d和写入的q程中,假如在多用户q发的环境里边,其他用户已经把你要修改的数据q行了修Ҏ非常有可能发生的情况Q这样就造成了数据的不一致性。解册L办法QSQL SERVER提出了乐观锁定和悲观锁定的概念,下边我以一个实例来说明如何使用乐观锁定和悲观锁定来解决q样的问题?</p> <p>/* 建立试?Card,代表一个真实的卡库,供用h?用户要从里边选出一个未使用的卡Q也是F_Flag=0的卡Q给用户注册Q更新F_Name,F_Time,F_Flag字段. 假如出现两个用户同时更新一张卡的情况,是不能容忍的Q也是我们所说的数据不一致行?/</p> <p>create table Card(F_CardNO varchar(20),F_Name varchar(20),F_Flag bit,F_Time datetime)<br /> Go<br /> insert Card(F_CardNo,F_Flag) select '1111-1111',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1112',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1113',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1114',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1115',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1116',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1117',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1118',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1119',0<br /> insert Card(F_CardNo,F_Flag) select '1111-1110',0<br /> Go</p> <p>-- 下边是我们经怋用的更新Ҏ如下:</p> <p>declare @CardNo varchar(20)<br /> Begin Tran</p> <p>-- 选择一张未使用的卡<br /> select top 1 @CardNo=F_CardNo<br /> from Card where F_Flag=0</p> <p>-- 延迟50U,模拟q发讉K.<br /> waitfor delay '000:00:50'</p> <p>-- 把刚才选择出来的卡q行注册.</p> <p>update Card<br /> set F_Name=user,<br /> F_Time=getdate(),<br /> F_Flag=1<br /> where F_CardNo=@CardNo</p> <p>commit</p> <p>问题:假如我们在同一H口执行同一D代码,但是L了waitfor delay子句.两边执行完毕?我们发现管执行了两ơ注册,但是只注册了一张卡Q也是两个人注册了同一张卡. </p> <p>悲观锁定解决Ҏ</p> <p>-- 我们只要对上边的代码做微的改变可以实现悲观的锁定.</p> <p>declare @CardNo varchar(20)<br /> Begin Tran</p> <p>-- 选择一张未使用的卡<br /> select top 1 @CardNo=F_CardNo<br /> from Card with (UPDLOCK) where F_Flag=0</p> <p>-- 延迟50U,模拟q发讉K.<br /> waitfor delay '000:00:50'</p> <p>-- 把刚才选择出来的卡q行注册.</p> <p>update Card<br /> set F_Name=user,<br /> F_Time=getdate(),<br /> F_Flag=1<br /> where F_CardNo=@CardNo</p> <p>commit</p> <p>注重其中的区别了?with(updlock),是的,我们在查询的时候用了with (UPDLOCK)选项,在查询记录的时候我们就对记录加上了更新?表示我们卛_Ҏ记录q行更新.注重更新锁和׃n锁是不冲H的,也就是其他用戯可以查询此表的内?但是和更新锁和排它锁是冲H的.所以其他的更新用户׃d.假如我们在另外一个窗口执行此代码,同样不加waifor delay子句.两边执行完毕?我们发现成功的注册了两张?可能我们已经发现了悲观锁定的~点:当一个用戯行更新的事务的时?其他更新用户必须排队{待,即那个用户更新的不是同一条记? </p> <p>乐观锁定解决Ҏ</p> <p>-- 首先我们在Card表里边加上一列F_TimeStamp ?该列是varbinary(8)cd.但是在更新的时候这个g自动增长.</p> <p>alter table Card add F_TimeStamp timestamp not null</p> <p>-- 悲观锁定<br /> declare @CardNo varchar(20)<br /> declare @timestamp varbinary(8)<br /> declare @rowcount int</p> <p>Begin Tran</p> <p>-- 取得卡号和原始的旉戛_?br /> select top 1 @CardNo=F_CardNo,<br /> @timestamp=F_TimeStamp<br /> from Card<br /> where F_Flag=0</p> <p>-- 延迟50U,模拟q发讉K.<br /> waitfor delay '000:00:50'</p> <p>-- 注册?但是要比较时间戳是否发生了变?假如没有发生变化.更新成功.假如发生变化,更新p|.</p> <p>update Card<br /> set F_Name=user,<br /> F_Time=getdate(),<br /> F_Flag=1<br /> where F_CardNo=@CardNo and F_TimeStamp=@timestamp<br /> set @rowcount=@@rowcount<br /> if @rowcount=1<br /> begin<br /> print '更新成功!'<br /> commit<br /> end<br /> else if @rowcount=0<br /> begin<br /> if exists(select 1 from Card where F_CardNo=@CardNo)<br /> begin<br /> print '此卡已经被另外一个用h册!'<br /> rollback tran<br /> end<br /> else<br /> begin<br /> print 'q不存在此卡!'<br /> rollback tran<br /> end<br /> end</p> <p>在另外一个窗口里Ҏ行没有waitfor的代?注册成功?q回原来的窗?我们׃发现到时间后它显C的提示是此卡以被另外一个用h册的提示.很明?q样我们也可以避免两个用户同时注册一张卡的现象的出现.同时,使用q种Ҏ的另外一个好处是没有使用更新?q样增加的系l的q发处理能力.</p> <p>上边我具体介l了乐观锁定和悲观锁定的使用Ҏ,在实际生产环境里?假如q发量不?我们完全可以使用悲观锁定的方?因ؓq种Ҏ使用h非常方便和简?但是假如pȝ的ƈ发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方?</p> <p><br /> 本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/gudenren/archive/2009/07/31/4397291.aspx</p> <img src ="http://www.tkk7.com/tinysun/aggbug/311952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tinysun/" target="_blank">何克?/a> 2010-02-04 14:22 <a href="http://www.tkk7.com/tinysun/archive/2010/02/04/311952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>锁_数据库原?/title><link>http://www.tkk7.com/tinysun/archive/2010/02/04/311949.html</link><dc:creator>何克?/dc:creator><author>何克?/author><pubDate>Thu, 04 Feb 2010 06:16:00 GMT</pubDate><guid>http://www.tkk7.com/tinysun/archive/2010/02/04/311949.html</guid><wfw:comment>http://www.tkk7.com/tinysun/comments/311949.html</wfw:comment><comments>http://www.tkk7.com/tinysun/archive/2010/02/04/311949.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tinysun/comments/commentRss/311949.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tinysun/services/trackbacks/311949.html</trackback:ping><description><![CDATA[<li><span><span>数据?-?  </span></span></li> <li><span id="79999xv" class="number">1</span><span>#定义   </span></span></li> <li><span>数据库和操作pȝ一P是一个多用户使用的共享资源。当多个用户q发地存取数据时Q在数据库中׃产生多个事务同时存取同一数据的情c若对ƈ发操作不加控制就可能会读取和存储不正的数据Q破坏数据库的一致性?  </span></li> <li><span>    加锁是实现数据库q发控制的一个非帔R要的技术。在实际应用中经怼遇到的与锁相关的异常情况Q当两个事务需要一l有冲突的锁Q而不能将事务l箋下去的话Q就会出现死锁,严重影响应用的正常执行?  </span></li> <li><span>    在数据库中有两种基本的锁cdQ排它锁QExclusive LocksQ即X锁)和共享锁QShare LocksQ即S锁)?  </span></li> <li><span>@当数据对象被加上排它锁时Q其他的事务不能对它d和修攏V?  </span></li> <li><span>@加了׃n锁的数据对象可以被其他事务读取,但不能修攏V?  </span></li> <li><span>数据库利用这两种基本的锁cd来对数据库的事务q行q发控制?  </span></li> <li><span>  </span></li> <li><span id="ttl9bx9" class="number">2</span><span>#悲观锁,正如其名Q它指的是对数据被外界(包括本系l当前的其他事务Q以及来自外部系l的事务处理Q修Ҏ保守态度Q因此,在整个数据处理过E中Q将数据处于锁定状态。悲观锁的实玎ͼ往往依靠数据库提供的锁机Ӟ也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则Q即使在本系l中实现了加锁机Ӟ也无法保证外部系l不会修Ҏ据)?  </span></span></li> <li><span>一个典型的倚赖数据库的悲观锁调用:   </span></li> <li><span>select * from account where name=”Erica” </span><span id="vd7ptjr" class="keyword">for</span><span> update   </span></span></li> <li><span>q条 sql 语句锁定?nbsp;account 表中所有符合检索条Ӟname=“Erica”Q的记录。本ơ事务提交之前(事务提交时会释放事务q程中的锁)Q外界无法修改这些记录?  </span></li> <li><span>悲观锁大多数情况下依靠数据库的锁机制实现Q以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销Q特别是寚w事务而言Q这L开销往往无法承受。如一个金融系l,当某个操作员d用户的数据,q在d的用h据的基础上进行修ҎQ如更改用户帐户余额Q,如果采用悲观锁机Ӟ也就意味着整个操作q程中(从操作员d数据、开始修改直x交修改结果的全过E,甚至q包括操作员中途去煮咖啡的旉Q,数据库记录始l处于加锁状态,可以惌Q如果面对几 百上千个q发Q这L情况导致怎样的后果?  </span></li> <li><span>  </span></li> <li><span>  </span></li> <li><span id="h99xjhv" class="number">3</span><span>#乐观锁机制在一定程度上解决了这个问题。乐观锁Q大多是Z数据版本QVersionQ记录机制实现。何谓数据版本?即ؓ数据增加一个版本标识,在基于数据库表的版本解决Ҏ中,一般是通过为数据库表增加一?nbsp;“version” 字段来实现读取出数据Ӟ此版本号一同读出,之后更新ӞҎ版本号加一。此Ӟ提交数据的版本数据与数据库表对应记录的当前版本信息q行比对Q如果提交的数据版本号大于数据库表当前版本号Q则予以更新Q否则认为是q期数据?  </span></span></li> <li><span>对于上面修改用户帐户信息的例子而言Q假设数据库中帐户信息表中有一?nbsp;version 字段Q当前gؓ </span><span id="zr79f9p" class="number">1</span><span> Q而当前帐户余额字D( balance Qؓ $</span><span id="ztvf99p" class="number">100</span><span> ?  </span></span></li> <li><span id="79vfhfv" class="number">1</span><span> 操作?nbsp;A 此时其dQ?nbsp;version=</span><span id="bb7n999" class="number">1</span><span> Q,q从其帐户余额中扣除 $</span><span id="d799vj9" class="number">50</span><span>Q?nbsp;$</span><span id="phzd7jp" class="number">100</span><span>-$</span><span id="7d9hlj9" class="number">50</span><span> Q?  </span></span></li> <li><span id="hlxrt79" class="number">2</span><span> 在操作员 A 操作的过E中Q操作员 B 也读入此用户信息Q?nbsp;version=</span><span id="rjlnhf9" class="number">1</span><span> Q,q从其帐户余额中扣除 $</span><span id="pxtv79f" class="number">20</span><span> Q?nbsp;$</span><span id="rrvx79p" class="number">100</span><span>-$</span><span id="pdf9hhr" class="number">20</span><span> Q?  </span></span></li> <li><span id="xnhjltb" class="number">3</span><span> 操作?nbsp;A 完成了修改工作,数据版本号加一Q?nbsp;version=</span><span id="79n9xd9" class="number">2</span><span> Q,q同帐户扣除后余额( balance=$</span><span id="7xzb99h" class="number">50</span><span> Q,提交x据库更新Q此时由于提交数据版本大于数据库记录当前版本Q数据被更新Q数据库记录 version 更新?nbsp;</span><span id="9j9vpfb" class="number">2</span><span> ?  </span></span></li> <li><span id="f9vv9nl" class="number">4</span><span> 操作?nbsp;B 完成了操作,也将版本号加一Q?nbsp;version=</span><span id="1t97x9h" class="number">2</span><span> Q试囑֐数据库提交数据( balance=$</span><span id="1fz79p9" class="number">80</span><span> Q,但此时比Ҏ据库记录版本时发玎ͼ操作?nbsp;B 提交的数据版本号?nbsp;</span><span id="jnp9xfl" class="number">2</span><span> Q数据库记录当前版本也ؓ </span><span id="9tnnr99" class="number">2</span><span> Q不满 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁{略Q因此,操作?nbsp;B 的提交被驛_。这P避免了操作?nbsp;B 用基于version=</span><span id="brf99tz" class="number">1</span><span>的旧数据修改的结果覆盖操作员 A 的操作结果的可能?  </span></span></li> <li><span>  </span></li> <li><span>  </span></li> <li><span id="jlpr9nn" class="number">4</span><span>#死锁   </span></span></li> <li><span>死锁的第一U情?  </span></li> <li><span>一个用户A 讉K表A(锁住了表A),然后又访问表BQ另一个用户B 讉K表B(锁住了表B)Q然后企图访问表AQ这时用户A׃用户B已经锁住表BQ它必须{待用户B释放表B才能l箋Q同L户B要等用户A释放表A才能l箋Q这死锁就产生了?  </span></li> <li><span>解决ҎQ?  </span></li> <li><span>q种死锁比较常见Q是׃E序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔l分析程序的逻辑Q对于数据库的多表操作时Q尽量按照相同的序q行处理Q尽量避免同旉定两个资源,如操作A和B两张表时QL按先A后B的顺序处理, 必须同时锁定两个资源Ӟ要保证在M时刻都应该按照相同的序来锁定资源?  </span></li> <li><span>  </span></li> <li><span>死锁的第二种情况   </span></li> <li><span>用户A查询一条纪录,然后修改该条U录Q这时用户B修改该条U录Q这时用户A的事务里锁的性质由查询的׃n锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必ȝA释放掉共享锁Q而A׃B的独占锁而无法上升的独占锁也׃可能释放׃n锁,于是出现了死锁。这U死锁比较隐蔽,但在E大点的目中经常发生。如在某目中,面上的按钮点击后,没有使按钮立d效,使得用户会多ơ快速点d一按钮Q这样同一D代码对数据库同一条记录进行多ơ操作,很容易就出现q种死锁的情c?  </span></li> <li><span>解决ҎQ?  </span></li> <li><span id="rn79zxl" class="number">1</span><span>、对于按钮等控gQ点d使其立刻失效Q不让用户重复点击,避免对同时对同一条记录操作?  </span></span></li> <li><span id="f999ppl" class="number">2</span><span>、用乐观锁q行控制?  </span></span></li> <li><span id="997xz9j" class="number">3</span><span>、用悲观锁q行控制?  </span></span></li> <li><span>  </span></li> <li><span>死锁的第三种情况   </span></li> <li><span>如果在事务中执行了一条不满条g的update语句Q则执行全表扫描Q把行锁上升ؓ表锁,多个q样的事务执行后Q就很容易生死锁和d。类似的情况q有当表中的数据量非常庞大而烦引徏的过或不合适的时候,使得l常发生全表扫描Q最l应用系l会来慢Q最l发生阻塞或死锁?  </span></li> <li><span>解决ҎQ?  </span></li> <li><span>SQL语句中不要用太复杂的关联多表的查询Q?#8220;执行计划”对SQL语句q行分析Q对于有全表扫描的SQL语句Q徏立相应的索引q行优化?nbsp;  </span></li> <img src ="http://www.tkk7.com/tinysun/aggbug/311949.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tinysun/" target="_blank">何克?/a> 2010-02-04 14:16 <a href="http://www.tkk7.com/tinysun/archive/2010/02/04/311949.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HASH JOIN ,MERGE JOIN ,NESTED LOOPhttp://www.tkk7.com/tinysun/archive/2010/02/01/311508.html何克?/dc:creator>何克?/author>Mon, 01 Feb 2010 07:04:00 GMThttp://www.tkk7.com/tinysun/archive/2010/02/01/311508.htmlhttp://www.tkk7.com/tinysun/comments/311508.htmlhttp://www.tkk7.com/tinysun/archive/2010/02/01/311508.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/311508.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/311508.html
对于Oracle的一些基本知识要加强学习Q我从网上抄了三个h对这个题目的见解下来Q供已参考?/font>
 
NESTED LOOP:

对于被连接的数据子集较小的情况,嵌套循环q接是个较好的选择。在嵌套循环中,?br /> 表被外表驱动Q外表返回的每一行都要在内表中检索找C它匹配的行,因此整个查询q回
的结果集不能太大Q大? 万不适合Q,要把q回子集较小表的作ؓ外表QCBO 默认外表?br /> 驱动表)Q而且在内表的q接字段上一定要有烦引。当然也可以用ORDERED 提示来改变CBO
默认的驱动表Q用USE_NL(table_name1 table_name2)可是强制CBO 执行嵌套循环q接?br />
HASH JOIN :

散列q接是CBO 做大数据集连接时的常用方式,优化器用两个表中较的表(或数?br /> 源)利用q接键在内存中徏立散列表Q然后扫描较大的表ƈ探测散列表,扑և与散列表匚w
的行?br /> q种方式适用于较的表完全可以放于内存中的情况,q样L本就是访问两个表的成
本之和。但是在表很大的情况下ƈ不能完全攑օ内存Q这时优化器会将它分割成若干不同?br /> 分区Q不能放入内存的部分把该分区写入磁盘的临时D,此时要有较大的时段从而尽?br /> 提高I/O 的性能?br /> 也可以用USE_HASH(table_name1 table_name2)提示来强制用散列连接。如果用散
列连接HASH_AREA_SIZE 初始化参数必够的大,如果?iQOracle使用SQL工作?br /> 自动理Q设|WORKAREA_SIZE_POLICY 为AUTOQ然后调整PGA_AGGREGATE_TARGET 卛_?br />
排序合ƈq接

通常情况下散列连接的效果都比排序合ƈq接要好Q然而如果行源已l被排过序,在执
行排序合q连接时不需要再排序了,q时排序合ƈq接的性能会优于散列连接。可以?br /> USE_MERGE(table_name1 table_name2)来强制用排序合q连?/div>
 


 
Nested loop join:

步骤Q确定一个驱动表(outer table)Q另一个表为inner tableQ驱动表中的每一行与inner表中的相应记录JOIN。类g个嵌套的循环。适用于驱动表的记录集比较(<10000Q而且inner表需要有有效的访问方法(IndexQ。需要注意的是:JOIN的顺序很重要Q驱动表的记录集一定要,q回l果集的响应旉是最快的?br />
cost = outer access cost + (inner access cost * outer cardinality)


| 2 | NESTED LOOPS | | 3 | 141 | 7 (15)|
| 3 | TABLE ACCESS FULL | EMPLOYEES | 3 | 60 | 4 (25)|
| 4 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 513 | 2 (50)|
| 5 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | |


EMPLOYEES为outer table, JOBS为inner table.

Hash join

步骤Q将两个表中较小的一个在内存中构造一个HASH表(对JOIN KEYQ,扫描另一个表Q同样对JOIN KEYq行HASH后探是否可以JOIN。适用于记录集比较大的情况。需要注意的是:如果HASH表太大,无法一ơ构造在内存中,则分成若q个partitionQ写入磁盘的temporary segmentQ则会多一个写的代P会降低效率?br />
cost = (outer access cost * # of hash partitions) + inner access cost
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 665 | 13300 | 8 (25)|
| 1 | HASH JOIN | | 665 | 13300 | 8 (25)|
| 2 | TABLE ACCESS FULL | ORDERS | 105 | 840 | 4 (25)|
| 3 | TABLE ACCESS FULL | ORDER_ITEMS | 665 | 7980 | 4 (25)|
--------------------------------------------------------------------------


ORDERS为HASH TABLEQORDER_ITEMS扫描

Sort merge join

步骤Q将两个表排序,然后两个表合ƈ。通常情况下,只有在以下情况发生时Q才会用此UJOIN方式Q?br />
1.RBO模式

2.不等价关?>,<,>=,<=,<>)

3.HASH_JOIN_ENABLED=false

4.数据源已排序

cost = (outer access cost * # of hash partitions) + inner access cost
 


 
转蝲biti的一D话:  
   
  举例Q表q接q回一条记? 
  存在两个表,一?  10条记?  Q一?000万条记录  
   
  ?表都存在q接字段索引Q若以小表ؓ驱动表,? 
  代hQ?   
  10*   (通过索引在大表查询一条记录的代h)    
   
  若以大表为驱动表Q? 
   
  1000?  *   (通过索引在小表中查询一条记录的代h)  
   
  通过索引获取一条记录,10rows的表Q代价通常?  3   blocks    
  索引2块,表一? 
   
  而如果是1000万的表,索引可能辑ֈ4块表一? 
  q样一来参考上面的计算Q你说哪个更好?很显Ӟ  
   
  表查询参? 
   
  SQL>   create   table   test   as   select   *   from   all_objects   where   rownum   <   11;  
   
  Table   created.  
   
  SQL>   create   index   test_index   on   test(object_id);  
   
  Index   created.  
   
  SQL>   select   object_id   from   test;  
   
  OBJECT_ID  
  ----------  
  18159  
  7781  
  4841  
  19891  
  22549  
  17099  
  17712  
  4287  
  10107  
  19135  
   
  10   rows   selected.  
   
   
  Execution   Plan  
  ----------------------------------------------------------  
  0   SELECT   STATEMENT   Optimizer=CHOOSE  
  1   0   TABLE   ACCESS   (FULL)   OF   'TEST'  
   
   
   
   
  Statistics  
  ----------------------------------------------------------  
  0   recursive   calls  
  12   db   block   gets  
  6   consistent   gets  
  0   physical   reads  
  0   redo   size  
  736   bytes   sent   via   SQL*Net   to   client  
  425   bytes   received   via   SQL*Net   from   client  
  2   SQL*Net   roundtrips   to/from   client  
  0   sorts   (memory)  
  0   sorts   (disk)  
  10   rows   processed  
   
  SQL>   select   *   from   test   where   object_id   =   4287;  
   
  OWNER   OBJECT_NAME  
  ------------------------------   ------------------------------  
  SUBOBJECT_NAME   OBJECT_ID   DATA_OBJECT_ID   OBJECT_TYPE  
  ------------------------------   ----------   --------------   ------------------  
  CREATED   LAST_DDL_   TIMESTAMP   STATUS   T   G   S  
  ---------   ---------   -------------------   -------   -   -   -  
  SYS   /1033c8a_SqlTypeWithMethods  
  4287   JAVA   CLASS  
  14-NOV-00   03-JUL-03   2003-07-03:11:18:19   INVALID   N   N   N  
   
   
   
  Execution   Plan  
  ----------------------------------------------------------  
  0   SELECT   STATEMENT   Optimizer=CHOOSE  
  1   0   TABLE   ACCESS   (BY   INDEX   ROWID)   OF   'TEST'  
  2   1   INDEX   (RANGE   SCAN)   OF   'TEST_INDEX'   (NON-UNIQUE)  
   
   
   
   
  Statistics  
  ----------------------------------------------------------  
  0   recursive   calls  
  0   db   block   gets  
  3   consistent   gets  
  0   physical   reads  
  0   redo   size  
  1157   bytes   sent   via   SQL*Net   to   client  
  425   bytes   received   via   SQL*Net   from   client  
  2   SQL*Net   roundtrips   to/from   client  
  0   sorts   (memory)  
  0   sorts   (disk)  
  1   rows   processed  

 TAG 表联?/a> oracle join

]]>
什么是持久化和对象关系映射ORM技?http://www.tkk7.com/tinysun/archive/2009/04/23/267162.html何克?/dc:creator>何克?/author>Thu, 23 Apr 2009 07:34:00 GMThttp://www.tkk7.com/tinysun/archive/2009/04/23/267162.htmlhttp://www.tkk7.com/tinysun/comments/267162.htmlhttp://www.tkk7.com/tinysun/archive/2009/04/23/267162.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/267162.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/267162.html何谓“持久?#8221;
持久QPersistenceQ,x数据Q如内存中的对象Q保存到可永久保存的存储讑֤中(如磁盘)。持久化的主要应用是内存中的数据存储在关系型的数据库中Q当然也可以存储在磁盘文件中、XML数据文g中等{?

何谓“持久?#8221;
持久层(Persistence LayerQ,即专注于实现数据持久化应用领域的某个特定pȝ的一个逻辑层面Q将数据使用者和数据实体相关联?/p>

何谓“对象数据映射QORMQ?#8221;
ORM-Object/Relational MapperQ即“对象-关系型数据映组?#8221;。对于O/RQ即 ObjectQ对象)?RelationalQ关pd数据Q,表示必须同时使用面向对象和关pd数据q行开发?/p>

备注Q徏模领域中?ORM ?Object/Role ModelingQ对象角色徏模)。另外这里是“O/R Mapper”而非“O/R Mapping”。相ҎԌO/R Mapping 描述的是一U设计思想或者实现机Ӟ?O/R Mapper指以O/R原理设计的持久化框架QFrameworkQ,包括 O/R机制q有 SQL自生成,事务处理QCache理{?/p>


除了 ORM 技术,q有以下几种持久化技?/p>

d域对象模?br /> 它是在实C装了关pL据模型和数据讉Kl节的一UŞ式。在 J2EE 架构中,EJB lg分ؓ会话 EJB 和实?EJB。会?EJB 通常实现业务逻辑Q而实?EJB 表示业务实体。实?EJB 又分ZU:?EJB 本n理持久化,?BMPQBean-Managed PersistenceQ;?EJB 容器理持久化,?CMPQContainer-Managed PersistenceQ。BM P是d域对象模式的一个例子,BMP 表示由实?EJB 自n理数据讉Kl节?br /> d域对象本w位于业务逻辑层,因此采用d域对象模式时Q整个应用仍然是三层应用l构Qƈ没有从业务逻辑层分d独立的持久化层?/p>

JDO 模式
Java Data ObjectsQJDOQ是 SUN 公司制定的描q对象持久化语义的标准API。严格的_JDO q不是对?关系映射接口Q因为它支持把对象持久化CQ意一U存储系l中Q包?关系数据库、面向对象的数据库、基?XML 的数据库Q以及其他专有存储系l。由于关pL据库是目前最行的存储系l,许多 JDO 的实现都包含了对?关系映射服务?/p>

CMP 模式
?J2EE 架构中,CMPQContainer-Managed PersistenceQ表C由 EJB 容器来管理实?EJB 的持久化QEJB 容器装了对?关系的映及数据讉Kl节。CMP ?ORM 的相g处在于,两者都提供对象-关系映射服务Q都把对象持久化的Q务从业务逻辑中分d来。区别在?CMP 负责持久化实?EJB lgQ?ORM 负责持久?POJOQ它是普通的Z Java Bean 形式的实体域对象?/p>

一般把Z Java Bean 形式的实体域对象UCؓ POJOQPlain Old Java ObjectQ,意ؓ又普通又古老的 Java 对象的意思。随着各种 ORM 映射工具的日成熟和行QPOJO有重现光彩,它和Z CMP 的实?EJB 相比Q即单又h很高的可UL性,因此联合使用 ORM 映射工具?POJOQ已l成ZU越来越受欢q的且用来取?CMP 的持久化Ҏ。POJO 的缺点就是无法做q程调用Q不支持分布式计?/p>


Z么要做持久化和ORM设计

在目前的企业应用pȝ设计中,MVCQ即 ModelQ模型)- ViewQ视图)- ControlQ控ӞZ要的pȝ架构模式。MVC 中的 Model 包含了复杂的业务逻辑和数据逻辑Q以及数据存取机Ӟ?JDBC的连接、SQL生成和Statement创徏、还有ResultSetl果集的d{){。将q些复杂的业务逻辑和数据逻辑分离Q以系l的紧耦合关系转化为松耦合关系Q即解耦合Q,是降低系l耦合度迫切要做的Q也是持久化要做的工作。MVC 模式实现了架构上表现层Q即ViewQ和数据处理层(即ModelQ分ȝ解耦合Q而持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。?ORM 作ؓ持久化设计中的最重要也最复杂的技术,也是目前业界热点技术?/p>

单来_按通常的系l设计,使用 JDBC 操作数据库,业务处理逻辑和数据存取逻辑是؜杂在一L?br /> 一般基本都是如下几个步骤:
1、徏立数据库q接Q获?Connection 对象?br /> 2、根据用L输入l装查询 SQL 语句?br /> 3、根?SQL 语句建立 Statement 对象 或?PreparedStatement 对象?br /> 4、用 Connection 对象执行 SQL语句Q获得结果集 ResultSet 对象?br /> 5、然后一条一条读取结果集 ResultSet 对象中的数据?br /> 6、根据读取到的数据,按特定的业务逻辑q行计算?br /> 7、根据计得到的l果再组装更?SQL 语句?br /> 8、再使用 Connection 对象执行更新 SQL 语句Q以更新数据库中的数据?br /> 7、最后依ơ关闭各?Statement 对象?Connection 对象?/p>

׃可看Z码逻辑非常复杂Q这q不包括某条语句执行p|的处理逻辑。其中的业务处理逻辑和数据存取逻辑完全h在一块。而一个完整的pȝ要包含成千上万个q样重复的而又h的处理过E,假如要对其中某些业务逻辑或者一些相兌的业务流E做修改Q要改动的代码量不可想象。另一斚wQ假如要换数据库产品或者运行环境也可能是个不可能完成的d。而用Lq行环境和要求却千差万别Q我们不可能为每一个用h一U运行环境设计一套一Lpȝ?br /> 所以就要将一L处理代码即业务逻辑和可能不一L处理x据存取逻辑分离开来,另一斚wQ关pd数据库中的数据基本都是以一行行的数据进行存取的Q而程序运行却是一个个对象q行处理Q而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC{等Q均是以行集的结果集一条条q行处理的。所以ؓ解决q一困难Q就出现 ORM q一个对象和数据之间映射技术?/p>

举例来说Q比如要完成一个购物打折促销的程序,?ORM 思想如下实玎ͼ引自《深入浅出Hibernate》)Q?br /> 业务逻辑如下Q?br /> public Double calcAmount(String customerid, double amount)
{
    // Ҏ客户ID获得客户记录
    Customer customer = CustomerManager.getCustomer(custmerid);
    // Ҏ客户{获得打折规则
    Promotion promotion = PromotionManager.getPromotion(customer.getLevel());
    // 累积客户L贚wQƈ保存累计l果
    customer.setSumAmount(customer.getSumAmount().add(amount);
    CustomerManager.save(customer);
    // q回打折后的金额
    return amount.multiply(protomtion.getRatio());
}
q样代码非常清CQ而且与数据存取逻辑完全分离。设计业务逻辑代码的时候完全不需要考虑数据库JDBC的那些千一律的操作Q而将它交l?CustomerManager ?PromotionManager 两个cd完成。这是一个简单的 ORM 设计Q实际的 ORM 实现框架比这个要复杂的多?/p>


目前有哪些流行的 ORM 产品
目前众多厂商和开源社区都提供了持久层框架的实玎ͼ常见的有
Apache OJB Q?a >http://db.apache.org/ojb/Q?br /> Cayenne Q?a >http://objectstyle.org/cayenne/Q?br /> Jaxor Q?a >http://jaxor.sourceforge.netQ?br /> Hibernate Q?a >http://www.hibernate.orgQ?br /> iBatis Q?a >http://www.ibatis.comQ?br /> jRelationalFramework Q?a >http://ijf.sourceforge.netQ?br /> mirage Q?a >http://itor.cq2.org/en/oss/mirage/toonQ?br /> SMYLE Q?a >http://www.drjava.de/smyleQ?br /> TopLink Q?a >http://otn.oracle.com/products/ias/toplink/index.htmlQ?br /> 其中 TopLink ?Oracle 的商业品,其他均ؓ开源项目?/p>

其中 Hibernate 的轻量 ORM 模型逐步立了在 Java ORM 架构中领导地位,甚至取代复杂而又J琐?EJB 模型而成Z实上?Java ORM 工业标准。而且其中的许多设计均?J2EE 标准l织吸纳而成为最?EJB 3.0 规范的标准,q也是开源项目媄响工业领域标准的有力见证?/p>
http://www.tkk7.com/fyz210/archive/2007/05/22/119098.html


]]>
ORM技术概念与实例http://www.tkk7.com/tinysun/archive/2009/04/23/267150.html何克?/dc:creator>何克?/author>Thu, 23 Apr 2009 07:02:00 GMThttp://www.tkk7.com/tinysun/archive/2009/04/23/267150.htmlhttp://www.tkk7.com/tinysun/comments/267150.htmlhttp://www.tkk7.com/tinysun/archive/2009/04/23/267150.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/267150.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/267150.htmlObject Relational MappingORMORM本质上就是将数据从一UŞ式{换到另外一UŞ式?q也同时暗示者额外的执行开销Q然而,如果ORM作ؓ一U中间g实现Q则会有很多Z做优化,而这些在手写的持久层q不存在?.

对象关系映射Q?/span>Q简U?/span>Q,是随着面向对象的Y件开发方法发展而生的面向对象的开发方法是当今企业U应用开发环境中的主开发方法,关系数据库是企业U应用环境中怹存放数据的主数据存储系l?/span>面向对象是从软g工程基本原则(如耦合、聚合、封?的基上发展v来的Q而关pL据库则是从数学理论发展而来的,两套理论存在显著的区别。ؓ了解册个不匚w的现?对象关系映射技术应q而生?/span>

让我们从O/R开始。字母Oh?对象"(Object),而R则来自于"关系"(Relational)。几乎所有的E序里面Q都存在对象和关pL据库。在业务逻辑层和用户界面层中Q我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中?/span>

当你开发一个应用程序的时?不用O/R Mapping),你可能会写不数据访问层的代码,用来从数据库保存Q删除,d对象信息Q等{。你在DAL中写了很多的Ҏ来读取对象数据,改变状态对象等{Q务。而这些代码写hL重复的?/span>

u          CRUDAPIu          APIu          mapping metadatau          ORMdirty checking, lazy association fetchingORM,,,.

:

http://www.jeez.com.cn/jbf



]]>
基础知识Q带你了解最常见?3个数据库术语http://www.tkk7.com/tinysun/archive/2009/02/22/256042.html何克?/dc:creator>何克?/author>Sun, 22 Feb 2009 07:56:00 GMThttp://www.tkk7.com/tinysun/archive/2009/02/22/256042.htmlhttp://www.tkk7.com/tinysun/comments/256042.htmlhttp://www.tkk7.com/tinysun/archive/2009/02/22/256042.html#Feedback0http://www.tkk7.com/tinysun/comments/commentRss/256042.htmlhttp://www.tkk7.com/tinysun/services/trackbacks/256042.html
1Q关pL型:用二l表格结构表C实体集Q外键表C实体间联系的数据模型称为关pL型。关pL型是pq个关系模式l成的集合?

2Q关pL式:关系模式实际上就是记录类型。它包括Q模式名Q属性名Q值域名以及模式的主键。关pL式仅是对数据Ҏ的描述?

3Q关pd例:是一个关p,即一张二l表根{?

4Q属性:在关pL型中Q字D늧为属性?

5Q域Q在关系中,每一个属性都有一个取D_UCؓ属性的值域?

6Q元l:在关pMQ记录称为元l?

7Q候选码Q在关系中能唯一标识元组的属性集UCؓ关系模式的候选码?

8Q主码:用户选作元组标识的一个候选码Z码?

9Q外码:某个关系的主码相应的属性在另一关系中出玎ͼ此时该主码在是另一关系的外码,如有两个关系S和SC,其中S#是关pS的主码,相应的属性S#在关pSC中也出现Q此时S#是关系SC的外码?

10Q实体完整性规则:q条规则要求关系中元l在l成ȝ的属性上不能有空倹{如果出现空|那么ȝ值就起不了唯一标识元组的作用?

11Q参照完整性规则:q条规则要求“不引用不存在的实?#8221;。其形式定义如下Q如果属性集K是关pL式R1的主码,K也是关系模式R2的外码,那么R2的关pMQK的取值只允许有两U可能,或者ؓI|或者等于R1关系中某个主码倹{?

q条规则在用时有三点应注意Q?

(1)外码和相应的ȝ可以不同名,只要定义在相同值域上即可?

(2)R1和R2也可以是同一个关pL式,表示了属性之间的联系?

(3)外码值是否允许空应视具体问题而定?

12Q过E性语aQ在~程时必ȝ得结果的操作步骤Q即“q什?#8221;?#8220;怎么q?#8221;。如Pascal和C语言{?

13Q非q程性语aQ编E时只须指出需要什么信息,不必l出具体的操作步骤的语言Q各U关pL询语a均属于非q程性语a?/div>

]]>
վ֩ģ壺 һӰ߿Ƭ| ޹Ʒպ| þþƷŮAVѹۿ| ޵һƵ߹ۿ| avһ | mm1313޾Ʒִִ| AVô뾫Ʒ| պAVһ | һһƬƵ| ھƷ鶹վ91鶹| Ƭһһ߹ۿ| һҹ| Ѿþþþþ| Ƶ| ޻ɫ߹ۿƵ| ĻȫѰ| Ƶۿ| fuli߹ۿ| ½һëƬƵۿi| þ޾Ʒ˳ۺ| ɫҹƵѲ| ޾ƷƵþþ| ѲƵ| ٸ36P| þþþþþþѿ| ߹ۿ޵Ӱ| ƬѹۿĻ| avպavӰ | zzjjzzjjƵȫ| һëƬڲ| Ļ޾Ʒ| òƵƽ̨| aëƬƵѹۿ| ɫƷ88ɫ¶ | ޹Ʒyw | vպv| 㽶þۺӰ| ѹۿɫվ| ޼ɫС˵| ŷһëƬ| ¼ҳ|