2013-03-04 64 views
4

在論壇應用程序中,線程的實際名稱存儲在一個表中,然後回覆被存儲在另一個表中。可搜索的文本在2個表格中,如何設計全文索引?

Table_Thread 
Subject varchar(255) e.g. "How to setup fulltext search" 

Table_Replies (users replies here) 
    ReplyText text(not null) 

現在我要創建兩個主題進行全文搜索和回覆列,但他們似乎非常相關所以他們應該在同一個指數。

可以做到這一點嗎?

我使用的是SQL Server 2005中

+0

這兩個表之間是否有任何關聯? – 2013-03-06 22:45:22

回答

6

假設有主題,你可以創建一個視圖WITH SCHEMABINDING答覆之間的關聯,創建視圖的UNIQUE CLUSTERED索引,然後添加以您的全文目錄選擇你想要的兩列。

0

當巨大的併發查詢請求到來時,RDBMS無法通過SQL支付它。更重要的是,選擇SQL嚴重支持全文搜索。所以你需要IR(信息檢索)庫,例如Java的Lucene。

0

可以創建含有索引列的表的+ PK的聯合一個索引視圖

例如

CREATE VIEW SearchText 
WITH SCHEMABINDING 
AS SELECT * FROM (
(Subject as Text, Table_Thread_ID as ID, 1 as Type FROM Table_Thread) 
UNION ALL 
(ReplyText as Text, Table_Replies_ID as ID, 2 as Type FROM Table_Replies)); 

我把1型和2那樣隨心所欲,因爲你需要一個唯一的密鑰,以建立全文索引。 然後在(ID,Type)和最後的全文索引上創建唯一索引。

CREATE UNIQUE INDEX SearchText_UK ON SearchText (ID, Type); 
CREATE FULLTEXT CATALOG ft AS DEFAULT; 
CREATE FULLTEXT INDEX ON SearchText(Text) 
    KEY INDEX SearchText_UK 
    WITH STOPLIST = SYSTEM; 
0

我已經看到了NopCommerce(C#MVC開源電子商務)上使用的產品「和「變異體」,只有迴歸」產品的全文搜索已經完成。這與您的案例非常相似,因爲您要搜索「主題」和「回覆」,但您顯然只想返回「主題」。我將其更改爲使用線程和回覆你:

首先,創建一個由表(可選),生成索引名稱的功能:

CREATE FUNCTION [dbo].[nop_getprimarykey_indexname] 
(
    @table_name nvarchar(1000) = null 
) 
RETURNS nvarchar(1000) 
AS 
BEGIN 
    DECLARE @index_name nvarchar(1000) 

    SELECT @index_name = i.name 
    FROM sys.tables AS tbl 
    INNER JOIN sys.indexes AS i ON (i.index_id > 0 and i.is_hypothetical = 0) AND (i.object_id=tbl.object_id) 
    WHERE (i.is_unique=1 and i.is_disabled=0) and ([email protected]_name) 

    RETURN @index_name 
END 
GO 

然後,通過創建目錄和索引使全文:

EXEC(' 
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_catalogs WHERE [name] = ''myFullTextCatalog'') 
    CREATE FULLTEXT CATALOG [myFullTextCatalog] AS DEFAULT') 


DECLARE @create_index_text nvarchar(4000) 
SET @create_index_text = ' 
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[Table_Thread]'')) 
    CREATE FULLTEXT INDEX ON [Table_Thread]([Subject]) 
    KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('Table_Thread') + '] ON [myFullTextCatalog] WITH CHANGE_TRACKING AUTO' 
EXEC(@create_index_text) 

SET @create_index_text = ' 
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[Table_Replies]'')) 
    CREATE FULLTEXT INDEX ON [Table_Replies]([ReplyText]) 
    KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('Table_Replies') + '] ON [myFullTextCatalog] WITH CHANGE_TRACKING AUTO' 
EXEC(@create_index_text) 

然後,在存儲過程中通過關鍵字來獲取產品,建立與匹配的關鍵字的產品ID列表的臨時表。現在

INSERT INTO #KeywordThreads ([ThreadId]) 
    SELECT t.Id 
    FROM Table_Thread t with (NOLOCK) 
    WHERE CONTAINS(t.[Subject], @Keywords) 

    UNION 
    SELECT r.ThreadId 
    FROM Table_Replies r with (NOLOCK) 
    WHERE CONTAINS(pv.[ReplyText], @Keywords) 

您可以使用臨時表#KeywordThreads加入與線程的列表,並返回他們。

我希望這會有所幫助。