2012-02-13 63 views
5

我们需要设计一个系统,允许用户在大文本中使用不同的关键字进行搜索,并在将来创建一些有关该关键字在所有文章中的频率的基本报告期。设计非常大的数据库搜索文本

我们将有:

  • 约200,000篇加入每天
  • 每篇文章的文本是约2KB
  • 物品存放6个月

为了做到这一点,我们来到采用以下解决方案:

  • 创建SOLR库存储物品
  • 使用MySQL数据库来存储物品的附加信息

系统将搜索SOLR通过关键字,然后将查找在MySQL结果检索其他信息。

所以,这是一个好方法吗?

如果大多数搜索只针对上个月添加的文章,保留两个数据库是不是一个好主意,一个是上个月为大多数搜索添加的文章,另一个是在所有文章中添加的文章?

如果您有任何提示/技巧如何改善这一点,将不胜感激。

在此先感谢!

+0

您可能也想看看http://stackoverflow.com/questions/9181566/full-text-搜索和蟒蛇/ 9182118 – 2012-02-13 15:26:32

回答

2

我认为你的解决方案非常好。如果你想在常见查询中获得更快的响应,我会评估在SOLR之前放置一个memcache实例。

我不确定这两个数据库,你必须看到与第一个到第二个DB的记录移动记录的负担相比,性能优势有多大。我怀疑是否有巨大的利益,但这只是直觉,不要接受我的言论和实验。

此外,您是否正在考虑如果数据集变得非常大,您可能需要一些可横向扩展的解决方案?

+0

感谢您的快速响应。我会做一些测试,看看移动记录或插入它们之间的区别。我已经考虑到数据库将变得非常大的事实,我认为我们可以使用MySQL集群来提高性能。您认为使用不同的数据库系统更适合,比如Cassandra更适合横向扩展吗? – 2012-02-13 11:25:08

+0

即使每天200k doc/day * 2kB/doc = 400MB/day,每年大约144GB的原始文本,我会担心更多关于文档本身的问题,而不是您在mysql中存储的元数据......实际上,那不是* *巨大的证明卡桑德拉,目前至少,IMHO – 2012-02-13 12:10:06

2

与其将数据存储在MySQL和Solr中,您可能希望考虑尝试使用MySQL 5.6。您应该可以使用一个存储引擎来满足您的所有需求。

MySQL实际上支持全文搜索多年,但仅支持过时的MyISAM表引擎。例如,MySQL 5.6支持InnoDB表的这种功能,这使得它与Ruby on Rails等框架更相关。

对MySQL的全文搜索的文档是:

http://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html

查询语法,这可能是特别感兴趣的那些比较它与Solr的特性,是:

http://dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html

+0

感谢您的答案。我也不知道InnoDB表上的MySQL全文搜索,但是你认为它比Solr更快吗?我没有从你提供的第二个链接中找到关于Solr的任何信息。 – 2012-02-13 11:34:53

+0

第二个链接没有提到Solr,但显示了可能的查询种类。这只是我所期望的信息,如果我决定在它和Solr之间。 – 2012-02-13 11:40:14

+0

我只是刚开始对Solr进行评估。我们只有成千上万的文档,而不是在6个月的部署期间拥有的数百万个文档。我将特别注意添加文档的时间,这是我们发现Solr最大问题的地方。 – 2012-02-13 11:43:00

1

事实上,我对使用Solr搜索平台没有任何意见,但在我看来,您可能会使用Java Content Repository JCR,这会让您获取数据库中的数据树形格式。因此,搜索将比平常快得多。 你必须看看这个链接来获得关于它

http://onjava.com/onjava/2006/10/04/what-is-java-content-repository.html

希望帮助

+0

我会看看'JCR'也做一些更多的研究。感谢您的提示 – 2012-02-13 11:47:17

+0

在这里,我会小心最高级的事情。 “指数级更快”具有非常明确的含义,因此,只有在字面上是真实的情况下才能做出这种声明 - 在这种情况下几乎肯定不是这种情况。 – Dathan 2012-02-24 05:45:57

+0

@Dathan让我们说**理论上**是这样的。我使用'eXo平台'以及使用JCR的'Platform Gatein',我发现内容的阅读速度非常快。 **我想这是JCR **的目的。对于这个_circumstance_,我不确定那是否帮助他。否则,他可以使用[Apache Lucene](http://lucene.apache.org/core/)。 – 2012-02-24 11:04:27

0

您要为每列(列1,列2,栏3)中有一个索引查找更多的信息而不是在如此大的桌子上进行桌面扫描。

问题是一个查询将使用一个索引。

如果您将一个索引放在(Column1,Column2,Column3)上,它仍然会为每个搜索执行一次表扫描,因为当为Column1使用索引时,它仍然需要检查Column2和Column3中的搜索关键字在同一时间,这些都没有下令。 - 索引仅针对Column1排序; Column2和Column2是随机顺序的

所以你有2个解决方案:要么改变表格布局,所以你没有Column1,Column2和Column3,但只有1列与搜索关键字:CNAME,如果你需要要知道它是否为Column1,2或3,然后添加一个带有1,2或3的整数的其他列。 在此cname列上放置一个索引,您的搜索将会很快。 但取决于你有其他列,这可能意味着你复制一些数据。

这就是我会做的。如果这还不够好,那么即使拆分表,所以只有一个表(id,cname),并使用该id可以从另一个表中查找其他需要的列。如果表格变得太长,您甚至可以拆分它,制作一个cnameAM,其中包含以A到M开头的单词和包含其余部分的cnameNZ。

如果无法更改表格布局: 而不是使用1个查询,使用多个查询

将索引放在每个列上并使用3个查询。 所以就(ID,列1)的指数,就(ID,列2)和(ID,栏3) 一个索引和:

SELECT * FROM 'SearchTable' WHERE Column1='$SearchKeyword' 
SELECT * FROM 'SearchTable' WHERE Column2='$SearchKeyword' 
SELECT * FROM 'SearchTable' WHERE Column3='$SearchKeyword' 

这3个选择会非常快,因为他们每做一个查找他们的具体索引 ,然后加入3个结果集进行进一步处理或使用您检索的ID查找更多列