国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 數(shù)據(jù)庫(kù) > SQL Server > 正文

使用 Microsoft SQL Server 2000 的全文搜索功能構(gòu)建 Web 搜索應(yīng)用程序

2024-08-31 00:48:00
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

使用 microsoft sql server 2000 的全文搜索功能構(gòu)建 web 搜索應(yīng)用程序 andrew b. cencinimicrosoft corporation 2002年12月 適用于:    microsoft® sql™ server 2000摘要:學(xué)習(xí)如何充分利用 sql server 2000 的全文搜索功能。本文包含有關(guān)實(shí)現(xiàn)最大吞吐率和最佳性能的幾點(diǎn)提示和技巧。 目錄簡(jiǎn)介 全文搜索功能簡(jiǎn)介 配置全文搜索功能 全文查詢(xún) 排位和優(yōu)化 其他性能技巧 小結(jié) 附錄 a:實(shí)現(xiàn)全文搜索功能的最佳選擇 附錄 b:使用最佳選擇、結(jié)果分頁(yè)和有效全文查詢(xún)邏輯的示例應(yīng)用程序 附錄 c:資源 簡(jiǎn)介使用 microsoft® sql™ server 2000 的全文搜索功能,可以對(duì)在非結(jié)構(gòu)化文本數(shù)據(jù)上生成的索引執(zhí)行快速、靈活的查詢(xún)。常用的全文搜索工具是網(wǎng)站的搜索引擎。為了幫助讀者理解全文搜索功能的最佳使用方法,本文介紹了大量抽象概念;并對(duì)優(yōu)化全文索引和查詢(xún)以實(shí)現(xiàn)最大吞吐率和最佳性能,提供了幾點(diǎn)提示和技巧。全文搜索功能簡(jiǎn)介全文搜索功能在 sql server 7.0 中引入。全文搜索的核心引擎建立在 microsoft search (mssearch) 技術(shù)上,microsoft exchange 和 microsoft sharepoint™ portal server 等產(chǎn)品中也采用了此項(xiàng)技術(shù)。sql server 7.0 全文搜索中公開(kāi)的功能可提供基本的文本搜索功能,并使用早期版本的 mssearch;而 sql server 2000 的全文搜索實(shí)現(xiàn)則包含一組可靠的索引和查詢(xún)功能,并在 sql server 7.0 的基礎(chǔ)之上添加了幾項(xiàng)增強(qiáng)功能。這些增強(qiáng)功能包括:通過(guò) microsoft 群集服務(wù)完全支持群集操作,能夠過(guò)濾和索引 image 列中存儲(chǔ)的文檔,提供改進(jìn)的語(yǔ)言支持,以及在性能、可縮放性和可靠性方面進(jìn)行了改進(jìn)。mssearch 生成、維護(hù)和查詢(xún)文件系統(tǒng)中(而不是 sql server 中)存儲(chǔ)的全文索引。mssearch 進(jìn)行全文索引時(shí)使用的邏輯和物理存儲(chǔ)單元是目錄。全文目錄在每個(gè)數(shù)據(jù)庫(kù)中包含一個(gè)或多個(gè)全文索引 - 可以為 sql server 中的每個(gè)表創(chuàng)建一個(gè)全文索引,且索引中可以包含該表中的一列或多列。每個(gè)表只能屬于一個(gè)目錄,且每個(gè)表只能創(chuàng)建一個(gè)索引。我們將簡(jiǎn)單介紹有關(guān)組織全文目錄和索引的最佳方案 - 但首先,讓我們來(lái)簡(jiǎn)單了解一下全文搜索的工作原理。配置全文搜索功能要為 sql server 中存儲(chǔ)的文本數(shù)據(jù)創(chuàng)建全文索引,應(yīng)該先完成以下幾步準(zhǔn)備工作。第一步是以全文方式啟用包含要生成索引的文本數(shù)據(jù)的數(shù)據(jù)庫(kù)(如果您尚未執(zhí)行此操作)。注意:執(zhí)行以下語(yǔ)句將丟棄并重新創(chuàng)建屬于要啟用全文搜索的數(shù)據(jù)庫(kù)的所有全文目錄。除非要重新創(chuàng)建全文目錄,否則請(qǐng)確保在要啟用的特定數(shù)據(jù)庫(kù)中未創(chuàng)建任何全文目錄。如果您是 sysadmin 角色的成員或此數(shù)據(jù)庫(kù)的 db_owner,可以繼續(xù)進(jìn)行并發(fā)出以下語(yǔ)句:use northwind exec sp_fulltext_database 'enable'

接下來(lái),您需要?jiǎng)?chuàng)建全文目錄,以存儲(chǔ)全文索引。正如前面所提到的,此目錄中的數(shù)據(jù)存儲(chǔ)在文件系統(tǒng)中(而不是 sql server 中),因此,在考慮全文目錄的存儲(chǔ)位置時(shí)應(yīng)該仔細(xì)選擇。除非指定其他位置,否則全文目錄將存儲(chǔ)在 ftdata 目錄(位于 microsoft sql server/mssql 存儲(chǔ)位置中)的子目錄中。以下是在非默認(rèn)位置創(chuàng)建全文目錄的方法:exec sp_fulltext_catalog 'cat_desc', 'create', 'f:/ft'

