亚洲熟妇无码AV,亚洲精品无码久久久影院相关影片,久久亚洲sm情趣捆绑调教http://m.tkk7.com/jiangshachina/category/16091.html同是Java愛(ài)好者,相逢何必曾相識(shí)!<br> &nbsp;&nbsp;&nbsp;a cup of Java, cheers!zh-cnFri, 10 Jul 2015 09:35:43 GMTFri, 10 Jul 2015 09:35:43 GMT60MySQL: MyISAM or InnoDB?(譯)http://m.tkk7.com/jiangshachina/archive/2009/05/31/279288.htmlSha JiangSha JiangSun, 31 May 2009 13:41:00 GMThttp://m.tkk7.com/jiangshachina/archive/2009/05/31/279288.htmlhttp://m.tkk7.com/jiangshachina/comments/279288.htmlhttp://m.tkk7.com/jiangshachina/archive/2009/05/31/279288.html#Feedback2http://m.tkk7.com/jiangshachina/comments/commentRss/279288.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/279288.htmlMySQL: MyISAM or InnoDB?
通過(guò)JavaLobby看到的一篇博文,為選擇MySQL的數(shù)據(jù)表引擎提供了一些意見(jiàn),希望對(duì)大家有幫助。(2009.05.31最后更新)
我這個(gè)可愛(ài)的小哥哥祝可愛(ài)的小朋友們節(jié)日愉快 ^_^

    MyISAM是MySQL的默認(rèn)存儲(chǔ)引擎,但很多人忘記還有其它的選擇。決定使用哪種(哪些)存儲(chǔ)引擎可能需要些技巧,但評(píng)估一下MyISAM是否適合你的需要還是值得的。有一組存儲(chǔ)引擎可用,但我將只關(guān)注MyISAM和InnoDB,因?yàn)樗鼈儽挥玫淖疃唷?br /> 需考慮的問(wèn)題:
    你是否需要外鍵?
    你是否需要事務(wù)?
    你是否需要全文索引?
    你的數(shù)據(jù)訪問(wèn)(查詢)模式是什么?
    你的數(shù)據(jù)集有多大?

    思考上述問(wèn)題將使你走入正確的方向,但有些例外。如果你使用事務(wù)或外鍵,就使用InnoDB。要使用全文索引,你常需選擇MyISAM,因?yàn)樗鼉?nèi)建地支持這一特性;但是,MyISAM難以應(yīng)對(duì)超過(guò)200萬(wàn)的數(shù)據(jù)行。你可以使用Sphinx以使你的InnoDB表能獲取全文索引,但這需要花費(fèi)一些時(shí)間。
    數(shù)據(jù)集的大小是決定你使用哪種引擎的主要因素。由于InnoDB的事務(wù)和崩潰恢復(fù)特性,對(duì)于較大的數(shù)據(jù)集,則傾向于該引擎。然而,恢復(fù)MyISAM數(shù)據(jù)表所花費(fèi)的時(shí)間由數(shù)據(jù)集的大小來(lái)衡量,但恢復(fù)InnoDB所花費(fèi)的時(shí)間由事務(wù)日志的大小來(lái)衡量-而你對(duì)日志有一定的控制力。例如,相較于恢復(fù) InnoDB數(shù)據(jù)表所需要的幾分鐘,你可能需要幾小時(shí)甚至幾天時(shí)間來(lái)恢復(fù)MyISAM數(shù)據(jù)表。
    你讀/寫(xiě)數(shù)據(jù)表的方式可能會(huì)極大地影響你所使用的存儲(chǔ)引擎的性能。在MyISAM數(shù)據(jù)表中執(zhí)行COUNT()會(huì)很快,但對(duì)于InnoDB數(shù)據(jù)表則十分痛苦,最好避免。在InnoDB數(shù)據(jù)表中查找主鍵極其的快,但要注意到,太長(zhǎng)的主鍵會(huì)影響到性能。批量插入在MyISAM數(shù)據(jù)表更快些,但批量更新在 InnoDB中會(huì)較快些--特別是當(dāng)進(jìn)行并發(fā)增加時(shí)。
    那么你應(yīng)該選擇哪種引擎呢?如果你工作在一個(gè)小項(xiàng)目中,那么MyISAM可能正適合你。甚至在較大環(huán)境中使用MyISAM也能獲取很大的成功,但這依具體情況不同而不同。如果你計(jì)劃用于非常大的數(shù)據(jù)集,并且需要事務(wù)或外鍵約束,那就應(yīng)該直接使用InnoDB。但需要記住,相較于MyISAM,InnoDB 數(shù)據(jù)表需要很大的內(nèi)存和存儲(chǔ)空間。將100GB的MyISAM數(shù)據(jù)表轉(zhuǎn)化成InnoDB數(shù)據(jù)表就會(huì)表現(xiàn)得令人吃驚的壞。



Sha Jiang 2009-05-31 21:41 發(fā)表評(píng)論
]]>
深入db4o(譯)http://m.tkk7.com/jiangshachina/archive/2007/12/05/164430.htmlSha JiangSha JiangWed, 05 Dec 2007 04:31:00 GMThttp://m.tkk7.com/jiangshachina/archive/2007/12/05/164430.htmlhttp://m.tkk7.com/jiangshachina/comments/164430.htmlhttp://m.tkk7.com/jiangshachina/archive/2007/12/05/164430.html#Feedback8http://m.tkk7.com/jiangshachina/comments/commentRss/164430.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/164430.html深入db4o
    這是Rick Grehan發(fā)表在TheServerSide上的一篇關(guān)于面向?qū)ο髷?shù)據(jù)庫(kù)--db4o的文章,較全面地介紹了db4o的關(guān)鍵特性,希望對(duì)大家認(rèn)識(shí)db4o能有所幫助。(2007.12.07最后更新)

    db4o-針對(duì)對(duì)象的數(shù)據(jù)庫(kù)-是一個(gè)完全的對(duì)象數(shù)據(jù)庫(kù);它以使對(duì)象在其生命周期中-無(wú)論是在數(shù)據(jù)庫(kù)內(nèi)或是在外-都保持著它們的本性這樣一種方式操縱對(duì)象。不論類的復(fù)雜性如何,對(duì)象的內(nèi)容,結(jié)構(gòu)和關(guān)系都能夠被保存。
    更準(zhǔn)確地說(shuō),db4o是一個(gè)數(shù)據(jù)庫(kù)引擎,你只要將它的一個(gè)jar文件包含到你的數(shù)據(jù)庫(kù)應(yīng)用的類路徑中就可以使用它了(至少對(duì)于Java是這樣的)。所以,db4o運(yùn)行在與你的應(yīng)用程序相同的進(jìn)程空間中,并能被直接地調(diào)用;它不需要類似于在ODBC或JDBC中使用的驅(qū)動(dòng)文件。db4o存在針對(duì)Java,.NET和Mono的版本;它們?cè)诠δ苌隙急舜讼嗟取?事實(shí)上,使用.NET創(chuàng)建的db4o數(shù)據(jù)庫(kù)也能由Java程序訪問(wèn);反之亦然。)
    db4o是開(kāi)源的。可執(zhí)行文件,源代碼和文檔可從http://www.db4objects.com/中下載。廣泛的例子程序,和一個(gè)活躍的用戶社區(qū)一樣,也都可以從這個(gè)站點(diǎn)中找到。
    db4o最引人的特性之一就是它在簡(jiǎn)易性與強(qiáng)大的功能之間的顯著平衡。一方面,它的API是如此地易于掌握和方便使用,即使是初學(xué)者也能在相同的時(shí)間內(nèi)創(chuàng)建一個(gè)功能完備的數(shù)據(jù)庫(kù)對(duì)象。另一方面,這些相同的API也提供了更底層的能夠深入調(diào)用數(shù)據(jù)庫(kù)引擎的方法,以允許核心開(kāi)發(fā)者為了得到適當(dāng)?shù)男阅芏苌钊氲皆撘娴膬?nèi)部中去調(diào)整db4o的工具。
    db4o的特性就是最好的證明--這勝過(guò)只是討論--所以我們將通過(guò)示例這種方法去證明db4o。然而,我們必須牢記本文通篇只是展示了db4o特性中的一部分罷了。感興趣的朋友會(huì)發(fā)現(xiàn)為了知曉該數(shù)據(jù)庫(kù)引擎的全部功能而去查閱db4o的文檔所花的時(shí)間是值得的。

db4o基礎(chǔ)
    讓我們以初學(xué)者使用db4o時(shí)可能會(huì)做的事情開(kāi)始:定義了一些類,然后持久化這些類的對(duì)象。我們所假定的類為同樣也是假定的QA項(xiàng)目做一個(gè)跟蹤測(cè)試的系統(tǒng)。我們的系統(tǒng)由兩個(gè)類組成,首先是TestSuite類:
    public class TestSuite {
        private String name;  // Test Suite name
        private String description;
        private String configuration;
        private char overallScore;
        private ArrayList <TestCase> cases;
        private long dateExec;
        ... <remainder of TestSuite definition> ...
    }
    TestSuite是TestCase對(duì)象的容器,(一個(gè)測(cè)試用例就是一個(gè)可單獨(dú)執(zhí)行的測(cè)試程序--相關(guān)的測(cè)試用例組合成一個(gè)測(cè)試組)。測(cè)試組使用額外的,全局的數(shù)據(jù)成員,每個(gè)數(shù)據(jù)成員的用途也是相對(duì)明顯的:configuration記錄被測(cè)試的指定系統(tǒng);overallScore是對(duì)整個(gè)測(cè)試組一個(gè)簡(jiǎn)要的評(píng)分('P'代表通過(guò),'F'代表失敗,'B'代表被阻塞,等等。);dateExec是一個(gè)毫秒級(jí)的域,標(biāo)識(shí)該測(cè)試組被執(zhí)行時(shí)的日期與時(shí)刻。是ArrayList對(duì)象的cases含有單個(gè)的測(cè)試用例,由TestCase類定義:
    public class TestCase {
        private String name;
        private String comment;
        private char status;
        private long duration;
        private float result;
        ... <remainder of TestCase definition> ...
    }
    每個(gè)測(cè)試用例都有一個(gè)名稱,形式自由的注釋字段,狀態(tài)(通過(guò)或失敗),持續(xù)時(shí)間和結(jié)果(例如,為了與測(cè)試-字節(jié)/秒的吞吐量-的任意數(shù)據(jù)關(guān)聯(lián))。
    因?yàn)槲覀兯P(guān)注是db4o的使用,所以我們不想在描述這些類的使用細(xì)節(jié)上停留。就讓我們簡(jiǎn)單地說(shuō),我們已經(jīng)執(zhí)行了一個(gè)特別地測(cè)試組中所有的測(cè)試用例,將測(cè)試的結(jié)果存放在一個(gè)TestSuite對(duì)象中(與TestCase對(duì)象相關(guān)的ArrayList對(duì)象cases中),然后關(guān)閉數(shù)據(jù)庫(kù)。是不是太容易了。
    // Create the database
    new File("testsuites.YAP").delete();
    ObjectContainer db = Db4o.openFile("testsuites.YAP");
    // Store the TestSuite object
    db.set(testsuite);
    // Close the database
    db.close();
    就是它。彈指一揮間,你就已經(jīng)做到了。(當(dāng)然,為了保持簡(jiǎn)潔,我們?nèi)サ袅藙?chuàng)建TestSuite對(duì)象和它的TestCase組件的細(xì)節(jié))
    停下來(lái)想想上述代碼做了什么事情。特別要考慮你沒(méi)有看到的--db4o已經(jīng)做了但還未被告之的事情。
    首先,我們不需要告訴db4o任何關(guān)于TestSuite類的結(jié)構(gòu)的信息;不需要我們的幫助,db4o就能發(fā)現(xiàn)這個(gè)結(jié)構(gòu)。利用Java反射機(jī)制的能力,db4o測(cè)定TestSuite類的結(jié)構(gòu),并勾勒出該類的裝配方式以推導(dǎo)出此類對(duì)象的成員與關(guān)鍵數(shù)據(jù)。
    第二,我們不必建議db4o去關(guān)注ArrayList。不僅我們不必將ArrayList的大小告訴db4o,而且我們也不必把它里面的內(nèi)容告訴db4o。正如db4o在它剛接觸testsuite對(duì)象時(shí)就能夠發(fā)現(xiàn)它所需要的一切,db4o也能知道它所需要的關(guān)于(在ArrayList中的)TestCase對(duì)象的所有信息。
    結(jié)果就是,如果我們把testsuite作為一個(gè)任意寵大而復(fù)雜的對(duì)象樹(shù)的根,db4o能找到并存儲(chǔ)整個(gè)樹(shù)而不需要我們的任何協(xié)助。所以,存儲(chǔ)這個(gè)處于根部的對(duì)象testsuite也就是存儲(chǔ)了整個(gè)ArrayList對(duì)象。
    最后,我們也沒(méi)有必須要求db4o以事務(wù)的保護(hù)性方式去調(diào)用set方法。任何會(huì)修改ObjectContainer(表示數(shù)據(jù)庫(kù)的db4o對(duì)象)的調(diào)用都會(huì)自動(dòng)地開(kāi)啟一個(gè)事務(wù),除非已經(jīng)有一個(gè)活躍的事務(wù)了。此外還會(huì)調(diào)用close方法去終止這個(gè)事務(wù),所以上述代碼等價(jià)于:
    db.startTransaction();
    db.set(testsuite);
    db.commitTransaction();
    db.close();
    此處的startTransaction和commitTransaction方法是為了證明我們的觀點(diǎn)而虛構(gòu)的。db4o也確實(shí)有顯示地提交或中止事務(wù)的方法,但為了使原先的代碼足夠的簡(jiǎn)潔我們沒(méi)有使用這些方法。db4o隱式的事務(wù)使得數(shù)據(jù)庫(kù)能夠一直處于一致的狀態(tài);一旦commit方法已經(jīng)執(zhí)行了,數(shù)據(jù)庫(kù)的完整性就能夠得到保證,甚至是發(fā)生了災(zāi)難性失敗也能如此。

