2012-03-04 64 views
4

我正在开发一个SQL Server 2008项目,我相信全文搜索是最好的方法。我一直在尽可能多地阅读它,并且非常了解如何将它设置为单个表格。但我不完全知道如何用我的方案设置它 - 想象一下如下表结构:SQL Server全文搜索 - 多对多关系

- Id 
- Title 
- Description 

BOOKAUTHOR

- BookId 
- AuthorId 

作者

- Id 
- Name 

正如您所看到的,数据库包含一个带有书籍的表格,每本书可以没有,一个或多个作者。每位作者也可以是没有,一本或多本书的一部分 - 即BookAuthor表具有多对多关系,可通过链接表BookAuthor处理。

我现在想要完成的是一个搜索工具,用于根据用户提供的搜索字符串查找匹配的书籍。因此,如果在Brown用户类型我希望找到的所有书籍,其中以下任一列中包含单词Brown

Book.Title 
Book.Description 
Author.Name 

从本质上说,我希望有一个结果集的书籍,包括书的标题Brown Bear和作者Dan Brown所写的书籍。如果有任何建议,我应该如何设置,我真的很感激你的意见!

(作为一个侧面说明,一旦我有这样的过滤工作,查询结果将还需要排序和分页,通过@SortOrder@PageIndex@PageSize传递到存储过程中处理 - 但我想这可能是一个)

+0

为什么您认为全文搜索在这里是一个体面的解决方案?这对我来说看起来像正常的数据库设计。 – TomTom 2012-03-04 13:20:47

+0

[在多个表,列中使用SQL Server 2008中的全文搜索]可能的重复(http://stackoverflow.com/questions/403630/using-full-text-search-in-sql-server-2008-across -multiple-tables-columns) – 2012-03-04 14:01:19

+0

@TomTom如上所述搜索“Brown”只是我想获得的简单示例。我需要能够搜索x个单词,并且使用LIKE不起作用。我们还希望将来能够找到_almost_匹配的行,并且这将需要全文搜索(据我所知)。 – Iskariot 2012-03-05 07:33:18

回答

2

CONTAINS谓词可以将要搜索的列列表作为其第一个参数;但是,这些列必须来自单个表格。你有几个选择来解决这个限制。一种选择是,您可以执行两个单独的搜索,每个表上一个,然后将结果联合在一起。

select Id, Title from Book where contains([Description], 'brown') 
union 
select b.Id, b.Title 
    from Book b inner join BookAuthor ba on b.Id = ba.BookId 
     inner join Author a on a.Id=ba.AuthorId 
    where contains([Name], 'brown') 

另一种选择是采取的事实,即FTS indexes can be created on indexed views。为此,请创建一个索引视图,该视图包含Book表中的Title字段和Author表中的Name字段,然后在视图中的这两列上创建一个FTS索引。然后,您可以按照以下方式针对此视图撰写查询:

select BookId, Title from vw_BooksAndAuthors 
where contains(([Description], [Name]), 'brown') 
+0

谢谢你的建议乔! #1我一定会看到它会给出正确的结果 - 你有任何关于两个查询和工会性能打击的想法吗?假设一本书同时具有与搜索相匹配的描述和5个独立的作者匹配 - 同一本书在与union声明“合并”之前将被发现6次。 – Iskariot 2012-03-05 07:47:37

+0

对,两个查询和一个联合的性能肯定会比单个查询的性能更差。出于性能考虑,您可能需要考虑一些事项,但在您投入时间之前,您应该先确定性能将成为应用程序中的问题,而不是浪费时间进行过早优化。如果您想要优化性能,可以定期运行一个作业,并将书籍和作者表的内容集合到一个非标准化表中,然后查询单个非标准化表。 – 2012-03-05 15:24:36

+0

是的,我也在考虑这个选项,基本上有一个BookIndex表,它具有BookId和一个/许多额外的列,其中包含所有相关的可搜索信息,例如标题,描述每个作者的名称聚合在一行上在那张桌子里。然后全文索引那一个,并在搜索时将它加入Book-table。我想我会尝试你的第一个建议与工会,但如果表现成为一个问题,我会沿着这条路线。非常感谢您的意见! – Iskariot 2012-03-08 08:06:40