在本例中,全文目錄將創(chuàng)建為“f:/ft”的子目錄,如果您查看文件系統(tǒng)的該部分,將看到它有了自己的目錄。mssearch 使用的全文目錄的命名規(guī)則是:sql+dbid+catalogid

目錄 id 從 00005 開(kāi)始,并且每新建一個(gè)目錄就遞增 1。如果可能的話(huà),最好在其所在的物理驅(qū)動(dòng)器上創(chuàng)建全文目錄。如果生成全文索引的進(jìn)程需要進(jìn)行大量的 i/o 操作(具體而言,就是從 sql server 中讀取數(shù)據(jù),然后向文件系統(tǒng)寫(xiě)入索引),則應(yīng)避免使 i/o 子系統(tǒng)成為瓶頸。那么,全文目錄有多大呢?通常情況下,全文目錄的系統(tǒng)開(kāi)銷(xiāo)比 sql server 中存儲(chǔ)的數(shù)據(jù)(對(duì)其進(jìn)行全文索引)量高出大約 30%;但是,此規(guī)則取決于數(shù)據(jù)中唯一單詞(或主鍵)的分布,以及被您視為是干擾詞的單詞的分布。干擾詞(或終止詞)是指要排除在全文索引和查詢(xún)以外的詞語(yǔ)(因?yàn)樗鼈儾皇悄信d趣的搜索詞,而且出現(xiàn)頻率很高,所以只會(huì)使索引變得很大,而不會(huì)有實(shí)際效果)。稍后,我們將介紹有關(guān)干擾詞選擇方面的注意事項(xiàng),以及如何優(yōu)化干擾詞以改善查詢(xún)性能。如果您尚未執(zhí)行此操作,請(qǐng)?jiān)诿總€(gè)要生成全文索引的表上創(chuàng)建一個(gè)唯一的單列非空索引。這個(gè)唯一索引用于將表中的每一行映射到 mssearch 內(nèi)部使用的一個(gè)唯一可壓縮主鍵。接下來(lái),您需要讓 mssearch 知道您要為表創(chuàng)建全文索引。對(duì)表發(fā)出以下語(yǔ)句可將該表添加到所選的全文目錄中(在本例中,它是我們?cè)谇懊鎰?chuàng)建的“cat_desc”):exec sp_fulltext_table 'categories', 'create', 'cat_desc',   'pk_categories'

下一步是向此全文索引添加列。您可以為每一列選擇一種語(yǔ)言,如果該列的類(lèi)型為 image,則必須再指定一列,以指示 image 列的每一行中存儲(chǔ)的文檔類(lèi)型。在列語(yǔ)言選擇方面,有一些重要但尚未成文的注意事項(xiàng)。這些注意事項(xiàng)與文本的標(biāo)記方式以及 mssearch 對(duì)文本的索引方式有關(guān)。被索引的文本是通過(guò)一個(gè)稱(chēng)作單詞分隔符(用作單詞邊界標(biāo)記)的組件提供的。在英文中,單詞分隔符通常是空格或某種形式的標(biāo)點(diǎn)符號(hào);而在其他語(yǔ)言中(例如德語(yǔ)),單詞或字符可以組合在一起;因此,所選的列語(yǔ)言應(yīng)表示要存儲(chǔ)在該列的行中的語(yǔ)言。如果不確定,最好的方法通常是使用中性單詞分隔符(只使用空格和標(biāo)點(diǎn)符號(hào)執(zhí)行標(biāo)記功能)。選擇列語(yǔ)言的另一個(gè)好處是“尋根溯源”。全文查詢(xún)中的尋根溯源是指在特定語(yǔ)言中搜索某一單詞的所有變化形式的過(guò)程。選擇語(yǔ)言的另一個(gè)考慮因素與數(shù)據(jù)的表示方法有關(guān)。對(duì)于非 image 列數(shù)據(jù)來(lái)說(shuō),不需要執(zhí)行特殊的過(guò)濾操作;而文本通常需要將單詞分隔組件按原樣傳遞。單詞分隔符主要用于處理書(shū)面文本。因此,如果文本中有任何類(lèi)型的標(biāo)記(例如 html),則在索引和搜索過(guò)程中,語(yǔ)言精確性將不會(huì)很高。這種情況下,您有兩種選擇 - 首選方法是只將文本數(shù)據(jù)存儲(chǔ)在 image 列中,并指明其文檔類(lèi)型,以便對(duì)其進(jìn)行過(guò)濾。如果不選擇此方法,則可以考慮使用中性單詞分隔符,并且可能的話(huà),在干擾詞列表中添加標(biāo)記數(shù)據(jù)(例如 html 中的“br”)。在指定了中性語(yǔ)言的列中不能進(jìn)行任何基于語(yǔ)言的尋根溯源,但有些環(huán)境可能會(huì)要求您選擇此方法。在知道列選項(xiàng)后,通過(guò)發(fā)出以下語(yǔ)句在全文索引中添加一列或兩列:exec sp_fulltext_column 'categories', 'description', 'add'

您可能注意到,此處未指定任何語(yǔ)言 - 這種情況下,將使用默認(rèn)的全文語(yǔ)言。可以通過(guò)系統(tǒng)存儲(chǔ)過(guò)程“sp_configure”為服務(wù)器設(shè)置默認(rèn)全文語(yǔ)言。將所有列添加到全文索引后,即可執(zhí)行填充操作。填充方法之多實(shí)在是不勝枚舉,此處不作詳細(xì)介紹。在本例中,只需對(duì)表啟動(dòng)完全填充,并等待它執(zhí)行完畢:exec sp_fulltext_table 'categories', 'start_full'