查詢I - QBE
    有了已經(jīng)存于數(shù)據(jù)庫(kù)中的對(duì)象,下一步我們想要展示的操作將肯定就是查詢和恢復(fù)。db4o提供了三種查詢API:有一種簡(jiǎn)單,有一種優(yōu)雅,還有一種則復(fù)雜。每一種API都有其所長(zhǎng),并適用于不同的查詢條件。以db4o的眼光來(lái)看,你選擇哪一種API并沒(méi)有關(guān)系:它們都是可兼容的。
    我們以簡(jiǎn)單的API開(kāi)始:query by exampel(QBE)。
    使用QBE是如此的容易:為你的查詢目標(biāo)構(gòu)建一個(gè)'模板'對(duì)象,然后把它傳入ObjectContainer的query方法。實(shí)際上,你就是告訴db4o'去拿到所有與這個(gè)對(duì)象看起來(lái)一樣的對(duì)象'。(這與JavaSpaces查詢API非常相似;為了清楚地了解如何處理基本數(shù)據(jù)類型,可以看下面的內(nèi)容,db4o的處理方式與JavaSpaces不同。也要注意,JavaSpace Entry對(duì)象期望使用public字段,db4o則沒(méi)有這種要求。)
    假設(shè)一個(gè)測(cè)試組名為"Network Throughput",我們想取出這個(gè)測(cè)試組執(zhí)行的所有測(cè)試以便我們能確定失敗了的測(cè)試所占的百分比(基于TestSuite的overalScore值)。使用QBE,完成該工作的代碼如下:
    // Open the database
    ObjectContainer db = Db4o.openFile("testsuites.YAP");

    // Instantiate the template object, filling in
    // only the name field
    testTemplate = new TestSuite("Network Throughput");

    // Execute the query
    ObjectSet result = db.get(testTemplate);
    fails = 0.0f;
    total = 0.0f;

    // Step through results,
    while(result.hasNext())
    {
        testsuite = (TestSuite)result.next();
        if(testsuite.getOverallScore()=='F')
        fails += 1.0f;
        total += 1.0f;
    }

    if(total == 0.0f)
        System.out.println("No tests of that type found.");
    else
    {
        System.out.println("Percent failed: " + (fails/total * 100.0f) + "%");
        System.out.println("Total executed: " + total);
    }
    db.close();
    在上面的代碼中,testTemplate是QBE的模板對(duì)象。注意,只有它的name字段有真實(shí)的值;所有其它的成員變量不是為null就是為0。Null或0字段不參與QBE查詢;因此,調(diào)用db.get方法就會(huì)返回在該數(shù)據(jù)庫(kù)中name字段匹配"Network Throughput"的所有TestSuite對(duì)象。匹配的TestSuite對(duì)象將返回在一個(gè)ObjectSet結(jié)果對(duì)象中。上述代碼遍歷該結(jié)果,取出對(duì)象,然后計(jì)算結(jié)果并展示出來(lái)。
    QBE明顯的優(yōu)點(diǎn)就是它的簡(jiǎn)易性。不需要掌握其它單獨(dú)的查詢語(yǔ)言。另外,QBE也是類型安全的:你不需要?jiǎng)?chuàng)建一個(gè)類似于SQL的查詢語(yǔ)句
    SELECT TestSuite.overallScore FROM TestSuite WHERE TestSuite.name = 200.0
    另一方面,由于該查詢是由Java代碼創(chuàng)建的,編譯器不會(huì)允許你把一個(gè)浮點(diǎn)值賦給一個(gè)String字段;反之亦然。
    QBE明顯的缺點(diǎn)就是它只能執(zhí)行"等于"查詢。另外,QBE使用null值去確定不參與查詢的String或?qū)ο笠贸蓡T變量,使用0值去指定不參與查詢的數(shù)字字段。所以,例如,我不能發(fā)明一個(gè)QBE查詢?nèi)カ@得所有result字段的值為0的TestCase對(duì)象。
    更為精細(xì)的查詢要求一個(gè)能力更強(qiáng)的查詢機(jī)制,而db4o恰恰就有這樣一種機(jī)制。

查詢方式II - 原生查詢(Native Query)
    db4o的原生查詢系統(tǒng)應(yīng)該是能想像得到的最具彈性的查詢機(jī)制。不像使用數(shù)據(jù)庫(kù)查詢語(yǔ)言去構(gòu)建查詢,你是使用"無(wú)格式的普通Java語(yǔ)句"去構(gòu)造原生查詢。原生查詢用兩種手段去實(shí)現(xiàn)這件不可思意的工作:一個(gè)是Predicate類;另一個(gè)是QueryComparator接口。這個(gè)類包含一個(gè)可重載的(overrideable)回調(diào)方法,該方法將指定如何從數(shù)據(jù)庫(kù)中選擇對(duì)象(如果你愿意,你將會(huì)看到查詢語(yǔ)句的主體....)。這個(gè)接口只聲明了一個(gè)方法,該方法用于指明如何對(duì)查詢結(jié)果進(jìn)行排序。
    作為一個(gè)例子,我們假設(shè)想找到在給定的一周內(nèi)執(zhí)行過(guò)了的總得分為"failed",但與之關(guān)聯(lián)的測(cè)試用例中有超過(guò)一半的被評(píng)為"passed"的測(cè)試組。這不是一個(gè)簡(jiǎn)單的"等于"查詢,所以它不能使用QBE構(gòu)建。
    然而,db4o的原生查詢可以直接地生成該查詢。首先,我們繼承db4o的Predicate類:
    // Predicate class sub-class for native query example
    public class NativeQueryQuery extends Predicate<TestSuite>
    {
        ObjectContainer db;
        private long startdate;
        private long enddate;

        // 構(gòu)造器要在本地獲得ObjectContainer對(duì)象和日期范圍
        public NativeQueryQuery(ObjectContainer _db,
            long _start, long _end)
        {
            db = _db;
            startdate = _start;
            enddate = _end;
        }

        // 這就是查詢的主體
        public boolean match(TestSuite testsuite)
        {
            float passed;
            float total;
            TestCase testcase;

            // 判斷testsuite是否在指定的日期范圍內(nèi)
            if(testsuite.getDateExec()<startdate ||
              testsuite.getDateExec()>enddate) return false;

            // 如果該測(cè)試組對(duì)象中沒(méi)有測(cè)試用例對(duì)象,則拒絕將該測(cè)試組對(duì)象放入查詢結(jié)果中
            if(testsuite.getNumberOfCases()==0)
                return false;

            // 檢查該測(cè)試組對(duì)象中的測(cè)試用例的通過(guò)率是否超過(guò)50%
            passed = 0.0f;
            total = 0.0f;
            for(int i=0; i<testsuite.getNumberOfCases(); i++)
            {
                testcase = testsuite.getTestCase(i);
                if(testcase.getStatus()=='P')
                    passed+=1.0f;
                total+=1.0f;
            }
            if((passed/total)<.5) return false;
                return true;
        }
    }
    注意在這個(gè)類的使用中使用了Java泛型語(yǔ)義,這就是告訴db4o只去取TestSuite對(duì)象。當(dāng)查詢執(zhí)行時(shí),TestSuite對(duì)象就會(huì)傳入match方法(我們之前提到過(guò)的回調(diào)方法),如果傳入的TestSuite對(duì)象符合查詢規(guī)范該方法就返回true,否則就返回false。
    match方法中的代碼首先確定侯選對(duì)象是否是在一周的日期范圍內(nèi)。如果是,則循環(huán)該對(duì)象中的成員變量測(cè)試用例的對(duì)象,計(jì)算出所有通過(guò)了的測(cè)試用例的總數(shù)。如果,得到的通過(guò)率小于50%,該測(cè)試組就被拒絕;否則,就讓它通過(guò)。
    我們可以使用如下的代碼準(zhǔn)確地展示該查詢程序:
    . . .
    TestSuite testsuite;
    NativeQueryQuery nqqClass;
    Date now;

    // Open the database
    ObjectContainer db = Db4o.openFile("testsuites.YAP");

    // Instantiate a NativeQueryQuery object,
    // setting the start and end dates for
    // any test in the past week
    // 604800000 = milliseconds in a week
    now = new Date();
    nqqClass = new NativeQueryQuery(db,
    now.getTime()-604800000L,
    now.getTime());

    // Execute the query and display the
    // results
    System.out.println("Results:");
    ObjectSet results = db.query(nqqClass);
    if(results.isEmpty())
        System.out.println("  NOTHING TO DISPLAY");

    while(results.hasNext())
    {
        testsuite = (TestSuite)(results.next());
        System.out.println(testsuite.toString());
    }

    db.close();
    . . .
    可以把原生查詢想像成這樣:目標(biāo)類的對(duì)象一個(gè)接一個(gè)從數(shù)據(jù)庫(kù)中取出,然后把它們傳入match方法中。只有那些被match方法返回true的對(duì)象才會(huì)置于查詢結(jié)果ObjectSet對(duì)象中。基本上可以說(shuō),如果你會(huì)知道如何寫(xiě)Java代碼,那么你就知道如何寫(xiě)原生查詢。
    那么排序呢?如果想按日期的升序排列查詢結(jié)果,我們就要實(shí)現(xiàn)QueryComparator接口,如下所示:
    public class NativeQuerySort implements QueryComparator<TestSuite>{
        public int compare(TestSuite t1, TestSuite t2)
        {
            if (t1.getDateExec() < t2.getDateExec()) return -1;
            if (t1.getDateExec() > t2.getDateExec()) return 1;
            return 0;
        }
     }
compare方法的作用十分明顯。那些在查詢中得以勝出的對(duì)象會(huì)成對(duì)的傳入compare方法,如果第一個(gè)對(duì)象會(huì)排在第二個(gè)對(duì)象之前,相同或之后的位置,該方法就會(huì)分別返回一個(gè)小于,等于或大于0的值。為了準(zhǔn)確地說(shuō)明對(duì)查詢結(jié)果的排序,我們實(shí)例化NativeQuerySort,并把對(duì)query方法的調(diào)用修改成如下:
    . . .
    // Instantiate the sort class
    nqsClass = new NativeQuerySort();
    . . .
    ObjectSet results = db.query(nqqClass, nqsClass);
    . . .
其它的代碼仍然與原先的保持一致。
    好懷疑的讀者可能會(huì)抱怨道,原生查詢只是一種編程上的小伎倆--相比較于直接去拿到所有的TestSuite對(duì)象然后再排除其中不符合條件的對(duì)象這樣的程序,原生查詢并不快。
    是的,但并不十分準(zhǔn)確。原生能夠被優(yōu)化。你所需要做的只是把兩個(gè)jar文件--db4o-xxx-nqopt.jar(xxx表示db4o的版本)和bloat.jar--置于CLASSPATH環(huán)境變量中。在查詢執(zhí)行的時(shí)候,這些類庫(kù)中的代碼會(huì)對(duì)(在match方法中)例如基本數(shù)據(jù)類型比較,算術(shù)和布爾表達(dá)式,簡(jiǎn)單的對(duì)象成員訪問(wèn),以及更多方面的結(jié)構(gòu)進(jìn)行優(yōu)化。這個(gè)被支持的優(yōu)化的列表在不停的增長(zhǎng),因?yàn)閐b4o引擎還在擴(kuò)展優(yōu)化的范圍。

查詢方式III - S.O.D.A.
    db4o獨(dú)一無(wú)二的能力之一就是它的API被分層了。開(kāi)發(fā)者能夠選擇通過(guò)高層次--賦予數(shù)據(jù)庫(kù)引擎相當(dāng)大的自由度,讓它決定如何去實(shí)現(xiàn)它的操作--或者開(kāi)發(fā)者也可以使用一種更直接地方式去訪問(wèn)db4o。后一種選擇為程序員平添了更多的負(fù)擔(dān),程序員必須更加小心地引導(dǎo)數(shù)據(jù)庫(kù)引擎的內(nèi)部工作。但回報(bào)就是得到一個(gè)更快,能力更強(qiáng)的數(shù)據(jù)庫(kù)應(yīng)用。
    db4o的S.O.D.A.(Simple Object Data Access)查詢機(jī)制就是該層次API的一個(gè)完美的例子。S.O.D.A.就是db4o的內(nèi)部查詢系統(tǒng)--QBE和原生查詢都被翻譯成了S.O.D.A.。然而,應(yīng)用程序也能直接地調(diào)用S.O.D.A.。
    假設(shè)我們想找到所有名為"Network Throughput",且至少擁有一個(gè)其result字段--我們使用這個(gè)參數(shù)作為字節(jié)/秒的量度--不小于指定值(比方說(shuō),100)的測(cè)試用例的測(cè)試組。為該請(qǐng)求而做的S.O.D.A.查詢可能就像這樣:
    . . .
    TestSuite testsuite;

    // Open the database
    ObjectContainer db = Db4o.openFile("testsuites.YAP");

    // Construct the query
    Query query = db.query();
    query.constrain(TestSuite.class);
    Constraint nameConst = query.descend("name").
    constrain("Network Throughput");
    query.descend("cases").descend("result").
    constrain(100.0f).smaller().and(nameConst);

    System.out.println("Results:");
    // Execute the query
    ObjectSet result = query.execute();
    if(result.isEmpty())
    System.out.println("NOTHING TO DISPLAY");

    while(result.hasNext())
    {
        testsuite = (TestSuite)(result.next());
        System.out.println(testsuite.toString());
    }

    db.close();
    . . .
    在由Illustration 1所示圖表的幫助下,這些有點(diǎn)兒神秘的代碼就變得不那么神秘了。該程序所構(gòu)建的歸總起來(lái)就是一個(gè)用于指導(dǎo)底層數(shù)據(jù)庫(kù)引擎的查詢圖(Query Graph)。descend方法創(chuàng)建了該圖的一個(gè)分支,該分支向下步入對(duì)象的結(jié)構(gòu)中。每個(gè)descend方法就在這個(gè)樹(shù)中構(gòu)建一個(gè)結(jié)點(diǎn),可以在這些結(jié)點(diǎn)上再附上一個(gè)約束(使用constrain方法)。用SQL的話來(lái)說(shuō),約束指定了查詢的"WHERE"子句部分。多個(gè)約束可以在與(and)或或(or)方法的協(xié)助下結(jié)合起來(lái)。在上面的查詢中我們已經(jīng)使用了and方法去關(guān)聯(lián)這些約束。
                                    
