【问题标题】:SQL Server full-text search - many-to-many relationshipSQL Server 全文搜索 - 多对多关系
【发布时间】:2012-03-22 05:25:34
【问题描述】:

我正在使用 SQL Server 2008 开展一个项目,我认为全文搜索是最好的方法。我一直在尽可能多地阅读它,并且非常了解 hos 为一张桌子设置它。但是我不完全确定如何在我的场景中设置它 - 想象一下下面的表结构:

图书

- Id
- Title
- Description

图书作者

- BookId
- AuthorId

作者

- Id
- Name

如您所见,数据库包含一个包含书籍的表,每本书可以没有、一个或多个作者。每个作者也可以是一本书、一本或多本书的一部分——即BookAuthor 表具有多对多关系,由链接表BookAuthor 处理。

此时我想要完成的是一个搜索工具,可以根据用户提供的搜索字符串来查找匹配的书籍。因此,如果用户输入Brown,我想查找以下任一列中包含单词Brown 的所有书籍:

Book.Title
Book.Description
Author.Name

本质上,我想要一个结果集,包括标题为Brown Bear 的书和作者Dan Brown 写的书。如果有任何关于我应该如何设置的建议,我非常感谢您的意见!

(作为旁注,一旦我有这个过滤工作,查询结果也需要是可排序和可分页的,通过 @SortOrder@PageIndex@PageSize 处理传递到存储过程 -但我想这可能是一个单独的问题!)

【问题讨论】:

  • 为什么你认为全文搜索在这里是一个不错的解决方案?对我来说,这看起来就像普通的数据库设计。
  • @TomTom 如上所述搜索“Brown”只是我想要实现的一个简化示例。我需要能够搜索 x 个单词,并且使用 LIKE 将不起作用。我们将来还希望能够找到几乎匹配的行,这将需要全文搜索(据我所知)。
  • @AdrianIftode 是的,我看过那个,如果这被认为是重复的,我深表歉意。正如那里的第二个答案所述,我没有发现接受的答案可以解决问题。线程中的另一个建议是在 Book-table 中构建一个额外的列,其中包含我认为可以工作的所有可搜索数据,但会很麻烦且不规范化,所以我很好奇是否有人有任何其他建议。
  • @Iskariot 很遗憾,我无法撤消最后的投票。我不知道这些观点,看起来很有希望

标签: sql-server sql-server-2008 tsql full-text-search


【解决方案1】:

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')

【讨论】:

  • 感谢乔的建议! #1 我肯定看到它会给出正确的结果——你知道两个查询和一个联合对性能的影响吗?假设一本书既有与搜索匹配的描述,又有 5 个匹配的独立作者 - 在它们与联合语句“合并”之前,同一本书将被找到 6 次。
  • 对,两个查询一个union的性能肯定会比一个查询差。出于性能原因,您可能需要考虑一些事情,但在您投入时间之前,您应该首先确定性能将成为您的应用程序中的一个问题,而不是浪费时间进行过早的优化。如果您确实想优化性能,您可以有一个作业定期运行并将 book 和 author 表的内容聚合到一个去规范化的表中,然后查询单个去规范化的表。
  • 是的,我也在考虑这个选项,基本上有一个具有 BookId 的 BookIndex 表,以及一个/多个具有所有相关可搜索信息的额外列,例如标题,每个描述作者姓名聚合在该表的一行中。然后对其进行全文索引,并在搜索时将其加入 Book-table。我想我会与工会一起尝试上面的第一个建议,但如果性能成为问题,我会沿着这条路走。非常感谢您的意见!
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 2013-05-29
  • 2013-09-30
  • 2015-10-29
相关资源
最近更新 更多