您可能希望使用 fulltextcatalogproperty 或 objectproperty 函數(shù)來(lái)監(jiān)視填充狀態(tài)。要獲取目錄填充狀態(tài),可以執(zhí)行:select fulltextcatalogproperty('cat_desc', 'populatestatus')

通常情況下,如果完全填充正在進(jìn)行,則返回的結(jié)果是“1”。有關(guān)如何使用 fulltextcatalogproperty 和 objectproperty 的詳細(xì)信息,請(qǐng)參閱 sql server books online。全文查詢(xún)查詢(xún)?nèi)乃饕c執(zhí)行 sql server 中的標(biāo)準(zhǔn)關(guān)系型查詢(xún)略有不同。由于索引是在 sql server 外部進(jìn)行存儲(chǔ)和管理的,因此全文查詢(xún)處理大部分由 mssearch 完成(因此,那些一部分是關(guān)系型、一部分基于全文的查詢(xún)將被單獨(dú)處理),這樣做有時(shí)會(huì)損害性能。從本質(zhì)上說(shuō),執(zhí)行全文查詢(xún)時(shí),查詢(xún)?cè)~傳遞給 mssearch,后者遍歷其內(nèi)部數(shù)據(jù)結(jié)構(gòu)(索引),并向 sql server 返回主鍵和排位值。如果執(zhí)行 contains 或 freetext 查詢(xún),則通常看不到主鍵或排位值,但如果執(zhí)行 containstable 或 freetexttable 查詢(xún),則將獲得這些值,然后這些值通常會(huì)與基表合并在一起。與基表合并主鍵的進(jìn)程需要很高的系統(tǒng)開(kāi)銷(xiāo) - 稍后,我們將向您介紹一些巧妙的方法以盡量減少或完全避免這種合并。如果您通過(guò)不斷思考,對(duì)全文查詢(xún)?nèi)绾畏祷財(cái)?shù)據(jù)有了一個(gè)初步了解,就可以推測(cè)出 contains/freetext 查詢(xún)僅執(zhí)行 containstable/freetexttable 查詢(xún)并與基表進(jìn)行合并。有了這樣的了解,您應(yīng)該避免使用這些類(lèi)型的查詢(xún),除非不這樣做的開(kāi)銷(xiāo)更高。在 web 搜索應(yīng)用程序中,使用 containstable 與 freetexttable 比使用不帶 table 的同類(lèi)函數(shù)好得多。到現(xiàn)在為止,您已經(jīng)知道全文查詢(xún)是用來(lái)從 sql server 之外存儲(chǔ)的 mssearch 索引中訪問(wèn)數(shù)據(jù)的特殊方法,還知道如果盲目地與基表進(jìn)行合并,就會(huì)遇到麻煩。應(yīng)該了解的另外一個(gè)重要內(nèi)容是 contains 樣式查詢(xún)與 freetext 樣式查詢(xún)之間的本質(zhì)差別。contains 查詢(xún)用于對(duì)所查詢(xún)的所有詞語(yǔ)執(zhí)行完全匹配查詢(xún)。無(wú)論您只查找單個(gè)單詞,還是查找以“orange”開(kāi)頭的所有單詞,系統(tǒng)只返回包含所有搜索詞的結(jié)果。因此,contains 查詢(xún)速度很快,因?yàn)樗鼈兺ǔ7祷睾苌俚慕Y(jié)果,并且不需要執(zhí)行過(guò)多的附加處理。contains 查詢(xún)的缺點(diǎn)包括令人生厭的干擾詞過(guò)濾問(wèn)題。經(jīng)驗(yàn)豐富的開(kāi)發(fā)人員以及過(guò)去使用過(guò)全文搜索的數(shù)據(jù)庫(kù)管理員,在試圖匹配只包含單個(gè)干擾詞的單詞或詞組時(shí),曾遇到過(guò)“您的查詢(xún)只包含干擾詞”這樣令人吃驚的錯(cuò)誤。要避免收到此錯(cuò)誤,方法之一是在執(zhí)行全文查詢(xún)之前過(guò)濾出干擾詞。向包含干擾詞的 contains 查詢(xún)返回結(jié)果是不可能的,因?yàn)榇祟?lèi)查詢(xún)只返回與整個(gè)查詢(xún)字符串完全匹配的結(jié)果。由于干擾詞不是全文索引項(xiàng),因此包含干擾詞的 contains 查詢(xún)不會(huì)返回任何行。freetext 查詢(xún)消除了 contains 查詢(xún)中偶爾出現(xiàn)的所有警告說(shuō)明。當(dāng)發(fā)出 freetext 查詢(xún)時(shí),實(shí)際上發(fā)出的是詞根查詢(xún)。因此,當(dāng)您搜索“root beer”時(shí),“root”和“beer”包含其所有形式(尋根溯源與語(yǔ)言相關(guān);所用的語(yǔ)言由生成索引時(shí)指定的全文列語(yǔ)言確定,并且在所有查詢(xún)的列中必須相同),并且系統(tǒng)將返回至少與這些詞語(yǔ)之一匹配的所有行。freetext 查詢(xún)的負(fù)面影響是它們通常比 contains 查詢(xún)耗用更多的 cpu - 因?yàn)橐獙じ菰匆约胺祷馗嗟慕Y(jié)果,就需要包含更復(fù)雜的排位計(jì)算。不過(guò),基于 freetext 的查詢(xún)非常靈活,而且速度非常快,是基于 web 的搜索應(yīng)用程序中通常使用的最佳選擇。排位和優(yōu)化我經(jīng)常遇到使用全文搜索的用戶(hù),他們問(wèn)我排位編號(hào)是什么意思,以及如何將排位編號(hào)轉(zhuǎn)換成某種用戶(hù)可以理解的值。對(duì)這個(gè)問(wèn)題,回答可長(zhǎng)可短,在這里我將進(jìn)行簡(jiǎn)要回答。簡(jiǎn)單而言,這些排位編號(hào)不如結(jié)果返回的順序那樣重要。也就是說(shuō),當(dāng)您按照排位對(duì)結(jié)果進(jìn)行排序時(shí),總是首先返回關(guān)聯(lián)程度最高的結(jié)果。排位值本身常常變化 - 全文搜索使用概率排位算法,即返回的每個(gè)文檔的關(guān)聯(lián)性受全文索引中的任何或所有其他文檔的直接影響。有些人認(rèn)為,一種有助于增加某些行排位的技巧是在這些行的全文索引列中重復(fù)常用的搜索關(guān)鍵字。盡管在某種程度上,這種方法可能會(huì)提高這些行因某些關(guān)鍵字而首先返回的幾率,但在其他情況下,可能會(huì)適得其反 - 而且還存在使詞語(yǔ)查詢(xún)性能降低的風(fēng)險(xiǎn)。較好的解決方案是為搜索應(yīng)用程序?qū)崿F(xiàn)“最佳選擇”系統(tǒng)(請(qǐng)參閱以下示例),這樣就可以確保首先返回某些文檔。多次重復(fù)使用關(guān)鍵字會(huì)使這些特定關(guān)鍵字的全文索引擴(kuò)大,并使得 mssearch 在查找正確行和計(jì)算排位時(shí)浪費(fèi)時(shí)間。如果全文索引數(shù)據(jù)量很大,并嘗試使用了此方法,您可能會(huì)發(fā)現(xiàn)某些全文查詢(xún)很耗時(shí)。如果能夠?qū)崿F(xiàn)更細(xì)致(也可能更精確)的“最佳選擇”系統(tǒng),您會(huì)發(fā)現(xiàn)它明顯改善了查詢(xún)性能。多次重復(fù)數(shù)據(jù)的另一個(gè)問(wèn)題與用于組合關(guān)系型查詢(xún)和全文查詢(xún)的常用技巧有關(guān)。許多使用全文搜索的用戶(hù)都深受此問(wèn)題的困擾,每當(dāng)他們?cè)噲D將某種過(guò)濾器應(yīng)用于全文查詢(xún)返回的結(jié)果時(shí),便會(huì)遇到這樣的問(wèn)題。正如前面所說(shuō)的,全文查詢(xún)?yōu)槊總€(gè)匹配行返回一個(gè)主鍵和一個(gè)排位 - 要收集有關(guān)這些行的任何詳細(xì)信息,必須與它的基表進(jìn)行合并。由于從無(wú)限制的全文查詢(xún)中可能會(huì)返回任意數(shù)量的結(jié)果,因此合并可能需要大量系統(tǒng)開(kāi)銷(xiāo)。人們發(fā)現(xiàn)避免合并的一個(gè)有效方法是只在全文索引中添加要過(guò)濾的數(shù)據(jù)(如果可能)。換句話(huà)說(shuō),如果用戶(hù)要從報(bào)紙上所有文章的正文中搜索關(guān)鍵字“ichiro”,并且只希望返回該報(bào)上體育專(zhuān)欄中的文章,則查詢(xún)語(yǔ)句通常如下所示:-- [方法 1:]-- 開(kāi)銷(xiāo)最高:先全部選擇,然后再合并和過(guò)濾select articles_tbl.author, articles_tbl.body, articles_tbl.dateline,    ft_tbl.[rank] from freetexttable(articles, body, 'ichiro') as ft_tblinner join articles as articles_tblon ft_tbl.[key] = articles_tbl.articleidwhere articles_tbl.category = 'sports'