與其它的查詢方式一樣,查詢結(jié)果返回到ObjectSet對(duì)象中,通過(guò)遍歷該對(duì)象就可取出那些拿到的對(duì)象。
    注意,由于S.O.D.A.是一種低層次的訪問(wèn)方法,沒(méi)有智能的指示,它就沒(méi)有默認(rèn)的行為。訪問(wèn)cases對(duì)象的成員變量result字段的代碼很簡(jiǎn)單
    query.descend("cases").descend("result"). ...
我們并沒(méi)有告訴S.O.D.A."cases"是一個(gè)集合對(duì)象。所以當(dāng)查詢執(zhí)行時(shí),它會(huì)不被察覺(jué)地檢測(cè)ArrayList對(duì)象cases中所有元素(TestCase對(duì)象)的result字段,然后會(huì)正確地返回那些擁有符合搜索規(guī)范的測(cè)試用例的測(cè)試組。

db4o性能調(diào)優(yōu)
    我們已經(jīng)展示了db4o的基本操作(但無(wú)關(guān)緊要的刪除操作除外,下面將會(huì)提到它)。但,正如我們?cè)诒疚耐ㄆ岬降模琩b4o發(fā)布(expose)了一個(gè)API層次結(jié)構(gòu),以允許開(kāi)發(fā)者能夠選擇以何種層次的API去控制建立在該數(shù)據(jù)庫(kù)引擎之上的應(yīng)用程序。從另一方面看,如果你所想做的只是向數(shù)據(jù)庫(kù)存入,及從數(shù)據(jù)庫(kù)取出對(duì)象,那么你就已經(jīng)看到了你所需要的一切。然而,如果你的應(yīng)用的需求超出了添加,更新,查詢和刪除,可能還有一個(gè)db4o的特性可解決你的問(wèn)題。
    db4o的ObjectContainer實(shí)際上發(fā)布(expose)了兩個(gè)API。第一個(gè)API非常的簡(jiǎn)單,由十個(gè)方法組成。這些方法處理數(shù)據(jù)庫(kù)的打開(kāi)與關(guān)閉;添加,更新,查詢和刪除對(duì)象;及提交或中止事務(wù)。短言之,該API為你提供了在操縱數(shù)據(jù)庫(kù)時(shí)所需要所有功能。然而,該API中的一個(gè)方法--ext()--是進(jìn)入"被擴(kuò)展的"ObjectContainer的一個(gè)入口。該被擴(kuò)展的ObjectContainer為深入控制db4o的內(nèi)部發(fā)布(expose)了更多方法。例如,你可以獲得并改變數(shù)據(jù)庫(kù)的配置上下文,使用它你能夠修改該引擎的行為。
    例如,假設(shè)你已經(jīng)從數(shù)據(jù)庫(kù)中拿到了一個(gè)TestSuite對(duì)象,發(fā)現(xiàn)該對(duì)象中的數(shù)據(jù)是錯(cuò)誤的,并決定該對(duì)象應(yīng)該被刪除。此外,你還決定你必須刪除的不僅是該TestSuite對(duì)象,而且還有所有與之關(guān)聯(lián)的TestCase對(duì)象(在ArrayList對(duì)象cases中)。
    你是可以冗長(zhǎng)而乏味地遍歷這個(gè)ArrayList對(duì)象,一個(gè)接一個(gè)地刪除每一個(gè)TestCase對(duì)象,然后再刪除TestSuite對(duì)象本身。可能一種更好的解決方案是為這個(gè)TestSuite對(duì)象啟用db4o的"級(jí)聯(lián)刪除"特性。
    . . .
    // Fetch the database's configuration context
    Configuration config = db.ext().configure();
    // Get the ObjectClass for TestSuite
    ObjectClass oc = config.objectClass("testsuites.TestSuite");
    // Turn on cascaded delete
    oc.cascadeOnDelete(true);
    ...  ...
    db.delete(ts1);
    . . .
在上述代碼中,我們實(shí)例化了一個(gè)ObjectClass對(duì)象,該對(duì)象使我們能夠訪問(wèn)到TestSuite對(duì)象的db4o內(nèi)部表現(xiàn)形式。我們打開(kāi)cascadeOnDelete標(biāo)記,以便當(dāng)執(zhí)行db4o.delete(ts1)時(shí),不僅ts1對(duì)象會(huì)被刪除,而且所有由ts1引用的TestCase對(duì)象也會(huì)被刪除。(由于顯而易見(jiàn)的原因,默認(rèn)情況下,級(jí)聯(lián)刪除是被關(guān)閉的)
    作為另一個(gè)例子,假設(shè)你想為數(shù)據(jù)庫(kù)預(yù)分配存儲(chǔ)空間,以至于要最小化磁盤(pán)驅(qū)動(dòng)器的頭移動(dòng)(head movement)。(最好是在硬盤(pán)碎片整理之后,并新創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)時(shí)這樣做。)并且假設(shè)以O(shè)bjectContainer對(duì)象db作為打開(kāi)了的數(shù)據(jù)庫(kù):
    // Fetch the database's configuration context
    // 獲得數(shù)據(jù)庫(kù)的配置上下文
    Configuration config = db.ext().configure();
    // Pre-allocate 200,000 bytes
    // 預(yù)分配200000000字節(jié)
    config.reserveStorageSpace(200000000L);
把數(shù)據(jù)庫(kù)文件預(yù)擴(kuò)展到200000000字節(jié)(略小于200兆字節(jié))。假設(shè)該磁盤(pán)已經(jīng)做碎片整理了,那么被分配的塊就是連續(xù)的,這可顯著提升數(shù)據(jù)庫(kù)的訪問(wèn)。

db4o高級(jí)應(yīng)用
    完全可以說(shuō),db4o在它不大的空間(約500K)內(nèi)已裝入了足夠多的特性,相比較于db4o在運(yùn)行過(guò)程中所做的眾多事情,我們不能花費(fèi)更多的筆墨去解釋它們了。但是有兩個(gè)特性十分突出,以至于肯定要提到它們。
    db4o的對(duì)象復(fù)制實(shí)現(xiàn)了被總稱為面向?qū)ο蟀娴臄?shù)據(jù)庫(kù)同步。使用復(fù)制所提供的功能,你能為一個(gè)數(shù)據(jù)庫(kù)中的一個(gè)對(duì)象做一個(gè)副本,并將該副本放入另一個(gè)數(shù)據(jù)庫(kù)中。使用這樣的方法,副本對(duì)象就無(wú)形中和原始對(duì)象關(guān)聯(lián)在了一起。對(duì)任一對(duì)象--原始對(duì)象或副本對(duì)象--的改變都會(huì)被跟蹤到,以便在之后的某個(gè)時(shí)候,數(shù)據(jù)庫(kù)能夠被重組,并且這兩個(gè)數(shù)據(jù)庫(kù)中對(duì)象的不同之處可被分解(例如,可同步這兩個(gè)數(shù)據(jù)庫(kù))。
    它工作起來(lái)就像這樣:為使一個(gè)數(shù)據(jù)庫(kù)可被復(fù)制,與事務(wù)計(jì)數(shù)器一樣,該數(shù)據(jù)庫(kù)中被創(chuàng)建的任何一個(gè)對(duì)象都用一個(gè)唯一全局標(biāo)識(shí)符(UUID)進(jìn)行了標(biāo)記。當(dāng)你從原始數(shù)據(jù)庫(kù)中"復(fù)制"一個(gè)對(duì)象到另一個(gè)數(shù)據(jù)庫(kù)中,副本對(duì)象會(huì)帶著與它的原始對(duì)象相同的UUID和事務(wù)計(jì)數(shù)器。副本數(shù)據(jù)庫(kù)現(xiàn)在就可以從它的原始數(shù)據(jù)庫(kù)那兒弄走了。修改副本對(duì)象的內(nèi)容將會(huì)導(dǎo)致對(duì)象的事務(wù)計(jì)數(shù)器被修改。所以,當(dāng)這兩個(gè)數(shù)據(jù)庫(kù)重新連接起來(lái),db4o內(nèi)建的同步處理機(jī)制就能一個(gè)對(duì)象一個(gè)對(duì)象地進(jìn)行正確的匹配(使用UUID),并確定原始或副本對(duì)象是否已經(jīng)改變了。db4o甚至能追蹤到每個(gè)對(duì)象發(fā)生最后一次修改時(shí)的時(shí)間,以便用戶寫(xiě)的沖突解決代碼能確定哪個(gè)對(duì)象是最近更新的。
    從操作行為來(lái)看,db4o的同步處理機(jī)制與原生查詢十分相似。回想一下,當(dāng)實(shí)現(xiàn)了一個(gè)原生查詢類時(shí),我們要定義一個(gè)match方法,該方法確定哪些對(duì)象符合(或不符合)查詢規(guī)范。使用同步復(fù)制,我們要定義一個(gè)ReplicationProcess對(duì)象,我們會(huì)把沖突處理對(duì)象傳入該方法中。這些Java代碼可能像這樣:
    . . .
    ReplicationProcess replication = db1.ext().
        replicationBegin(db2, new ReplicationConflictHandler()
        {  
            public Object resolveConflict(
                ReplicationProcess rprocess, Object a, Object b)
                {
                    . . .  ...
                    return winning_object;
                }
            )
        };
在上述代碼中,Object a是來(lái)自于數(shù)據(jù)庫(kù)db1的對(duì)象,Object b則來(lái)自于數(shù)據(jù)庫(kù)db2。默認(rèn)情況下,同步是雙向的。同步處理保證勝出的對(duì)象(由resolveConflict方法返回的對(duì)象)能存入這兩個(gè)數(shù)據(jù)庫(kù)中。所以當(dāng)復(fù)制完成時(shí),這兩個(gè)數(shù)據(jù)庫(kù)中被復(fù)制的對(duì)象就同步了。
    最后,db4o最強(qiáng)大的特性之一就是它能毫不費(fèi)力地容忍類結(jié)構(gòu)的演變。假設(shè),在向數(shù)據(jù)庫(kù)內(nèi)加入數(shù)百個(gè)TestSuite對(duì)象之后,我們決定這個(gè)類必須要被修改。就是說(shuō),我們已經(jīng)被告之,該系統(tǒng)必須能追蹤到每個(gè)TestSuite的執(zhí)行QA工程師,所以必須加入如下字段
    private int engineerID;
到TestSuite類的定義中。
    現(xiàn)在我們就遇到了兩個(gè)相關(guān)聯(lián)的問(wèn)題。第一個(gè)問(wèn)題不是很糟糕:已存在于數(shù)據(jù)庫(kù)中的用于表示測(cè)試的TestSuite對(duì)象,并沒(méi)有為它們記錄QA工程師的ID,所以我們將不得不將一個(gè)虛擬的值賦給這些對(duì)象的engineerID字段;該值會(huì)指出"未記錄QA工程師的ID"。第二個(gè)問(wèn)題就更難應(yīng)付了:我們必須不知原因地把已有的TestSuite對(duì)象移植到"新的"類結(jié)構(gòu)中。我們必須為數(shù)據(jù)庫(kù)中所有已存在的TestSuite對(duì)象加上一個(gè)engineerID字段。除了把舊數(shù)據(jù)庫(kù)中的對(duì)象復(fù)制到一個(gè)中間性的文件,然后重新創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)這種方法之外,我們還能怎么做呢?
    幸運(yùn)地是,使用db4o,我們確實(shí)什么都不用做。為了能操縱新的engineerID字段,以完成業(yè)務(wù)邏輯上所要求的變化,如果就只是向(我們的應(yīng)用程序中的)TestSuite類添加一個(gè)engineerID字段,我們完全不必觸動(dòng)db4o API的任何調(diào)用。當(dāng)db4o使用"新的"TestSuite類結(jié)構(gòu)去讀取"舊的"TestSuite對(duì)象,db4o將認(rèn)為這些對(duì)象中的engineerID字段消失了,并且會(huì)優(yōu)雅地把該字段的值設(shè)為0。如果我們把0當(dāng)作"未記錄QA工程師的ID",那么我們所做的移植就完成了。寫(xiě)入到數(shù)據(jù)庫(kù)中的新TestSuite對(duì)象將會(huì)包括新字段。(事實(shí)上,對(duì)舊的TestSuite對(duì)象本身進(jìn)行重寫(xiě),會(huì)使db4o不被察覺(jué)地為這些對(duì)象加上新字段。)所以,通過(guò)發(fā)布一個(gè)包含新的TestSuite定義的更新應(yīng)用,我們完全可以不被察覺(jué)地從舊的TestSuite對(duì)象移植到新的...正如前述應(yīng)用所做的那樣。

