SQL Server 全文搜尋/全文索引
概述
全文引擎使用全文索引中的資訊來編譯可快速搜尋表中的特定詞或片語的全文查詢。全文索引將有關重要的詞及其位置的資訊儲存在資料庫表的一列或多列中。全文索引是一種特殊型別的基於標記的功能性索引,它是由 SQL Server 全文引擎生成和維護的。生成全文索引的過程不同於生成其他型別的索引。全文引擎並非基於特定行中儲存的值來構造 B 樹結構,而是基於要編制索引的文字中的各個標記來生成倒排、堆積且壓縮的索引結構。
- 全文索引是針對資料表,只能對錶建立全文索引,不能對資料庫建立全文索引。
- 每個資料庫可以不包含全文目錄或包含多個全文目錄,一個全文目錄可以包含多個全文索引,但一個全文索引只能用於構成一個全文目錄。
- 一個數據表只能建立一個全文索引,一個全文索引可以包含多個欄位。
- 建立全文索引的表必須要有一個唯一的非空索引,並且這個唯一的非空的索引只能是一個欄位,不能是組合欄位。
- 每個表只允許有一個全文索引。
- 可以對以下型別的列建立全文索引:
char
、varchar
、nchar
、nvarchar
、text
、ntext
、image
、xml
、varbinary
和varbinary(max)
,從而可對這些列進行全文搜尋。對資料型別為varbinary
、varbinary(max)
、image
或xml
的列建立全文索引需要您指定型別列,型別列是用來儲存每行中文件的副檔名(.doc、.pdf、xls 等)的表列。
注意:全文搜尋是 SQL Server 資料庫引擎的一個可選元件, 如果你在安裝 SQL Server 時沒有選擇全文搜尋,請再次執行 SQL Server 安裝程式來新增它。
如果已安裝了全文搜尋元件,可在服務中檢視對應的服務是否有執行:
可以使用以下查詢語句來檢視對應的資料庫是否已開啟全文搜尋:
SELECT DATABASEPROPERTY('{DatabaseName}', 'isfulltextenabled');
如果返回結果是 0,可以使用以下指令碼進行啟用:
EXEC sp_fulltext_database 'enable'
全文搜尋查詢與 LIKE 謂詞的對比
LIKE與全文搜尋不同,LIKE僅對字元模式有效。另外,不能使用LIKE來查詢格式化的二進位制資料。此外,對大量非結構化的文字資料執行LIKE查詢要比對相同資料執行同樣的全文查詢慢得多。對數百萬行文字資料進行的LIKE查詢可能需要幾分鐘的時間才能返回結果;而對於同樣的資料,全文查詢只需要幾秒甚至更少的時間,具體取決於返回的行數。
建立全文目錄
全文目錄用來儲存全文索引。可以直接使用以下指令碼進行建立:
CREATE FULLTEXT CATALOG DefaultFullTextCatalog;
或者使用管理工具的圖形化介面進行建立:
為資料庫表建立全文索引
為資料庫表建立全文索引的時候需要指定對應的語言。因為不同的語言的分詞都有所差異,SQL Server將會使用對應語言的分詞器處理表中的資料。SQL Server的全文搜尋支援大約 50 種不同語言,可通過查詢sys.fulltext_languages表來檢視所有支援的語言。
下面我們對Shop表的ShopName和ShopAddress兩個欄位新增簡體中文的全文索引:
CREATE FULLTEXT INDEX ON [dbo].[Shop] ( [ShopName] LANGUAGE 2052, [ShopAddress] LANGUAGE 2052 ) KEY INDEX [PK_Shop] ON DefaultFullTextCatalog WITH CHANGE_TRACKING AUTO
同樣也可以使用管理工具的圖形化介面進行建立:
全文搜尋謂詞/函式
全文查詢使用全文謂詞(CONTAINS
和FREETEXT
)以及全文函式(CONTAINSTABLE
和FREETEXTTABLE
)。它們支援複雜的 Transact-SQL 語法,這種語法支援各種形式的查詢詞。
CONTAINS
CONTAINS用於在 SQL Server 中搜索單個詞和短語的精確或模糊(不太精確的)匹配項、在一定差別範圍內的相近詞或加權匹配項。
例如,查詢商鋪名或者地址中有福田的商鋪:
SELECT * FROM dbo.Shop WHERE CONTAINS((ShopName, ShopAddress),N'福田')
CONTAINSTABLE
在查詢方式上與CONTAINS
幾乎一樣。但CONTAINSTABLE返回的是符合查詢條件的表,在 SQL 語句中我們可以把它當作一個普通的表來使用,並且使用CONTAINSTABLE的查詢對每一行返回一個相關性排名值 (RANK) 和全文鍵 (KEY)。RANK用於表示相關性的匹配程度,它的值在0~1000之間,KEY就是主表的ID。
所以我們的查詢的時候可以使用RANK進行排序,將相關性高的排在前面:
SELECT T0.ShopID, T0.ShopName, T0.ShopAddress, T1.RANK FROM dbo.Shop T0 INNER JOIN CONTAINSTABLE (Shop, ShopAddress, N'福田') T1 ON T0.ShopID = T1.[KEY] ORDER BY T1.RANK DESC;
FREETEXT/FREETEXTTABLE
FREETEXT
/FREETEXTTABLE
的用法與CONTAINS
/CONTAINSTABLE
一致。不同的在於FREETEXT
/FREETEXTTABLE
會先把要查詢的詞句先進行分詞然後再查詢匹配。
例如可以直接查詢:福田的郵局,查詢時SQL Server會自動拆分。
SELECT T0.ShopID, T0.ShopName, T0.ShopAddress, T1.RANK FROM dbo.Shop T0 INNER JOIN FREETEXTTABLE (Shop, (ShopName, ShopAddress), N'福田的郵局') T1 ON T0.ShopID = T1.[KEY] ORDER BY T1.RANK DESC;
另外,可以通過查詢sys.dm_fts_parser
來檢視分詞結果:
SELECT * FROM sys.dm_fts_parser ('"福田的郵局"', 2052, 0, 0);
更多
以上只列舉了SQL Server全文搜尋的一些基本知識和簡單的用法,更詳細的內容可以檢視微軟的官方文件
原文地址:http://www.zkea.net/codesnippet/detail/sqlserver-fulltext-search.html