-- [方法 2:]-- 可以使用,但會(huì)導(dǎo)致意外結(jié)果并變慢,或者會(huì)返回不準(zhǔn)確的結(jié)果: -- 執(zhí)行全文過(guò)濾,并且只提取主鍵和排位-- (處理在 web 服務(wù)器上完成)select [key], [rank] from containstable(articles, *, 'formsof(inflectional('ichiro')       and "sports"')

這兩個(gè)查詢(xún)要么不必要地占用大量系統(tǒng)開(kāi)銷(xiāo),要么存在返回錯(cuò)誤結(jié)果的可能性(在第二個(gè)查詢(xún)中,“sports”很可能出現(xiàn)在所有類(lèi)型的文章中)。這兩項(xiàng)技術(shù)還存在其他變體,但這是兩種非常簡(jiǎn)單的模型。如果可行,我通常建議您對(duì)數(shù)據(jù)進(jìn)行水平劃分。即,“類(lèi)別”列的每個(gè)可能值都自成一列(或表),并且與該文章相關(guān)的可搜索關(guān)鍵字僅存儲(chǔ)在此列中。采用此方法,而不是使用一個(gè)“正文”列和一個(gè)“類(lèi)別”列,可以去掉“類(lèi)別”列,而使用存儲(chǔ)可搜索關(guān)鍵字的“body_<category>”列。如以下示例所示:-- 如果您可以調(diào)整架構(gòu),這非常有效 ‐ 每個(gè)類(lèi)別-- 都成為自己的列(或表格),并且需要命中的-- 全文索引也較少。這明顯需要作一些解釋……select [key], [rank] from freetexttable(articles, body_sports, 'ichiro')