全方位數(shù)據(jù)庫(kù)
    通過(guò)適當(dāng)?shù)貞?yīng)用,db4o就能成為數(shù)據(jù)庫(kù)中的"瑞士軍刀"。它占用足夠小的內(nèi)存空間,使它能夠被包含在一個(gè)不需要消耗大量資源的項(xiàng)目中。同樣地,一個(gè)數(shù)據(jù)庫(kù)只在磁盤(pán)上占用一個(gè)文件的事實(shí)可能會(huì)使人們?cè)诘谝谎劭吹剿鼤r(shí),不能認(rèn)識(shí)到它豐富的功能。將數(shù)據(jù)庫(kù)從一個(gè)地方移到另一個(gè)地方就是一個(gè)簡(jiǎn)單的文件拷貝;你不必?fù)?dān)心分離的索引文件,數(shù)據(jù)文件,數(shù)據(jù)庫(kù)結(jié)構(gòu)文件等等這些文件的位置。對(duì)于快速部署和零管理的數(shù)據(jù)庫(kù)應(yīng)用,db4o很能勝任。
    另外,根據(jù)我們已多次描述過(guò)的,db4o在簡(jiǎn)單性和優(yōu)雅之間達(dá)到了適度的平衡。db4o的QBE既如此的簡(jiǎn)單,又如此的功能強(qiáng)大,對(duì)于一組令人驚奇的應(yīng)用,它經(jīng)常是我們唯一需要的查詢API。如果你主要是通過(guò)指針導(dǎo)航而不是查詢?nèi)ピL問(wèn)數(shù)據(jù)庫(kù),QBE就特別有吸引力。在這種情況下,QBE經(jīng)常能高效地拿到一個(gè)對(duì)象網(wǎng)絡(luò)(Object Network)的根對(duì)象。然后,你就能使用db4o的激活(activation)功能從根部向下進(jìn)行對(duì)象引用導(dǎo)航,如果這些對(duì)象都完全在內(nèi)存中的話,你就更可以這么做了。
    而在使用QBE并不高效的時(shí)候,原生查詢和S.O.D.A.就能派上用場(chǎng)了,并且它們伴隨著一堆特性和低層次的API。我們還沒(méi)有展示db4o的加密功能,插入式文件I/O(例如,它允許你添加"寫(xiě)后讀(read-after-write)"驗(yàn)證),信號(hào)量,客戶端/服務(wù)器端模式,以及其它難以計(jì)數(shù)的功能。我們結(jié)論性的建議很簡(jiǎn)單:當(dāng)你的下一個(gè)Java應(yīng)用需要一個(gè)數(shù)據(jù)庫(kù),在最終開(kāi)始編碼之前,你可以去訪問(wèn)一下http://www.db4objects.com/。這是很值得的。



Sha Jiang 2007-12-05 12:31 發(fā)表評(píng)論
]]>
MySQL索引(摘)http://m.tkk7.com/jiangshachina/archive/2007/07/03/127728.htmlSha JiangSha JiangTue, 03 Jul 2007 00:44:00 GMThttp://m.tkk7.com/jiangshachina/archive/2007/07/03/127728.htmlhttp://m.tkk7.com/jiangshachina/comments/127728.htmlhttp://m.tkk7.com/jiangshachina/archive/2007/07/03/127728.html#Feedback0http://m.tkk7.com/jiangshachina/comments/commentRss/127728.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/127728.htmlMySQL索引
    本文介紹了數(shù)據(jù)庫(kù)索引,及其優(yōu)、缺點(diǎn)。針對(duì)MySQL索引的特點(diǎn)、應(yīng)用進(jìn)行了詳細(xì)的描述。分析了如何避免MySQL無(wú)法使用,如何使用EXPLAIN分析查詢語(yǔ)句,如何優(yōu)化MySQL索引的應(yīng)用。本文摘自《MySQL 5權(quán)威指南》(3rd)的8.9節(jié)。(2007.07.05最后更新)

    索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。
    注:[1]索引不是萬(wàn)能的!索引可以加快數(shù)據(jù)檢索操作,但會(huì)使數(shù)據(jù)修改操作變慢。每修改數(shù)據(jù)記錄,索引就必須刷新一次。為了在某種程序上彌補(bǔ)這一缺陷,許多SQL命令都有一個(gè)DELAY_KEY_WRITE項(xiàng)。這個(gè)選項(xiàng)的作用是暫時(shí)制止MySQL在該命令每插入一條新記錄和每修改一條現(xiàn)有之后立刻對(duì)索引進(jìn)行刷新,對(duì)索引的刷新將等到全部記錄插入/修改完畢之后再進(jìn)行。在需要把許多新記錄插入某個(gè)數(shù)據(jù)表的場(chǎng)合,DELAY_KEY_WRITE選項(xiàng)的作用將非常明顯。[2]另外,索引還會(huì)在硬盤(pán)上占用相當(dāng)大的空間。因此應(yīng)該只為最經(jīng)常查詢和最經(jīng)常排序的數(shù)據(jù)列建立索引。注意,如果某個(gè)數(shù)據(jù)列包含許多重復(fù)的內(nèi)容,為它建立索引就沒(méi)有太大的實(shí)際效果。
    從理論上講,完全可以為數(shù)據(jù)表里的每個(gè)字段分別建一個(gè)索引,但MySQL把同一個(gè)數(shù)據(jù)表里的索引總數(shù)限制為16個(gè)。
    1. InnoDB數(shù)據(jù)表的索引
    與MyISAM數(shù)據(jù)表相比,索引對(duì)InnoDB數(shù)據(jù)的重要性要大得多。在InnoDB數(shù)據(jù)表上,索引對(duì)InnoDB數(shù)據(jù)表的重要性要在得多。在InnoDB數(shù)據(jù)表上,索引不僅會(huì)在搜索數(shù)據(jù)記錄時(shí)發(fā)揮作用,還是數(shù)據(jù)行級(jí)鎖定機(jī)制的苊、基礎(chǔ)。"數(shù)據(jù)行級(jí)鎖定"的意思是指在事務(wù)操作的執(zhí)行過(guò)程中鎖定正在被處理的個(gè)別記錄,不讓其他用戶進(jìn)行訪問(wèn)。這種鎖定將影響到(但不限于)SELECT...LOCK IN SHARE MODE、SELECT...FOR UPDATE命令以及INSERT、UPDATE和DELETE命令。
    出于效率方面的考慮,InnoDB數(shù)據(jù)表的數(shù)據(jù)行級(jí)鎖定實(shí)際發(fā)生在它們的索引上,而不是數(shù)據(jù)表自身上。顯然,數(shù)據(jù)行級(jí)鎖定機(jī)制只有在有關(guān)的數(shù)據(jù)表有一個(gè)合適的索引可供鎖定的時(shí)候才能發(fā)揮效力。
    2. 限制
    如果WEHERE子句的查詢條件里有不等號(hào)(WHERE coloum != ...),MySQL將無(wú)法使用索引。
    類似地,如果WHERE子句的查詢條件里使用了函數(shù)(WHERE DAY(column) = ...),MySQL也將無(wú)法使用索引。
    在JOIN操作中(需要從多個(gè)數(shù)據(jù)表提取數(shù)據(jù)時(shí)),MySQL只有在主鍵和外鍵的數(shù)據(jù)類型相同時(shí)才能使用索引。
    如果WHERE子句的查詢條件里使用比較操作符LIKE和REGEXP,MySQL只有在搜索模板的第一個(gè)字符不是通配符的情況下才能使用索引。比如說(shuō),如果查詢條件是LIKE 'abc%',MySQL將使用索引;如果查詢條件是LIKE '%abc',MySQL將不使用索引。
    在ORDER BY操作中,MySQL只有在排序條件不是一個(gè)查詢條件表達(dá)式的情況下才使用索引。(雖然如此,在涉及多個(gè)數(shù)據(jù)表查詢里,即使有索引可用,那些索引在加快ORDER BY方面也沒(méi)什么作用)
    如果某個(gè)數(shù)據(jù)列里包含許多重復(fù)的值,就算為它建立了索引也不會(huì)有很好的效果。比如說(shuō),如果某個(gè)數(shù)據(jù)列里包含的凈是些諸如"0/1"或"Y/N"等值,就沒(méi)有必要為它創(chuàng)建一個(gè)索引。
   
    普通索引、唯一索引和主索引
    1. 普通索引
    普通索引(由關(guān)鍵字KEY或INDEX定義的索引)的唯一任務(wù)是加快對(duì)數(shù)據(jù)的訪問(wèn)速度。因此,應(yīng)該只為那些最經(jīng)常出現(xiàn)在查詢條件(WHERE column = ...)或排序條件(ORDER BY column)中的數(shù)據(jù)列創(chuàng)建索引。只要有可能,就應(yīng)該選擇一個(gè)數(shù)據(jù)最整齊、最緊湊的數(shù)據(jù)列(如一個(gè)整數(shù)類型的數(shù)據(jù)列)來(lái)創(chuàng)建索引。
    2. 唯一索引
    普通索引允許被索引的數(shù)據(jù)列包含重復(fù)的值。比如說(shuō),因?yàn)槿擞锌赡芡酝粋€(gè)姓名在同一個(gè)"員工個(gè)人資料"數(shù)據(jù)表里可能出現(xiàn)兩次或更多次。
    如果能確定某個(gè)數(shù)據(jù)列將只包含彼此各不相同的值,在為這個(gè)數(shù)據(jù)列創(chuàng)建索引的時(shí)候就應(yīng)該用關(guān)鍵字UNIQUE把它定義為一個(gè)唯一索引。這么做的好處:一是簡(jiǎn)化了MySQL對(duì)這個(gè)索引的管理工作,這個(gè)索引也因此而變得更有效率;二是MySQL會(huì)在有新記錄插入數(shù)據(jù)表時(shí),自動(dòng)檢查新記錄的這個(gè)字段的值是否已經(jīng)在某個(gè)記錄的這個(gè)字段里出現(xiàn)過(guò)了;如果是,MySQL將拒絕插入那條新記錄。也就是說(shuō),唯一索引可以保證數(shù)據(jù)記錄的唯一性。事實(shí)上,在許多場(chǎng)合,人們創(chuàng)建唯一索引的目的往往不是為了提高訪問(wèn)速度,而只是為了避免數(shù)據(jù)出現(xiàn)重復(fù)。
    3. 主索引
    在前面已經(jīng)反復(fù)多次強(qiáng)調(diào)過(guò):必須為主鍵字段創(chuàng)建一個(gè)索引,這個(gè)索引就是所謂的"主索引"。主索引與唯一索引的唯一區(qū)別是:前者在定義時(shí)使用的關(guān)鍵字是PRIMARY而不是UNIQUE。
    4. 外鍵索引
    如果為某個(gè)外鍵字段定義了一個(gè)外鍵約束條件,MySQL就會(huì)定義一個(gè)內(nèi)部索引來(lái)幫助自己以最有效率的方式去管理和使用外鍵約束條件。
    5. 復(fù)合索引
    索引可以覆蓋多個(gè)數(shù)據(jù)列,如像INDEX(columnA, columnB)索引。這種索引的特點(diǎn)是MySQL可以有選擇地使用一個(gè)這樣的索引。如果查詢操作只需要用到columnA數(shù)據(jù)列上的一個(gè)索引,就可以使用復(fù)合索引INDEX(columnA, columnB)。不過(guò),這種用法僅適用于在復(fù)合索引中排列在前的數(shù)據(jù)列組合。比如說(shuō),INDEX(A, B, C)可以當(dāng)做A或(A, B)的索引來(lái)使用,但不能當(dāng)做B、C或(B, C)的索引來(lái)使用。
    6. 索引的長(zhǎng)度
    在為CHAR和VARCHAR類型的數(shù)據(jù)列定義索引時(shí),可以把索引的長(zhǎng)度限制為一個(gè)給定的字符個(gè)數(shù)(這個(gè)數(shù)字必須小于這個(gè)字段所允許的最大字符個(gè)數(shù))。這么做的好處是可以生成一個(gè)尺寸比較小、檢索速度卻比較快的索引文件。在絕大多數(shù)應(yīng)用里,數(shù)據(jù)庫(kù)中的字符串?dāng)?shù)據(jù)大都以各種各樣的名字為主,把索引的長(zhǎng)度設(shè)置為10~15個(gè)字符已經(jīng)足以把搜索范圍縮小到很少的幾條數(shù)據(jù)記錄了。
    在為BLOB和TEXT類型的數(shù)據(jù)列創(chuàng)建索引時(shí),必須對(duì)索引的長(zhǎng)度做出限制;MySQL所允許的最大索引長(zhǎng)度是255個(gè)字符。

    全文索引
    文本字段上的普通索引只能加快對(duì)出現(xiàn)在字段內(nèi)容最前面的字符串(也就是字段內(nèi)容開(kāi)頭的字符)進(jìn)行檢索操作。如果字段里存放的是由幾個(gè)、甚至是多個(gè)單詞構(gòu)成的較大段文字,普通索引就沒(méi)什么作用了。這種檢索往往以LIKE %word%的形式出現(xiàn),這對(duì)MySQL來(lái)說(shuō)很復(fù)雜,如果需要處理的數(shù)據(jù)量很大,響應(yīng)時(shí)間就會(huì)很長(zhǎng)。
    這類場(chǎng)合正是全文索引(full-text index)可以大顯身手的地方。在生成這種類型的索引時(shí),MySQL將把在文本中出現(xiàn)的所有單詞創(chuàng)建為一份清單,查詢操作將根據(jù)這份清單去檢索有關(guān)的數(shù)據(jù)記錄。全文索引即可以隨數(shù)據(jù)表一同創(chuàng)建,也可以等日后有必要時(shí)再使用下面這條命令添加:
        ALTER TABLE tablename ADD FULLTEXT(column1, column2)
    有了全文索引,就可以用SELECT查詢命令去檢索那些包含著一個(gè)或多個(gè)給定單詞的數(shù)據(jù)記錄了。下面是這類查詢命令的基本語(yǔ)法:
        SELECT * FROM tablename
        WHERE MATCH(column1, column2) AGAINST('word1', 'word2', 'word3')
    上面這條命令將把column1和column2字段里有word1、word2和word3的數(shù)據(jù)記錄全部查詢出來(lái)。
    注解:InnoDB數(shù)據(jù)表不支持全文索引。

    查詢和索引的優(yōu)化
    只有當(dāng)數(shù)據(jù)庫(kù)里已經(jīng)有了足夠多的測(cè)試數(shù)據(jù)時(shí),它的性能測(cè)試結(jié)果才有實(shí)際參考價(jià)值。如果在測(cè)試數(shù)據(jù)庫(kù)里只有幾百條數(shù)據(jù)記錄,它們往往在執(zhí)行完第一條查詢命令之后就被全部加載到內(nèi)存里,這將使后續(xù)的查詢命令都執(zhí)行得非常快--不管有沒(méi)有使用索引。只有當(dāng)數(shù)據(jù)庫(kù)里的記錄超過(guò)了1000條、數(shù)據(jù)總量也超過(guò)了MySQL服務(wù)器上的內(nèi)存總量時(shí),數(shù)據(jù)庫(kù)的性能測(cè)試結(jié)果才有意義。
    在不確定應(yīng)該在哪些數(shù)據(jù)列上創(chuàng)建索引的時(shí)候,人們從EXPLAIN SELECT命令那里往往可以獲得一些幫助。這其實(shí)只是簡(jiǎn)單地給一條普通的SELECT命令加一個(gè)EXPLAIN關(guān)鍵字作為前綴而已。有了這個(gè)關(guān)鍵字,MySQL將不是去執(zhí)行那條SELECT命令,而是去對(duì)它進(jìn)行分析。MySQL將以表格的形式把查詢的執(zhí)行過(guò)程和用到的索引(如果有的話)等信息列出來(lái)。
    在EXPLAIN命令的輸出結(jié)果里,第1列是從數(shù)據(jù)庫(kù)讀取的數(shù)據(jù)表的名字,它們按被讀取的先后順序排列。type列指定了本數(shù)據(jù)表與其它數(shù)據(jù)表之間的關(guān)聯(lián)關(guān)系(JOIN)。在各種類型的關(guān)聯(lián)關(guān)系當(dāng)中,效率最高的是system,然后依次是const、eq_ref、ref、range、index和All(All的意思是:對(duì)應(yīng)于上一級(jí)數(shù)據(jù)表里的每一條記錄,這個(gè)數(shù)據(jù)表里的所有記錄都必須被讀取一遍--這種情況往往可以用一索引來(lái)避免)。
    possible_keys數(shù)據(jù)列給出了MySQL在搜索數(shù)據(jù)記錄時(shí)可選用的各個(gè)索引。key數(shù)據(jù)列是MySQL實(shí)際選用的索引,這個(gè)索引按字節(jié)計(jì)算的長(zhǎng)度在key_len數(shù)據(jù)列里給出。比如說(shuō),對(duì)于一個(gè)INTEGER數(shù)據(jù)列的索引,這個(gè)字節(jié)長(zhǎng)度將是4。如果用到了復(fù)合索引,在key_len數(shù)據(jù)列里還可以看到MySQL具體使用了它的哪些部分。作為一般規(guī)律,key_len數(shù)據(jù)列里的值越小越好(意思是更快)。
    ref數(shù)據(jù)列給出了關(guān)聯(lián)關(guān)系中另一個(gè)數(shù)據(jù)表里的數(shù)據(jù)列的名字。row數(shù)據(jù)列是MySQL在執(zhí)行這個(gè)查詢時(shí)預(yù)計(jì)會(huì)從這個(gè)數(shù)據(jù)表里讀出的數(shù)據(jù)行的個(gè)數(shù)。row數(shù)據(jù)列里的所有數(shù)字的乘積可以讓我們大致了解這個(gè)查詢需要處理多少組合。
    最后,extra數(shù)據(jù)列提供了與JOIN操作有關(guān)的更多信息,比如說(shuō),如果MySQL在執(zhí)行這個(gè)查詢時(shí)必須創(chuàng)建一個(gè)臨時(shí)數(shù)據(jù)表,就會(huì)在extra列看到using temporary字樣。



Sha Jiang 2007-07-03 08:44 發(fā)表評(píng)論
]]>
My.cnf配置選項(xiàng)(摘)http://m.tkk7.com/jiangshachina/archive/2007/05/23/119308.htmlSha JiangSha JiangWed, 23 May 2007 01:26:00 GMThttp://m.tkk7.com/jiangshachina/archive/2007/05/23/119308.htmlhttp://m.tkk7.com/jiangshachina/comments/119308.htmlhttp://m.tkk7.com/jiangshachina/archive/2007/05/23/119308.html#Feedback2http://m.tkk7.com/jiangshachina/comments/commentRss/119308.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/119308.htmlMy.cnf配置選項(xiàng)
本文中的配置都是從《MySQL5權(quán)威指南(3rd)》中摘抄出來(lái)的,個(gè)人認(rèn)為對(duì)于使用MySQL十分有用。放在此處方便自己隨時(shí)查閱,也希望對(duì)其他朋友有所助益。(2007.05.30最后更新)

mysqld程序--目錄和文件
basedir = path  使用給定目錄作為根目錄(安裝目錄)。
character-sets-dir = path  給出存放著字符集的目錄。
datadir = path  從給定目錄讀取數(shù)據(jù)庫(kù)文件。
pid-file = filename  為mysqld程序指定一個(gè)存放進(jìn)程ID的文件(僅適用于UNIX/Linux系統(tǒng)); Init-V腳本需要使用這個(gè)文件里的進(jìn)程ID結(jié)束mysqld進(jìn)程。
socket = filename  為MySQL客戶程序與服務(wù)器之間的本地通信指定一個(gè)套接字文件(僅適用于UNIX/Linux系統(tǒng); 默認(rèn)設(shè)置一般是/var/lib/mysql/mysql.sock文件)。
    在Windows環(huán)境下,如果MySQL客戶與服務(wù)器是通過(guò)命名管道進(jìn)行通信的,--sock選項(xiàng)給出的將是該命名管道的名字(默認(rèn)設(shè)置是MySQL)。
lower_case_table_name = 1/0  新目錄和數(shù)據(jù)表的名字是否只允許使用小寫(xiě)字母; 這個(gè)選項(xiàng)在Windows環(huán)境下的默認(rèn)設(shè)置是1(只允許使用小寫(xiě)字母)。

mysqld程序--語(yǔ)言設(shè)置
character-sets-server = name  新數(shù)據(jù)庫(kù)或數(shù)據(jù)表的默認(rèn)字符集。為了與MySQL的早期版本保持兼容,這個(gè)字符集也可以用--default-character-set選項(xiàng)給出; 但這個(gè)選項(xiàng)已經(jīng)顯得有點(diǎn)過(guò)時(shí)了。
collation-server = name  新數(shù)據(jù)庫(kù)或數(shù)據(jù)表的默認(rèn)排序方式。
lanuage = name  用指定的語(yǔ)言顯示出錯(cuò)信息。

mysqld程序--通信、網(wǎng)絡(luò)、信息安全
enable-named-pipes  允許Windows 2000/XP環(huán)境下的客戶和服務(wù)器使用命名管道(named pipe)進(jìn)行通信。這個(gè)命名管道的默認(rèn)名字是MySQL,但可以用--socket選項(xiàng)來(lái)改變。
local-infile [=0]  允許/禁止使用LOAD DATA LOCAL語(yǔ)句來(lái)處理本地文件。
myisam-recover [=opt1, opt2, ...]  在啟動(dòng)時(shí)自動(dòng)修復(fù)所有受損的MyISAM數(shù)據(jù)表。這個(gè)選項(xiàng)的可取值有4種:DEFAULT、BACKUP、QUICK和FORCE; 它們與myisamchk程序的同名選項(xiàng)作用相同。
old-passwords  使用MySQL 3.23和4.0版本中的老算法來(lái)加密mysql數(shù)據(jù)庫(kù)里的密碼(默認(rèn)使用MySQL 4.1版本開(kāi)始引入的新加密算法)。
port = n  為MySQL程序指定一個(gè)TCP/IP通信端口(通常是3306端口)。
safe-user-create  只有在mysql.user數(shù)據(jù)庫(kù)表上擁有INSERT權(quán)限的用戶才能使用GRANT命令; 這是一種雙保險(xiǎn)機(jī)制(此用戶還必須具備GRANT權(quán)限才能執(zhí)行GRANT命令)。
shared-memory  允許使用內(nèi)存(shared memory)進(jìn)行通信(僅適用于Windows)。
shared-memory-base-name = name  給共享內(nèi)存塊起一個(gè)名字(默認(rèn)的名字是MySQL)。
skip-grant-tables  不使用mysql數(shù)據(jù)庫(kù)里的信息來(lái)進(jìn)行訪問(wèn)控制(警告:這將允許用戶任何用戶去修改任何數(shù)據(jù)庫(kù))。
skip-host-cache  不使用高速緩存區(qū)來(lái)存放主機(jī)名和IP地址的對(duì)應(yīng)關(guān)系。
skip-name-resovle  不把IP地址解析為主機(jī)名; 與訪問(wèn)控制(mysql.user數(shù)據(jù)表)有關(guān)的檢查全部通過(guò)IP地址行進(jìn)。
skip-networking  只允許通過(guò)一個(gè)套接字文件(Unix/Linux系統(tǒng))或通過(guò)命名管道(Windows系統(tǒng))進(jìn)行本地連接,不允許ICP/IP連接; 這提高了安全性,但阻斷了來(lái)自網(wǎng)絡(luò)的外部連接和所有的Java客戶程序(Java客戶即使在本地連接里也使用TCP/IP)。
user = name  mysqld程序在啟動(dòng)后將在給定UNIX/Linux賬戶下執(zhí)行; mysqld必須從root賬戶啟動(dòng)才能在啟動(dòng)后切換到另一個(gè)賬戶下執(zhí)行; mysqld_safe腳本將默認(rèn)使用--user=mysql選項(xiàng)來(lái)啟動(dòng)mysqld程序。

mysqld程序--內(nèi)存管理、優(yōu)化、查詢緩存區(qū)
bulk_insert_buffer_size = n  為一次插入多條新記錄的INSERT命令分配的緩存區(qū)長(zhǎng)度(默認(rèn)設(shè)置是8M)。
key_buffer_size = n  用來(lái)存放索引區(qū)塊的RMA值(默認(rèn)設(shè)置是8M)。
join_buffer_size = n  在參加JOIN操作的數(shù)據(jù)列沒(méi)有索引時(shí)為JOIN操作分配的緩存區(qū)長(zhǎng)度(默認(rèn)設(shè)置是128K)。
max_heap_table_size = n  HEAP數(shù)據(jù)表的最大長(zhǎng)度(默認(rèn)設(shè)置是16M); 超過(guò)這個(gè)長(zhǎng)度的HEAP數(shù)據(jù)表將被存入一個(gè)臨時(shí)文件而不是駐留在內(nèi)存里。
max_connections = n  MySQL服務(wù)器同時(shí)處理的數(shù)據(jù)庫(kù)連接的最大數(shù)量(默認(rèn)設(shè)置是100)。
query_cache_limit = n  允許臨時(shí)存放在查詢緩存區(qū)里的查詢結(jié)果的最大長(zhǎng)度(默認(rèn)設(shè)置是1M)。
query_cache_size = n  查詢緩存區(qū)的最大長(zhǎng)度(默認(rèn)設(shè)置是0,不開(kāi)辟查詢緩存區(qū))。
query_cache_type = 0/1/2  查詢緩存區(qū)的工作模式:0, 禁用查詢緩存區(qū); 1,啟用查詢緩存區(qū)(默認(rèn)設(shè)置); 2,"按需分配"模式,只響應(yīng)SELECT SQL_CACHE命令。
read_buffer_size = n  為從數(shù)據(jù)表順序讀取數(shù)據(jù)的讀操作保留的緩存區(qū)的長(zhǎng)度(默認(rèn)設(shè)置是128KB); 這個(gè)選項(xiàng)的設(shè)置值在必要時(shí)可以用SQL命令SET SESSION read_buffer_size = n命令加以改變。
read_rnd_buffer_size = n  類似于read_buffer_size選項(xiàng),但針對(duì)的是按某種特定順序(比如使用了ORDER BY子句的查詢)輸出的查詢結(jié)果(默認(rèn)設(shè)置是256K)。
sore_buffer = n  為排序操作分配的緩存區(qū)的長(zhǎng)度(默認(rèn)設(shè)置是2M); 如果這個(gè)緩存區(qū)太小,則必須創(chuàng)建一個(gè)臨時(shí)文件來(lái)進(jìn)行排序。
table_cache = n  同時(shí)打開(kāi)的數(shù)據(jù)表的數(shù)量(默認(rèn)設(shè)置是64)。
tmp_table_size = n  臨時(shí)HEAP數(shù)據(jù)表的最大長(zhǎng)度(默認(rèn)設(shè)置是32M); 超過(guò)這個(gè)長(zhǎng)度的臨時(shí)數(shù)據(jù)表將被轉(zhuǎn)換為MyISAM數(shù)據(jù)表并存入一個(gè)臨時(shí)文件。

mysqld程序--日志
log [= file]  把所有的連接以及所有的SQL命令記入日志(通用查詢?nèi)罩?; 如果沒(méi)有給出file參數(shù),MySQL將在數(shù)據(jù)庫(kù)目錄里創(chuàng)建一個(gè)hostname.log文件作為這種日志文件(hostname是服務(wù)器的主機(jī)名)。
log-slow-queries [= file]  把執(zhí)行用時(shí)超過(guò)long_query_time變量值的查詢命令記入日志(慢查詢?nèi)罩?; 如果沒(méi)有給出file參數(shù),MySQL將在數(shù)據(jù)庫(kù)目錄里創(chuàng)建一個(gè)hostname-slow.log文件作為這種日志文件(hostname是服務(wù)器主機(jī) 名)。
long_query_time = n  慢查詢的執(zhí)行用時(shí)上限(默認(rèn)設(shè)置是10s)。
long_queries_not_using_indexs  把慢查詢以及執(zhí)行時(shí)沒(méi)有使用索引的查詢命令全都記入日志(其余同--log-slow-queries選項(xiàng))。
log-bin [= filename]  把對(duì)數(shù)據(jù)進(jìn)行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二進(jìn)制格式記入日志(二進(jìn)制變更日志,binary update log)。這種日志的文件名是filename.n或默認(rèn)的hostname.n,其中n是一個(gè)6位數(shù)字的整數(shù)(日志文件按順序編號(hào))。
log-bin-index = filename  二進(jìn)制日志功能的索引文件名。在默認(rèn)情況下,這個(gè)索引文件與二進(jìn)制日志文件的名字相同,但后綴名是.index而不是.nnnnnn。
max_binlog_size = n  二進(jìn)制日志文件的最大長(zhǎng)度(默認(rèn)設(shè)置是1GB)。在前一個(gè)二進(jìn)制日志文件里的信息量超過(guò)這個(gè)最大長(zhǎng)度之前,MySQL服務(wù)器會(huì)自動(dòng)提供一個(gè)新的二進(jìn)制日志文件接續(xù)上。
binlog-do-db = dbname  只把給定數(shù)據(jù)庫(kù)里的變化情況記入二進(jìn)制日志文件,其他數(shù)據(jù)庫(kù)里的變化情況不記載。如果需要記載多個(gè)數(shù)據(jù)庫(kù)里的變化情況,就必須在配置文件使用多個(gè)本選項(xiàng)來(lái)設(shè)置,每個(gè)數(shù)據(jù)庫(kù)一行。
binlog-ignore-db = dbname  不把給定數(shù)據(jù)庫(kù)里的變化情況記入二進(jìn)制日志文件。
sync_binlog = n  每經(jīng)過(guò)n次日志寫(xiě)操作就把日志文件寫(xiě)入硬盤(pán)一次(對(duì)日志信息進(jìn)行一次同步)。n=1是最安全的做法,但效率最低。默認(rèn)設(shè)置是n=0,意思是由操作系統(tǒng)來(lái)負(fù)責(zé)二進(jìn)制日志文件的同步工作。
log-update [= file]  記載出錯(cuò)情況的日志文件名(出錯(cuò)日志)。這種日志功能無(wú)法禁用。如果沒(méi)有給出file參數(shù),MySQL會(huì)使用hostname.err作為種日志文件的名字。