對(duì)于包含大量數(shù)據(jù),且這些數(shù)據(jù)可適應(yīng)此架構(gòu)(或許是主架構(gòu))更改的系統(tǒng),其性能會(huì)得到顯著的提高。但在何時(shí)應(yīng)用多個(gè)過(guò)濾器或不應(yīng)用過(guò)濾器方面卻有著明顯的限制。當(dāng)然,還有其他的方法可以解決這些問(wèn)題。通過(guò)以上示例,您會(huì)了解一種將某些搜索條件抽象到架構(gòu)的方法 - 實(shí)際上是“欺騙”優(yōu)化程序(更確切的說(shuō)是“成為”優(yōu)化程序),因?yàn)樵?sql server 本身的全文查詢(xún)中當(dāng)前不存在本地優(yōu)化。其他性能技巧人們?cè)诹奶鞎r(shí)常常問(wèn)我的另一個(gè)問(wèn)題是如何才能分頁(yè)顯示全文查詢(xún)結(jié)果。換句話(huà)說(shuō),如果我要發(fā)出“root beer”查詢(xún),一次在某一 web 頁(yè)上顯示 40 個(gè)結(jié)果,并且只希望返回該頁(yè)面上的 40 個(gè)結(jié)果(例如,如果我在第三頁(yè),我希望僅返回第 81 至第 120 條結(jié)果)。對(duì)于分頁(yè)顯示結(jié)果,我曾見(jiàn)過(guò)多種方法,但沒(méi)有一種方法能夠做到百分之百有效。我所推薦的方法可以最大程度地減少全文查詢(xún)執(zhí)行的次數(shù)(實(shí)際上,對(duì)于要分頁(yè)顯示的每個(gè)結(jié)果集只需執(zhí)行一次),并將 web 服務(wù)器用作一個(gè)簡(jiǎn)單的緩存。從更高的層面來(lái)講,您只需在全文查詢(xún)中檢索一個(gè)完整的主鍵和排位值行集合(如果需要,可以在架構(gòu)中使用最佳選擇并提取常用過(guò)濾器),并將其存儲(chǔ)在 web 服務(wù)器的內(nèi)存中(這取決于您的應(yīng)用程序和負(fù)載,想象將 <32 字節(jié)的典型主鍵大小與 <4 字節(jié)的排位大小相加 [等于 <36 字節(jié)],然后乘以通常返回的結(jié)果集 <1000 行,最后等于 <35k。假定一個(gè)在任何給定時(shí)間返回 <1000 個(gè)活動(dòng)查詢(xún)結(jié)果集中的一個(gè)活動(dòng)緩存集,您將發(fā)現(xiàn)此活動(dòng)緩存集在 web 服務(wù)器上占用的內(nèi)存少于 35mb - 這還可以接受)。為了分頁(yè)顯示結(jié)果,該進(jìn)程只遍歷 web 服務(wù)器的內(nèi)存中存儲(chǔ)的數(shù)組,并對(duì) sql server 發(fā)出 select 以便只顯示需要顯示的行和列。這又回到了全文查詢(xún)僅返回主鍵和排位的概念中 - select(甚至許多這樣的查詢(xún)語(yǔ)句)比全文查詢(xún)的速度快許多倍。使用 select 而不是與基表合并多個(gè)行,并結(jié)合多個(gè)其他策略,您可以保留 sql server 計(jì)算機(jī)上更多的 cpu 周期,并且更有效、更劃算地利用 web 領(lǐng)域。另一種可以替代 web 服務(wù)器端緩存的方法是在 sql server 自身中緩存結(jié)果集,并定義多種用于瀏覽這些結(jié)果的方法。雖然本文著重說(shuō)明 web 服務(wù)器 (asp) 級(jí)別的應(yīng)用程序設(shè)計(jì),但 sql server 的可編程功能還為生成高性能的 web 搜索應(yīng)用程序提供了強(qiáng)大的框架。小結(jié)microsoft sql server 2000 的全文搜索功能為索引和查詢(xún)數(shù)據(jù)庫(kù)中存儲(chǔ)的非結(jié)構(gòu)化文本數(shù)據(jù)提供了可靠、快速而靈活的方法。如果要廣泛地將這種快速、準(zhǔn)確的搜索功能應(yīng)用于各種應(yīng)用程序,那么很有必要充分利用其速度和精確性,來(lái)實(shí)現(xiàn)全文搜索解決方案。通過(guò)分布計(jì)算負(fù)載并通過(guò)某些巧妙的方式對(duì)數(shù)據(jù)進(jìn)行組織,可以省下錢(qián)來(lái)購(gòu)買(mǎi)其他硬件和軟件,以擺脫因不必要的緩慢查詢(xún)帶來(lái)的困擾。在開(kāi)發(fā)優(yōu)秀的搜索應(yīng)用程序時(shí),通常要考慮到許多因素和注意事項(xiàng),希望本文提供的信息和示例對(duì)您學(xué)習(xí)使用 sql server 2000 生成出色的 web 搜索應(yīng)用程序會(huì)有所幫助。附錄 a:實(shí)現(xiàn)全文搜索功能的最佳選擇改進(jìn)全文查詢(xún)性能和有效性的一種可行方法是實(shí)現(xiàn)“最佳選擇”系統(tǒng)。此系統(tǒng)是一種很簡(jiǎn)單的方法,可確保某些與特定查詢(xún)表達(dá)式匹配的行先于其他行返回。最佳選擇沒(méi)有復(fù)雜的預(yù)編程邏輯(例如,sharepoint portal server 就包含這樣的邏輯),因此,通常是首選辦法。在本示例中挑選出最佳選擇,并將唯一的主鍵和一些關(guān)鍵字存儲(chǔ)在單獨(dú)的表中。freetexttable 查詢(xún)對(duì)(非常小的)最佳選擇表執(zhí)行,并且從該查詢(xún)中返回的任何結(jié)果都與對(duì)基表的 freetexttable 查詢(xún)結(jié)果一同返回。在給定這些搜索條件下,最先返回的將是所有“最佳選擇”行,隨后是被 mssearch 視為關(guān)聯(lián)程度最高的行(以遞減順序返回)。下面是一個(gè)非常簡(jiǎn)單的用于創(chuàng)建最佳選擇系統(tǒng)的示例腳本。use mydb