mysqld程序--鏡像(主控鏡像服務(wù)器)
server-id = n  給服務(wù)器分配一個(gè)獨(dú)一無(wú)二的ID編號(hào); n的取值范圍是1~2的32次方啟用二進(jìn)制日志功能。
log-bin = name  啟用二進(jìn)制日志功能。這種日志的文件名是filename.n或默認(rèn)的hostname.n,其中的n是一個(gè)6位數(shù)字的整數(shù)(日志文件順序編號(hào))。
binlog-do/ignore-db = dbname  只把給定數(shù)據(jù)庫(kù)里的變化情況記入二進(jìn)制日志文件/不把給定的數(shù)據(jù)庫(kù)里的變化記入二進(jìn)制日志文件。

mysqld程序--鏡像(從屬鏡像服務(wù)器)
server-id = n  給服務(wù)器分配一個(gè)唯一的ID編號(hào)
log-slave-updates  啟用從屬服務(wù)器上的日志功能,使這臺(tái)計(jì)算機(jī)可以用來(lái)構(gòu)成一個(gè)鏡像鏈(A->B->C)。
master-host = hostname  主控服務(wù)器的主機(jī)名或IP地址。如果從屬服務(wù)器上存在mater.info文件(鏡像關(guān)系定義文件),它將忽略此選項(xiàng)。
master-user = replicusername  從屬服務(wù)器用來(lái)連接主控服務(wù)器的用戶名。如果從屬服務(wù)器上存在mater.info文件,它將忽略此選項(xiàng)。
master-password = passwd  從屬服務(wù)器用來(lái)連接主控服務(wù)器的密碼。如果從屬服務(wù)器上存在mater.info文件,它將忽略此選項(xiàng)。
master-port = n  從屬服務(wù)器用來(lái)連接主控服務(wù)器的TCP/IP端口(默認(rèn)設(shè)置是3306端口)。
master-connect-retry = n  如果與主控服務(wù)器的連接沒(méi)有成功,則等待n秒(s)后再進(jìn)行管理方式(默認(rèn)設(shè)置是60s)。如果從屬服務(wù)器存在mater.info文件,
    它將忽略此選項(xiàng)。
master-ssl-xxx = xxx  對(duì)主、從服務(wù)器之間的SSL通信進(jìn)行配置。
read-only = 0/1  0: 允許從屬服務(wù)器獨(dú)立地執(zhí)行SQL命令(默認(rèn)設(shè)置); 1: 從屬服務(wù)器只能執(zhí)行來(lái)自主控服務(wù)器的SQL命令。
read-log-purge = 0/1  1: 把處理完的SQL命令立刻從中繼日志文件里刪除(默認(rèn)設(shè)置); 0: 不把處理完的SQL命令立刻從中繼日志文件里刪除。
replicate-do-table = dbname.tablename  與--replicate-do-table選項(xiàng)的含義和用法相同,但數(shù)據(jù)庫(kù)和數(shù)據(jù)庫(kù)表名字里允許出現(xiàn)通配符"%"
    (例如: test%.%--對(duì)名字以"test"開(kāi)頭的所有數(shù)據(jù)庫(kù)里的所以數(shù)據(jù)庫(kù)表進(jìn)行鏡像處理)。
replicate-do-db = name  只對(duì)這個(gè)數(shù)據(jù)庫(kù)進(jìn)行鏡像處理。
replicate-ignore-table = dbname.tablename  不對(duì)這個(gè)數(shù)據(jù)表進(jìn)行鏡像處理。
replicate-wild-ignore-table = dbn.tablen  不對(duì)這些數(shù)據(jù)表進(jìn)行鏡像處理。
replicate-ignore-db = dbname  不對(duì)這個(gè)數(shù)據(jù)庫(kù)進(jìn)行鏡像處理。
replicate-rewrite-db = db1name > db2name  把主控?cái)?shù)據(jù)庫(kù)上的db1name數(shù)據(jù)庫(kù)鏡像處理為從屬服務(wù)器上的db2name數(shù)據(jù)庫(kù)。
report-host = hostname  從屬服務(wù)器的主機(jī)名; 這項(xiàng)信息只與SHOW SLAVE HOSTS命令有關(guān)--主控服務(wù)器可以用這條命令生成一份從屬服務(wù)器的名單。
slave-compressed-protocol = 1  主、從服務(wù)器使用壓縮格式進(jìn)行通信--如果它們都支持這么做的話。
slave-skip-errors = n1, n2, ...或all  即使發(fā)生出錯(cuò)代碼為n1、n2等的錯(cuò)誤,鏡像處理工作也繼續(xù)進(jìn)行(即不管發(fā)生什么錯(cuò)誤,鏡像處理工作也繼續(xù)進(jìn)行)。
    如果配置得當(dāng),從屬服務(wù)器不應(yīng)該在執(zhí)行SQL命令時(shí)發(fā)生錯(cuò)誤(在主控服務(wù)器上執(zhí)行出錯(cuò)的SQL命令不會(huì)被發(fā)送到從屬服務(wù)器上做鏡像處理); 如果不使用
    slave-skip-errors選項(xiàng),從屬服務(wù)器上的鏡像工作就可能國(guó)為發(fā)生錯(cuò)誤而中斷,中斷后需要有人工參與才能繼續(xù)進(jìn)行。

mysqld--InnoDB--基本設(shè)置、表空間文件
skip-innodb  不加載InnoDB數(shù)據(jù)表驅(qū)動(dòng)程序--如果用不著InnoDB數(shù)據(jù)表,可以用這個(gè)選項(xiàng)節(jié)省一些內(nèi)存。
innodb-file-per-table  為每一個(gè)新數(shù)據(jù)表創(chuàng)建一個(gè)表空間文件而不是把數(shù)據(jù)表都集中保存在中央表空間里(后者是默認(rèn)設(shè)置)。該選項(xiàng)始見(jiàn)于MySQL 4.1。
innodb-open-file = n  InnoDB數(shù)據(jù)表驅(qū)動(dòng)程序最多可以同時(shí)打開(kāi)的文件數(shù)(默認(rèn)設(shè)置是300)。如果使用了innodb-file-per-table選項(xiàng)并且需要同時(shí)打開(kāi)很多
    數(shù)據(jù)表的話,這個(gè)數(shù)字很可能需要加大。
innodb_data_home_dir = p  InnoDB主目錄,所有與InnoDB數(shù)據(jù)表有關(guān)的目錄或文件路徑都相對(duì)于這個(gè)路徑。在默認(rèn)的情況下,這個(gè)主目錄就是MySQL的數(shù)據(jù)目錄。
innodb_data_file_path = ts  用來(lái)容納InnoDB為數(shù)據(jù)表的表空間: 可能涉及一個(gè)以上的文件; 每一個(gè)表空間文件的最大長(zhǎng)度都必須以字節(jié)(B)、兆字節(jié)(MB)或
    千兆字節(jié)(GB)為單位給出; 表空間文件的名字必須以分號(hào)隔開(kāi); 最后一個(gè)表空間文件還可以帶一個(gè)autoextend屬性和一個(gè)最大長(zhǎng)度(max:n)。
    例如,ibdata1:1G; ibdata2:1G:autoextend:max:2G的意思是: 表空間文件ibdata1的最大長(zhǎng)度是1GB,ibdata2的最大長(zhǎng)度也是1G,但允許它擴(kuò)充到2GB。
    除文件名外,還可以用硬盤(pán)分區(qū)的設(shè)置名來(lái)定義表空間,此時(shí)必須給表空間的最大初始長(zhǎng)度值加上newraw關(guān)鍵字做后綴,給表空間的最大擴(kuò)充長(zhǎng)度值加上
    raw關(guān)鍵字做后綴(例如/dev/hdb1:20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默認(rèn)設(shè)置是ibdata1:10M:autoextend。
innodb_autoextend_increment = n  帶有autoextend屬性的表空間文件每次加大多少兆字節(jié)(默認(rèn)設(shè)置是8MB)。這個(gè)屬性不涉及具體的數(shù)據(jù)表文件,那些文件的
    增大速度相對(duì)是比較小的。
innodb_lock_wait_timeout = n  如果某個(gè)事務(wù)在等待n秒(s)后還沒(méi)有獲得所需要的資源,就使用ROLLBACK命令放棄這個(gè)事務(wù)。這項(xiàng)設(shè)置對(duì)于發(fā)現(xiàn)和處理未能被
    InnoDB數(shù)據(jù)表驅(qū)動(dòng)程序識(shí)別出來(lái)的死鎖條件有著重要的意義。這個(gè)選項(xiàng)的默認(rèn)設(shè)置是50s。
innodb_fast_shutdown 0/1  是否以最快的速度關(guān)閉InnoDB,默認(rèn)設(shè)置是1,意思是不把緩存在INSERT緩存區(qū)的數(shù)據(jù)寫(xiě)入數(shù)據(jù)表,那些數(shù)據(jù)將在MySQL服務(wù)器下次
    啟動(dòng)時(shí)再寫(xiě)入(這么做沒(méi)有什么風(fēng)險(xiǎn),因?yàn)镮NSERT緩存區(qū)是表空間的一個(gè)組成部分,數(shù)據(jù)不會(huì)丟失)。把這個(gè)選項(xiàng)設(shè)置為0反面危險(xiǎn),因?yàn)樵谟?jì)算機(jī)關(guān)閉時(shí),
    InnoDB驅(qū)動(dòng)程序很可能沒(méi)有足夠的時(shí)間完成它的數(shù)據(jù)同步工作,操作系統(tǒng)也許會(huì)在它完成數(shù)據(jù)同步工作之前強(qiáng)行結(jié)束InnoDB,而這會(huì)導(dǎo)致數(shù)據(jù)不完整。

mysqld程序--InnoDB--日志
innodb_log_group_home_dir = p  用來(lái)存放InnoDB日志文件的目錄路徑(如ib_logfile0、ib_logfile1等)。在默認(rèn)的情況下,InnoDB驅(qū)動(dòng)程序?qū)⑹褂肕ySQL數(shù)據(jù)目
    錄作為自己保存日志文件的位置。   
innodb_log_files_in_group = n  使用多少個(gè)日志文件(默認(rèn)設(shè)置是2)。InnoDB數(shù)據(jù)表驅(qū)動(dòng)程序?qū)⒁暂嗈D(zhuǎn)方式依次填寫(xiě)這些文件; 當(dāng)所有的日志文件都寫(xiě)滿以后,
    之后的日志信息將寫(xiě)入第一個(gè)日志文件的最大長(zhǎng)度(默認(rèn)設(shè)置是5MB)。這個(gè)長(zhǎng)度必須以MB(兆字節(jié))或GB(千兆字節(jié))為單位進(jìn)行設(shè)置。
innodb_flush_log_at_trx_commit = 0/1/2  這個(gè)選項(xiàng)決定著什么時(shí)候把日志信息寫(xiě)入日志文件以及什么時(shí)候把這些文件物理地寫(xiě)(術(shù)語(yǔ)稱為"同步")到硬盤(pán)上。
    設(shè)置值0的意思是每隔一秒寫(xiě)一次日志并進(jìn)行同步,這可以減少硬盤(pán)寫(xiě)操作次數(shù),但可能造成數(shù)據(jù)丟失; 設(shè)置值1(設(shè)置設(shè)置)的意思是在每執(zhí)行完一條COMMIT
    命令就寫(xiě)一次日志并進(jìn)行同步,這可以防止數(shù)據(jù)丟失,但硬盤(pán)寫(xiě)操作可能會(huì)很頻繁; 設(shè)置值2是一般折衷的辦法,即每執(zhí)行完一條COMMIT命令寫(xiě)一次日志,
    每隔一秒進(jìn)行一次同步。
innodb_flush_method = x  InnoDB日志文件的同步辦法(僅適用于UNIX/Linux系統(tǒng))。這個(gè)選項(xiàng)的可取值有兩種: fdatasync,用fsync()函數(shù)進(jìn)行同步; O_DSYNC,
    用O_SYNC()函數(shù)進(jìn)行同步。
innodb_log_archive = 1  啟用InnoDB驅(qū)動(dòng)程序的archive(檔案)日志功能,把日志信息寫(xiě)入ib_arch_log_n文件。啟用這種日志功能在InnoDB與MySQL一起使用時(shí)沒(méi)有
    多大意義(啟用MySQL服務(wù)器的二進(jìn)制日志功能就足夠用了)。

mysqld程序--InnoDB--緩存區(qū)的設(shè)置和優(yōu)化
innodb_log_buffer_pool_size = n  為InnoDB數(shù)據(jù)表及其索引而保留的RAM內(nèi)存量(默認(rèn)設(shè)置是8MB)。這個(gè)參數(shù)對(duì)速度有著相當(dāng)大的影響,如果計(jì)算機(jī)上只運(yùn)行有
    MySQL/InnoDB數(shù)據(jù)庫(kù)服務(wù)器,就應(yīng)該把全部?jī)?nèi)存的80%用于這個(gè)用途。