create table documenttable(ftkey int not null, document ntext)create unique index dtftkey_idx on documenttable(ftkey)

/*   在此插入文檔   (要生成全文索引的所有文檔)*/

-- 為所有文檔表創(chuàng)建全文目錄和索引exec sp_fulltext_catalog 'documents_cat', 'create', 'f:/ftcats'exec sp_fulltext_table 'documenttable', 'create', 'documents_cat',       'dtftkey_idx'exec sp_fulltext_column 'documenttable', 'document', 'add'exec sp_fulltext_table 'documenttable', 'start_change_tracking'exec sp_fulltext_table 'documenttable', 'start_background_updateindex'

/*   現(xiàn)在創(chuàng)建最佳選擇表和索引   (添加應(yīng)該始終最先返回的文檔)*/create table bestbets(ftkey int not null, keywords ntext)create unique index bbftkey_idx on bestbets(ftkey)

/*   在此插入最佳選擇*/

-- 為最佳選擇表創(chuàng)建全文目錄和索引exec sp_fulltext_catalog 'bestbets_cat', 'create', 'f:/ftcats'exec sp_fulltext_table 'bestbets', 'create', 'bestbets_cat', 'bbftkey_idx'exec sp_fulltext_column 'bestbets', 'keywords', 'add'exec sp_fulltext_table 'bestbets', 'start_change_tracking'exec sp_fulltext_table 'bestbets', 'start_background_updateindex'

首先創(chuàng)建了一個(gè)通用的“所有文檔”表,用于存儲(chǔ)所有要全文索引的文檔。通常情況下,文檔表中包含其他列,但在本文中,只包含兩列 - 主鍵索引和文檔本身。全文目錄和索引是為文檔表而創(chuàng)建的。接著創(chuàng)建了“最佳選擇”表,用于存儲(chǔ)所有全文查詢(xún)中首先返回的特殊文檔。此表只需具有全文主鍵列和文檔本身(對(duì)將某些文檔作為查詢(xún)目標(biāo)的策略進(jìn)行優(yōu)化,包括在該文檔本身不包含的文檔中添加其他關(guān)鍵字)。全文目錄和索引是為最佳選擇表而創(chuàng)建的。最佳選擇表和文檔表可以共享文檔(最佳選擇文檔還存儲(chǔ)在常規(guī)文檔表中,它們共享同一個(gè)主鍵值),也可以相互排斥(最佳選擇文檔只存儲(chǔ)在最佳選擇表中)。為便于檢索,使最佳選擇表與文檔表互斥更為容易 - 這樣做就無(wú)需從最佳選擇和返回的普通搜索結(jié)果行集合中刪除共享操作。另一方面,使用此方法維護(hù)文檔可能很難實(shí)現(xiàn),因?yàn)樵诖朔椒ㄖ校诓樵?xún)中添加邏輯來(lái)刪除返回的行集合之間的共享文檔。如果給定上面的表,則可以創(chuàng)建兩個(gè)存儲(chǔ)過(guò)程,以便對(duì)最佳選擇表和文檔表進(jìn)行搜索。可使用 web 服務(wù)器級(jí)別的邏輯或其他存儲(chǔ)過(guò)程來(lái)緩存和顯示所需結(jié)果(與最佳選擇一起使用時(shí),請(qǐng)參閱下面有關(guān)緩存、顯示和分頁(yè)的一個(gè)完整、有效的示例)。首先,創(chuàng)建一個(gè)用于檢索最佳選擇行(如果有)的存儲(chǔ)過(guò)程:create procedure bbsearch @searchterm varchar(1024) as

select [key], [rank] from freetexttable(bestbets, keywords, @searchterm) order by [rank] desc