innodb_log_buffer_size = n  事務(wù)日志文件寫(xiě)操作緩存區(qū)的最大長(zhǎng)度(默認(rèn)設(shè)置是1MB)。
innodb_additional_men_pool_size = n  為用于內(nèi)部管理的各種數(shù)據(jù)結(jié)構(gòu)分配的緩存區(qū)最大長(zhǎng)度(默認(rèn)設(shè)置是1MB)。
innodb_file_io_threads = n  I/O操作(硬盤(pán)寫(xiě)操作)的最大線程個(gè)數(shù)(默認(rèn)設(shè)置是4)。
innodb_thread_concurrency = n  InnoDB驅(qū)動(dòng)程序能夠同時(shí)使用的最大線程個(gè)數(shù)(默認(rèn)設(shè)置是8)。

mysqld程序--其它選項(xiàng)
bind-address = ipaddr  MySQL服務(wù)器的IP地址。如果MySQL服務(wù)器所在的計(jì)算機(jī)有多個(gè)IP地址,這個(gè)選項(xiàng)將非常重要。
default-storage-engine = type  新數(shù)據(jù)表的默認(rèn)數(shù)據(jù)表類型(默認(rèn)設(shè)置是MyISAM)。這項(xiàng)設(shè)置還可以通過(guò)--default-table-type選項(xiàng)來(lái)設(shè)置。
default-timezone = name  為MySQL服務(wù)器設(shè)置一個(gè)地理時(shí)區(qū)(如果它與本地計(jì)算機(jī)的地理時(shí)區(qū)不一樣)。
ft_min_word_len = n  全文索引的最小單詞長(zhǎng)度工。這個(gè)選項(xiàng)的默認(rèn)設(shè)置是4,意思是在創(chuàng)建全文索引時(shí)不考慮那些由3個(gè)或更少的字符構(gòu)建單詞。
Max-allowed-packet = n  客戶與服務(wù)器之間交換的數(shù)據(jù)包的最大長(zhǎng)度,這個(gè)數(shù)字至少應(yīng)該大于客戶程序?qū)⒁幚淼淖畲驜LOB塊的長(zhǎng)度。這個(gè)選項(xiàng)的默認(rèn)設(shè)置是1MB。
Sql-mode = model1, mode2, ...  MySQL將運(yùn)行在哪一種SQL模式下。這個(gè)選項(xiàng)的作用是讓MySQL與其他的數(shù)據(jù)庫(kù)系統(tǒng)保持最大程度的兼容。這個(gè)選項(xiàng)的可取值包括
    ansi、db2、oracle、no_zero_date、pipes_as_concat。

注意:如果在配置文件里給出的某個(gè)選項(xiàng)是mysqld無(wú)法識(shí)別的(如,因?yàn)榉噶艘粋€(gè)愚蠢的打字錯(cuò)誤),MySQL服務(wù)器將不啟動(dòng)。



Sha Jiang 2007-05-23 09:26 發(fā)表評(píng)論
]]>
Apache2+MySQL5+PHP5安裝(原)http://m.tkk7.com/jiangshachina/archive/2007/01/02/91369.htmlSha JiangSha JiangTue, 02 Jan 2007 05:48:00 GMThttp://m.tkk7.com/jiangshachina/archive/2007/01/02/91369.htmlhttp://m.tkk7.com/jiangshachina/comments/91369.htmlhttp://m.tkk7.com/jiangshachina/archive/2007/01/02/91369.html#Feedback2http://m.tkk7.com/jiangshachina/comments/commentRss/91369.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/91369.html 在Linux上安裝Apache2+MySQL5+PHP5
最近由于工作原因,在RedHat AS 4.0上安裝了Apache2+MySQL5+PHP5。現(xiàn)將安裝使用的命令記錄,以備日后查詢,也希望對(duì)其他朋友有幫助。(2007.10.17最后更新)
    使用Apache2.0.59,MySQL5.0.16和PHP5.1.4的源代碼包進(jìn)行安裝。假設(shè)這三源代碼安裝包已經(jīng)解壓,且路徑分別為:/home/jiang/tools/httpd-2.0.59
/home/jiang/tools/mysql-5.0.16 /home/jiang/tools/php-5.1.4。而且它們的安裝目標(biāo)路徑分別為:/usr/local/apache2/usr/local/mysql5/usr/local/php5
1. 安裝Apache2
進(jìn)入
/home/jiang/tools/httpd-2.0.59目錄,執(zhí)行如下命令:
#./configure
--prefix=
/usr/local/apache2  -- 設(shè)置Apache安裝目標(biāo)目錄
--enable-so
--enable-vhost-alias
--enable-rewrite
--enable-deflate
--with-mpm=worker
#make
#make install

編輯文件/usr/local/apache2/conf/httpd.conf:
[1]查找元素DocumentRoot,它的值默認(rèn)為/usr/local/apache2/htdocs
[2]查找元素DirectoryIndex,在這一項(xiàng)可以添加實(shí)際應(yīng)用中需要的首頁(yè)文件名

啟動(dòng)/關(guān)閉Apache服務(wù)器:
進(jìn)入/usr/local/apache2/bin目錄,執(zhí)行命令./apachectl start(啟動(dòng)服務(wù)器)或./apachectl stop(關(guān)閉服務(wù)器)。

2. 安裝MySQL5
#
groupadd mysql  -- 添加組mysql
#
useradd -g mysql mysql  -- 添加用戶mysql,并將它放入組mysql中
進(jìn)入
/home/jiang/tools/mysql-5.0.16目錄,執(zhí)行如下命令:
#./configure
--prefix=/path_to_mysql5  -- 設(shè)置MySQL安裝目標(biāo)目錄
--with-charset=utf8  -- 設(shè)置默認(rèn)字符集為utf8
#make
#make install
#./scripts/mysql_install_db  -- 初始化MySQL數(shù)據(jù)庫(kù)
進(jìn)入/usr/local目錄,執(zhí)行如下命令:
#chown -R mysql.mysql mysql5 -- 將/usr/local/mysql5目錄及其子目錄的屬主賦予mysql用戶

/home/jiang/tools/mysql-5.0.16/support-files
目錄 中選擇一個(gè)合適的.cnf文件放入/etc目錄中,并將文件修改為my.cnf。然后編輯該文件,使它更能切合實(shí)際的應(yīng)用。

啟動(dòng)/關(guān)閉服務(wù)器:
進(jìn)入/usr/local/mysql5/bin目錄,執(zhí)行命令./mysqld_safe -u mysql(用mysql用戶啟動(dòng)服務(wù)器)或./mysqladmin -uroot shutdown(關(guān)閉服務(wù)器)。

3. 安裝PHP5
進(jìn)入/home/jiang/tools/php-5.1.4目錄,執(zhí)行如下命令:
#./configure
--prefix=/usr/local/php5
--enable-mbstring  -- 根據(jù)應(yīng)用的需要,添加mbstring模塊
--with-apxs2=/usr/local/apache2/bin/apxs
--with-apache2=/home/jiang/tools/httpd-2.0.59
--with-png
--with-zlib
--with-config-file-path=/usr/local/php5/lib
--with-mysql=/usr/local/mysql5
--with-mysqli=/home/jiang/tools/mysql-5.0.16/scripts/mysql_config  -- 根據(jù)應(yīng)用的需要,添加mysqli模塊

#make
#make install

/home/jiang/tools/php-5.1.4/php.ini-recommended文件放入/usr/local/php5/lib目錄中,并將文件名修改為php.ini
查看/usr/local/php5/lib/php.ini文件,看參數(shù)short_open_tag的值是否為On。如果是Off,請(qǐng)修改為On

查看/usr/local/apache2/conf/httpd.conf文件,看是否存在語(yǔ)句:
LoadModule php5_module        modules/libphp5.so
如果存在,即說(shuō)明apache已經(jīng)成功加載了php模塊;
并添加如下兩條語(yǔ)句(否則PHP頁(yè)面可能無(wú)法被解析):
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps


Sha Jiang 2007-01-02 13:48 發(fā)表評(píng)論
]]>
Maven入門(mén)--較復(fù)雜的實(shí)例(原)http://m.tkk7.com/jiangshachina/archive/2006/12/12/79093.htmlSha JiangSha JiangTue, 12 Dec 2006 10:03:00 GMThttp://m.tkk7.com/jiangshachina/archive/2006/12/12/79093.htmlhttp://m.tkk7.com/jiangshachina/comments/79093.htmlhttp://m.tkk7.com/jiangshachina/archive/2006/12/12/79093.html#Feedback21http://m.tkk7.com/jiangshachina/comments/commentRss/79093.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/79093.htmlMaven入門(mén)--較復(fù)雜的實(shí)例
本文將使用一個(gè)較復(fù)雜的實(shí)例,講述如何定制目錄布局(即不使用Maven標(biāo)準(zhǔn)目錄布局),以及講述一些關(guān)鍵插件的使用(配置)。為了方便其它朋友能夠方便地使用該實(shí)例,后臺(tái)數(shù)據(jù)庫(kù)使用開(kāi)源的面向?qū)ο髷?shù)據(jù)庫(kù)--db4o,該數(shù)據(jù)庫(kù)無(wú)需安裝,已包含在與本文配套的實(shí)例中,文末附有該實(shí)例的下載鏈接。(2007.01.02最后更新)
注:轉(zhuǎn)載時(shí)請(qǐng)注明原作者(jiangshachina)及出處(http://m.tkk7.com/jiangshachina)!

1 實(shí)例的構(gòu)想
文章開(kāi)頭的摘要已經(jīng)講述了,本文仍然將以一個(gè)實(shí)例描述如何使用Maven,
該實(shí)例將使用非Maven標(biāo)準(zhǔn)的目錄結(jié)構(gòu),并將呈現(xiàn)一些關(guān)鍵的Maven插件的配置與應(yīng)用。 該實(shí)例是一個(gè)基于db4o的數(shù)據(jù)庫(kù)Web應(yīng)用。該應(yīng)用本身十分簡(jiǎn)單,即從db4o數(shù)據(jù)庫(kù)中查詢出若干記錄并將它們顯現(xiàn)在Web頁(yè)面中。
    該實(shí)例仍然由一個(gè)普通應(yīng)用工程(demo-app)與一個(gè)Web應(yīng)用工程(demo-web),以及這兩個(gè)工程的父工程(demo)構(gòu)成,最終的目標(biāo)是將Web應(yīng)用工程制作成war文件,并部署到JBoss服務(wù)器中。啟動(dòng)服務(wù)器后,能夠在頁(yè)面中看到正確的查詢結(jié)果。
    該實(shí)例使用Eclipse3.2 + JDK1.5.0_10 + Windows2000開(kāi)發(fā)。當(dāng)然這僅僅只是我個(gè)人的開(kāi)發(fā)平臺(tái),但該實(shí)例并不受限于此平臺(tái);由于我選擇使用db4o針對(duì)JDK1.5的產(chǎn)品包,所以該實(shí)例只能運(yùn)行在JDK1.5.0或更高版本的JDK/JRE中; 該工程中的所有文件都使用UTF-8編碼方式。

2 demo工程
demo工程是其它兩個(gè)工程的父工程,它的主要職責(zé)是預(yù)定義子工程所需要依賴的jar文件(artifact),以及針對(duì)子工程所使用的插件進(jìn)行通用配置。該工程完整的POM文件如下所示:
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>mvn.demo</groupId>
    <artifactId>demo</artifactId>
    <packaging>pom</packaging>
    <version>
1.0-SNAPSHOT</version>
    <description>Maven Demo Project</description>

    <modules>
        <module>demo-app</module>
        <module>demo-web</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>mvn.demo</groupId>
                <artifactId>demo-app</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>mvn.demo</groupId>
                <artifactId>demo-web</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.db4o</groupId>
                <artifactId>db4o-java5</artifactId>
                <version>
5.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>
2.4</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-configuration</groupId>
                <artifactId>commons-configuration</artifactId>
                <version>
1.2</version>
                <exclusions>
                    <exclusion>
                        <groupId>dom4j</groupId>
                        <artifactId>dom4j</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>xml-apis</groupId>
                        <artifactId>xml-apis</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>xalan</groupId>
                        <artifactId>xalan</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>xerces</groupId>
                        <artifactId>xercesImpl</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
        <groupId>junit</groupId>
         <artifactId>junit</artifactId>
           <version>
3.8.1</version>
      <scope>test</scope>
    </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-
8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>
1.5</source>
                    <target>
1.5</target>
                    <encoding>UTF-
8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                    <charset>UTF16</charset>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
    預(yù)定義工程的依賴關(guān)系,就是把會(huì)被子工程依賴的artifact的詳細(xì)信息(groupId,artifactId,version,...)先聲明到<dependencyManagement>中。然后子工程只需要聲明使用某個(gè)artifact就可以了,即那時(shí)只需要設(shè)置groupId和artifactId(甚至更少)就可以了。
<dependencyManagement>中聲明的artifact并不一定真的會(huì)被使用到
2.1 聲明依賴關(guān)系
    根據(jù)實(shí)際情況,
該實(shí)例 需要使用db4o針對(duì)java5的產(chǎn)品包(jar文件)。由于該jar文件并不存在于Maven的中央倉(cāng)庫(kù)中,所以我們不能直接通過(guò)Maven獲得該jar文件。我們只能另外下載db4o-5.5(Java版)的壓縮包,然后從壓縮包內(nèi)獲得db4o-java5.jar。得到該jar后,必須先將它安裝到Maven的本地倉(cāng)庫(kù)中(安裝方法參見(jiàn)資源[1],主題"向本地倉(cāng)庫(kù)安裝文件時(shí)要生成POM文件"),以備后面的使用。此處將該artifact的groupId定義為com.db4o,artifactId定義為db4o-java5,version自然就是5.5了(請(qǐng)見(jiàn)上述POM腳本)。
    由于該實(shí)例最終是一個(gè)Web應(yīng)用,所以它至少需要依賴Servlet的包(servlet-api-2.4.jar),還需要commons-configuration-1.2.jar。這兩個(gè)artifact都已經(jīng)存在于Maven中央倉(cāng)庫(kù)中,所以我查找到它們后,按照Maven中央倉(cāng)庫(kù)的命名將它們聲明到了<dependencyManagement>中(請(qǐng)見(jiàn)上述POM腳本)。junit是進(jìn)行單元測(cè)試時(shí)使用的artifact,(假設(shè))它肯定會(huì)被每個(gè)工程使用,所以沒(méi)有將它設(shè)置到 <dependencyManagement>中,而直接設(shè)置到了 <dependency>中。
    細(xì)心的朋友肯定已經(jīng)發(fā)現(xiàn)了,針對(duì) commons-configuration的依賴聲明處多了一些語(yǔ)句。從表面上看,應(yīng)該是排除了4個(gè)artifact(dom4j, xml-apis xalan xerces )。不錯(cuò),就是排除了這4個(gè)jar文件(artifact)。如果有興趣的話,可以將整個(gè)<exclusions>元素刪除,然后再嘗試一下制作war文件。你會(huì)發(fā)現(xiàn)在WEB-INF/lib目錄下存在著這4個(gè)artifact對(duì)應(yīng)的jar文件。那我為什么要將它們“排除”呢?因?yàn)椋鼈兪嵌嘤嗟模〖矗鼈儗?duì)于我的這個(gè)Web應(yīng)用來(lái)說(shuō),根本就是無(wú)用的!
    Maven2加入了一個(gè)很好的特性:自動(dòng)加載“依賴的依賴(Transitive Dependency)”。以commons-configuration為例。為了能夠讓它運(yùn)行正常,我們實(shí)際上還需要其它一些jar(artifact),如commons-collections,commons-lang,...。但這些artifact我都沒(méi)有“顯示”地聲明需要依賴它們,但Maven會(huì)自動(dòng)加載,因?yàn)?/font> commons-configuration的POM文件將它們聲明為了dependency
    既然那個(gè)4個(gè)artifact是commons-configuration的依賴,為什么會(huì)認(rèn)為它們是無(wú)用的呢?實(shí)際上,它們就不應(yīng)該被聲明到commons-configuration的依賴關(guān)系中。這是commons-configuration開(kāi)發(fā)者的失誤,他們沒(méi)有將依賴關(guān)系整理清晰,而將一些確實(shí)既不是runtime,更不是compile-time需要的artifact放入到了依賴關(guān)系中。在Maven中央倉(cāng)庫(kù)中存在著很多這種情況,所以我們有時(shí)需要弄清楚“哪些文件是我們真正需要的,哪些是可以被清除的”。但有時(shí)候,很難做到一個(gè)不漏。正是由于這一原因,自動(dòng)加載Transitive Dependency這一極好的特性,有時(shí)讓人十分無(wú)奈 ^_^