確保已對(duì)傳入搜索字符串進(jìn)行清理,以避免在服務(wù)器上隨意執(zhí)行 t-sql,并確保用單引號(hào)將該字符串括起。這種情況下,使用 freetexttable 比使用 containstable 要好,因?yàn)?freetexttable 將采用尋根溯源功能,并找到與任何搜索詞相匹配的最佳選擇。接下來(lái),第二個(gè)存儲(chǔ)過(guò)程檢索與常規(guī)搜索標(biāo)準(zhǔn)匹配的文檔(如果有):create procedure ftsearch @searchterm varchar(1024) as

select [key], [rank] from freetexttable(documenttable, keywords, @searchterm) order by [rank] desc

此外,請(qǐng)確保已清理傳入搜索字符串,并用單引號(hào)將該字符串括起。執(zhí)行這些存儲(chǔ)過(guò)程時(shí),應(yīng)該在兩個(gè)存儲(chǔ)過(guò)程中傳入相同的搜索詞,首先執(zhí)行最佳選擇搜索,然后執(zhí)行普通全文搜索。下一節(jié)更全面地介紹了在構(gòu)建 web 搜索應(yīng)用程序時(shí),如何與其他全文搜索技術(shù)一起使用最佳選擇。附錄 b:使用最佳選擇、結(jié)果分頁(yè)和有效全文查詢(xún)邏輯的示例應(yīng)用程序在本例中,我們實(shí)現(xiàn)了一個(gè)幾乎利用了本文介紹的所有優(yōu)化方案的 web 搜索應(yīng)用程序。我們對(duì)聯(lián)機(jī)零售商目錄使用簡(jiǎn)單的搜索引擎方案,并假定在通信量很高的情況下,所有用戶(hù)都期待在很短的響應(yīng)時(shí)間內(nèi)獲得結(jié)果。本示例使用了前一節(jié)中的最佳選擇表和存儲(chǔ)過(guò)程。此應(yīng)用程序只是一些可用于實(shí)現(xiàn)最佳全文搜索性能的高級(jí)策略的簡(jiǎn)單示例。本示例使用了 asp,也可使用 isapi、asp.net 或其他平臺(tái)來(lái)實(shí)現(xiàn)具有各自?xún)?yōu)缺點(diǎn)的類(lèi)似解決方案。會(huì)話(huà)對(duì)象并不一定對(duì)所有應(yīng)用程序都適用,如果使用不當(dāng),可能帶來(lái)一定程度的危險(xiǎn)。在本例中,我們使用會(huì)話(huà)對(duì)象來(lái)實(shí)現(xiàn)快速有效的緩存機(jī)制 - 當(dāng)然還有許多其他方法可以在不同程度上實(shí)現(xiàn)該功能。下面是 asp 頁(yè)的通用代碼:<% @language = "vbscript" %><% response.buffer = true %><html>   <head>      <title>ft 測(cè)試</title></head>   <body><pre>----------------- 開(kāi)始測(cè)試 ------------------

<%

dim firstrow   ' 分頁(yè)顯示行時(shí)的第一行dim lastrow      ' 分頁(yè)顯示行時(shí)的最后一行dim pagesize   ' 頁(yè)面大小(每次的行數(shù))dim cn      ' 連接對(duì)象dim rs      ' ft 主鍵/排位返回的結(jié)果集(重復(fù)使用)dim usecache   ' 使用緩存或命中 ft(0:不使用;1:使用)dim alldata      ' 要緩存的結(jié)果行集合dim bbdata      ' 要緩存的最佳選擇行集合dim connectionstring   ' sql 連接字符串

' 確定是否要從緩存獲取數(shù)據(jù)' 默認(rèn)為否,否則接受傳入的數(shù)據(jù)if (request.form("usecache") <> "") then   usecache = request.form("usecache")elseif (request.querystring("usecache") <> "") then   usecache = request.querystring("usecache")else   usecache = 0end if

' 設(shè)置常量pagesize = 24firstrow = 0lastrow = 23connectionstring = <在此輸入您的連接字符串>

'----------------------------------------------------------------'' 顯示與最佳選擇/搜索詞匹配的簡(jiǎn)單主鍵/排位                       ''----------------------------------------------------------------'private sub searchnpage()

   dim p         ' 循環(huán)通過(guò)行時(shí)的計(jì)數(shù)器   dim numrows      ' 緩沖/結(jié)果集中的總行數(shù)

   if (usecache <> "1") then ' 獲取最佳選擇/結(jié)果并將其緩存

      dim queryarg   ' 傳入的查詢(xún)?cè)~      if (request.form("searchterm") <> "") then         queryarg = request.form("searchterm")      elseif (request.querystring("searchterm") <> "") then         queryarg = request.querystring("searchterm")      else         response.write("未提供搜索詞" & vbcrlf)         exit sub      end if     

      ' 理想情況下,應(yīng)該在此清理查詢(xún)?cè)~...      ' 添加自定義的清理邏輯,以防止      ' 隨意執(zhí)行 sql

      ' 調(diào)用 cleanstring(queryarg)

      ' 建立與 sql 的連接      set cn = server.createobject("adodb.connection")      cn.open connectionstring

      ' 從傳入的干凈字符串中獲取最佳選擇匹配項(xiàng)      set rs = cn.execute("exec bbsearch '" & queryarg & "'")

      ' 如果有最佳選擇,則獲取最佳選擇      if not(rs.eof) then         bbdata = rs.getrows      end if

      ' 現(xiàn)在從傳入的干凈字符串中獲取普通匹配項(xiàng)      set rs = cn.execute("exec ftsearch '" & queryarg & "'")

      ' 如果未返回任何結(jié)果,則結(jié)束      if (rs.eof and isempty(bbdata)) then         response.write("沒(méi)有匹配的行" & vbcrlf)         call connclose         exit sub      end if

      ' 否則,獲取行      if not(rs.eof) then         alldata = rs.getrows         session("results") = alldata      end if

      call connclose

   else ' 從緩存加載 (usecache=1)

      alldata = session("results")

      ' 在此獲取要使用的行范圍      if (request.form("firstrow") <> "") then         firstrow = request.form("firstrow")         lastrow = firstrow+pagesize      elseif (request.querystring("firstrow") <> "") then         firstrow = request.querystring("firstrow")         lastrow = firstrow+pagesize      end if

   end if ' usecache<>true

   ' 對(duì)于本應(yīng)用程序,只是打印出所有最佳選擇      ' (可能比頁(yè)面大小大),然后分頁(yè)顯示普通結(jié)果      ' 此處假設(shè):在使用緩存時(shí),如果沒(méi)有新的最佳選擇,' 則使用以前顯示的最佳選擇   if not(isempty(bbdata)) then      response.write("最佳選擇:" & vbcrlf)      for p = 0 to ubound(bbdata, 2)response.write(bbdata(0,p) & " "  & bbdata(1,p) & vbcrlf)      next      response.write(vbcrlf)   end if

   ' 返回搜索結(jié)果(可能只有最佳選擇)   if not(isempty(alldata)) then      if ubound(alldata, 2) < lastrow then         lastrow = ubound(alldata, 2)      end if

      response.write("搜索結(jié)果:" & vbcrlf)

      for p = firstrow to lastrowresponse.write(alldata(0,p) & " "  & alldata(1,p) & vbcrlf)      next   end if  ' not(isempty(alldata))

end sub

'----------------------------------------------------------------'' 關(guān)閉并清除連接對(duì)象                                             ''----------------------------------------------------------------'private sub connclose   rs.close   set rs = nothing   cn.close   set cn = nothingend sub

call searchnpage

%>

---------------- 測(cè)試結(jié)束 ----------------

<form action="<本頁(yè)>" method="post"><input type=submit value="next <%=pagesize%> rows" name="submit1"><input type=hidden name="usecache" value="1"><input type=hidden name="firstrow" value=<%=lastrow+1%>></form>

</pre>   </body></html>

一個(gè)簡(jiǎn)單的 html 窗體頁(yè)面即可像下面一樣利用上面的腳本:

<html><head><title>輸入搜索詞</title></head>

<body>

<form action="<搜索 asp 頁(yè)面>" method="post">搜索詞:<input name="searchterm"><p><input type="submit" value="search"></form>

</body></html>

正如以上兩個(gè)代碼示例所示,創(chuàng)建可執(zhí)行有效全文查詢(xún)(用最佳選擇完成)并緩存和分頁(yè)顯示結(jié)果的 web 應(yīng)用程序,并不需要花費(fèi)太多的工夫。只需使用最低的系統(tǒng)開(kāi)銷(xiāo),即可添加用于提供其他數(shù)據(jù)、增強(qiáng)最佳選擇的外觀以及在搜索結(jié)果中導(dǎo)航的邏輯(此外,強(qiáng)烈建議您實(shí)現(xiàn)其他用于錯(cuò)誤處理、安全設(shè)置和清理傳入數(shù)據(jù)的嚴(yán)密邏輯)。通過(guò)上面的高級(jí)建議和示例,使用 sql server 2000 全文搜索設(shè)計(jì)和實(shí)現(xiàn)快速可縮放的 web 搜索應(yīng)用程序就是輕而易舉的事情了。





附錄 c:資源full-text search deployment(英文)http://support.microsoft.com/default.aspx?scid=/support/sql/content/2000papers/fts_white%20paper.asp是那些初次接觸全文搜索的用戶(hù)的最佳參考。介紹了填充方法及硬件和軟件需求,并為使用 sql server 2000 全文搜索提供了提示、技巧和其他文檔。全文搜索公共新聞組 (microsoft.public.sqlserver.fulltext)查找有關(guān)全文搜索問(wèn)題的答案以及有用提示和技巧的理想場(chǎng)所。全文搜索新聞組是 sql server 開(kāi)發(fā)小組和博學(xué)的 microsoft mvp 成員經(jīng)常光顧的場(chǎng)所。


最大的網(wǎng)站源碼資源下載站,

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 天水市| 克什克腾旗| 泗阳县| 新津县| 衡阳市| 西昌市| 江城| 城固县| 奎屯市| 平塘县| 赞皇县| 通辽市| 五家渠市| 城固县| 福建省| 武威市| 申扎县| 虹口区| 谷城县| 临洮县| 日照市| 革吉县| 南靖县| 南丰县| 永新县| 商河县| 全南县| 滦平县| 石嘴山市| 台北县| 阿坝县| 蕉岭县| 卢氏县| 德清县| 台中县| 无为县| 湘潭县| 雅安市| 和硕县| 麦盖提县| 高尔夫|