2.2 對(duì)插件進(jìn)行基本配置
我們可以把對(duì)插件的全局性(如針對(duì)整個(gè)項(xiàng)目的)設(shè)置放到較高層次的POM文件中,因?yàn)樗鼈儽辉O(shè)置后,子工程們就會(huì)自然遵守它們,而且可以使每個(gè)子工程的情況都是一樣的。
    在第1節(jié)中,已經(jīng)表明該工程使用JDK1.5平臺(tái),并且所有文件都使用UTF-8
的編碼方式。而Maven默認(rèn)使用JDK1.3級(jí)別的javac編譯器;默認(rèn)使用本地編碼方式(簡(jiǎn)體中文Windows操作系統(tǒng)默認(rèn)使用GBK編碼方式)處理文件。這樣就必須對(duì)Maven進(jìn)行適當(dāng)設(shè)置,以滿足工程的實(shí)際需要。
    針對(duì)資源文件的處理,Maven使用maven-resources-plugin插件,需要將它的編碼方式設(shè)置為UTF-8。編譯Java源文件,是使用maven-compiler-plugin插件,需要將它的source(Java源文件)與target(class文件)的級(jí)別都設(shè)置為1.5,另外還要將它的encoding方式設(shè)置為UTF-8。(詳細(xì)設(shè)置請(qǐng)見(jiàn)POM腳本)

3 demo-app工程
demo-app工程是一個(gè)普通應(yīng)用程序工程,它用于處理和數(shù)據(jù)庫(kù)相關(guān)的操作,如針對(duì)數(shù)據(jù)庫(kù)的增、刪、改、查等基本功能。該工程POM文件的主要內(nèi)容如下所示:
<project>
    ......

    <build>
        <finalName>app</finalName>
        <directory>target</directory>

        <sourceDirectory>src/java</sourceDirectory>
        <outputDirectory>target/classes</outputDirectory>
        <resources>
            <resource>
                <directory>src/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </resource>
        </resources>

        <testSourceDirectory>src/test/java</testSourceDirectory>
        <testOutputDirectory>target/test-classes</testOutputDirectory>
        <testResources>
            <testResource>
                <directory>src/test/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                </excludes>
            </testResource>
        </testResources>
    </build>
</project>
    文章的開(kāi)頭已經(jīng)提到,本實(shí)例將會(huì)使用定制的目錄結(jié)構(gòu),但在前面卻一字不提此事,現(xiàn)在將描述如何定制目錄結(jié)構(gòu)。Maven的標(biāo)準(zhǔn)目錄結(jié)構(gòu)其實(shí)是在Super POM中設(shè)置的,由于任何POM都會(huì)繼承該P(yáng)OM,所以所有的工作都會(huì)默認(rèn)使用標(biāo)準(zhǔn)目錄結(jié)構(gòu)。要定制目錄,其實(shí)就是需要重新設(shè)置相關(guān)參數(shù)的值,即用新值覆蓋Super POM中的值。
[1]<finalName>,該元素指定了工程輸出的artifact的名稱,默認(rèn)值為${artifactId}-${version},此處修改為app。
[2]<directory>,該元素指定了工程輸出的目標(biāo)目錄。默認(rèn)值為target,此處未修改變。
[3]<sourceDirectory>,該元素指定了Java源文件所在的目錄。默認(rèn)值為src/main/java,此處修改為src/java。
[4]<outputDirectory>,該元素指定了編譯后的class文件的放置目錄。默認(rèn)值為target/classes,此處未作改變。
[5]<resources> <resource>,該元素指定了Java源文件使用的資源文件的存放目錄。默認(rèn)值為src/main/resources,此處修改為src/java。由于在編碼Java源文件時(shí),Maven會(huì)將資源路徑中的文件全部拷貝到classes目錄。而此時(shí)將Java資源文件目錄與Java源文件目錄,設(shè)置為同一目錄,所以需要將.java文件排除在資源文件的范疇之外( <exclude>**/*.java</exclude> )。
[6]
<testSourceDirectory>,該元素指定了單元測(cè)試Java源文件的放置目錄。默認(rèn)值為src/test/java,此處未作修改。
[7]
<testOutputDirectory>,該元素指定了單元測(cè)試Java源文件編譯后的class文件放置目錄。默認(rèn)值為 target/test-classes,此處未作改變。
[8]
<testResources> <testResource>,該元素指定了單元測(cè)試Java源文件所使用的資源文件的放置目錄。默認(rèn)值為src/test/resources,此處修改為 src/test/java。并且也做了與 設(shè)置<resources> <resource>時(shí)相同的處理(排除Java源文件)。
    通過(guò)上述設(shè)置后,就可以擁有一個(gè)定制的Maven工程目錄結(jié)構(gòu)了。

4 demo-web工程
demo-web工程是整個(gè)應(yīng)用最終的目標(biāo)輸出,因?yàn)榇颂幍哪康木褪侵谱饕粋€(gè)war文件,然后將它部署到JBoss服務(wù)器中。與demo-app工程相比,demo-web工程的POM文件主要有如下不同內(nèi)容:
<project >
    ......
    <build>
        ......
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>
2.0.1 </version>
                <configuration>
                    <webappDirectory>target/${artifactId}</webappDirectory>
                    <warSourceDirectory>src/webapp</warSourceDirectory>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jboss-maven-plugin</artifactId>
                <version>
1.3.1 </version>
                <configuration>
                    <jbossHome>E:/jboss-
4.0.2 </jbossHome>
                    <serverName>default</serverName>
                    <fileName>
                        ${project.build.directory}/${project.build.finalName}.${project.packaging}
                    </fileName>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
可以看出不同之處就在于對(duì)maven-war-plguin及jboss-maven-plugin插件的配置與使用。
    Maven使用maven-war-plugin插件對(duì)Web工程制作war文件。由于本文使用了定制目錄結(jié)構(gòu),這樣則會(huì)使maven-war-plugin無(wú)法找到Web工程的Web Root目錄(默認(rèn)是src/main/webapp),所以需要對(duì)該插件進(jìn)行適當(dāng)?shù)嘏渲谩?lt;warSourceDirectory>就是Web工程的Web Root目錄,此處設(shè)置為;<webappDirectory>是制作war文件之前,相當(dāng)于是一個(gè)被打開(kāi)(exploded)的war文件的根目錄(默認(rèn)是target/artifactId-version)。
    該工程的腳本中,還使用了一個(gè)JBoss插件。該插件可以將制作好的war文件部署(實(shí)質(zhì)上是拷貝)到指定的JBoss部署目錄中。<jbossHome>是JBoss的安裝根目錄,<serverName>指JBoss Server的名稱,<fileName>是被部署war文件的名稱。

參考資源
[1]Maven入門(mén)--概念與實(shí)例. http://m.tkk7.com/jiangshachina/archive/2006/09/01/67080.html
[2]Maven + Continuum Weed. http://m.tkk7.com/jiangshachina/archive/2006/09/11/68944.aspx
[3]Maven POM Reference. http://maven.apache.org/pom.html
[3]db4o. http://www.db4objects.com
本文實(shí)例下載地址--http://m.tkk7.com/files/jiangshachina/mvn-demo.rar



]]>
Oracle Weed(原)http://m.tkk7.com/jiangshachina/archive/2006/08/12/63121.htmlSha JiangSha JiangSat, 12 Aug 2006 01:22:00 GMThttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63121.htmlhttp://m.tkk7.com/jiangshachina/comments/63121.htmlhttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63121.html#Feedback0http://m.tkk7.com/jiangshachina/comments/commentRss/63121.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/63121.html閱讀全文

Sha Jiang 2006-08-12 09:22 發(fā)表評(píng)論
]]>
MySQL Weed(原)http://m.tkk7.com/jiangshachina/archive/2006/08/12/63120.htmlSha JiangSha JiangSat, 12 Aug 2006 01:19:00 GMThttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63120.htmlhttp://m.tkk7.com/jiangshachina/comments/63120.htmlhttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63120.html#Feedback0http://m.tkk7.com/jiangshachina/comments/commentRss/63120.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/63120.html閱讀全文

Sha Jiang 2006-08-12 09:19 發(fā)表評(píng)論
]]>
在Linux上安裝MySQL Server 5.0(原)http://m.tkk7.com/jiangshachina/archive/2006/08/12/63117.htmlSha JiangSha JiangSat, 12 Aug 2006 01:10:00 GMThttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63117.htmlhttp://m.tkk7.com/jiangshachina/comments/63117.htmlhttp://m.tkk7.com/jiangshachina/archive/2006/08/12/63117.html#Feedback0http://m.tkk7.com/jiangshachina/comments/commentRss/63117.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/63117.html閱讀全文

Sha Jiang 2006-08-12 09:10 發(fā)表評(píng)論
]]>
在Linux上安裝Oracle10g(原)http://m.tkk7.com/jiangshachina/archive/2006/08/11/63050.htmlSha JiangSha JiangFri, 11 Aug 2006 09:06:00 GMThttp://m.tkk7.com/jiangshachina/archive/2006/08/11/63050.htmlhttp://m.tkk7.com/jiangshachina/comments/63050.htmlhttp://m.tkk7.com/jiangshachina/archive/2006/08/11/63050.html#Feedback0http://m.tkk7.com/jiangshachina/comments/commentRss/63050.htmlhttp://m.tkk7.com/jiangshachina/services/trackbacks/63050.html 其實(shí)我對(duì)Linux和Oracle都不熟悉,在實(shí)際的安裝過(guò)程中,還有許多不明白的地方,經(jīng)常是“知其然,而不知其所以然”。如,為什么要配置kernel參數(shù)?相關(guān)kernel參數(shù)分別有什么作用?設(shè)置臨時(shí)交換空間所用的命令dd的功能是什么?......希望有朋友能夠針對(duì)其中的問(wèn)題進(jìn)行解答。如果文中有什么錯(cuò)誤,也請(qǐng)大家指正。
  閱讀全文

Sha Jiang 2006-08-11 17:06 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 天堂在线免费观看中文版| 午夜男人一级毛片免费| 国产亚洲一区二区三区在线不卡 | 在线观看免费高清视频| 亚洲同性男gay网站在线观看| 午夜免费福利片观看| 亚洲AV无码1区2区久久| 国产成人精品免费久久久久| 亚洲精选在线观看| 无码专区AAAAAA免费视频| 久久久久久a亚洲欧洲AV| 91久久青青草原线免费| 亚洲一区免费在线观看| 最近中文字幕免费mv视频7| 亚洲AV无码一区二区三区久久精品 | 国产精品成人免费综合| 亚洲av色香蕉一区二区三区| 国产91在线免费| 男人和女人高潮免费网站| 伊人久久精品亚洲午夜| 久久久99精品免费观看| 亚洲第一页在线视频| 女人让男人免费桶爽30分钟| 亚洲爆乳成av人在线视菜奈实| 国产美女无遮挡免费网站| 有码人妻在线免费看片| 亚洲人成色777777在线观看| 日韩精品极品视频在线观看免费| 亚洲中文字幕在线无码一区二区| 国产在线观看免费不卡| A级毛片成人网站免费看| 亚洲精品资源在线| 国产在线不卡免费播放| 中文永久免费观看网站| 亚洲国产精品成人综合久久久| 免费观看的av毛片的网站| 中文字幕永久免费| 久久综合久久综合亚洲| 亚洲日本va午夜中文字幕久久| 2015日韩永久免费视频播放| 亚洲国产成人无码AV在线影院|