好的,这就是我看到这个工作的方式。
我对 MongoDB 有完全相同的问题。MongoDB“提供”了搜索功能,但就像 MySQL 一样,你永远不应该使用它们,除非你想被 IO、CPU 和内存问题所困扰,并且被迫使用比平时更多的服务器来处理你的索引。
如果使用 Sphinx(或其他搜索技术),整个想法是通过拥有高性能索引搜索器来降低每台服务器的成本。
然而,Sphinx 不是存储引擎。查询跨表的确切关系并不那么简单,他们已经用 SphinxQL 稍微修正了这一点,但由于全文索引的性质,它仍然不像你在 MySQL 中那样进行整体连接。
相反,我会将关系存储在 MySQL 中,但在 Sphinx 中有一个“用户”索引。
在我的网站中,我个人有 2 个索引:
- 主要(房屋用户、视频、频道和播放列表)
- help(帮助系统搜索)
这些增量每分钟更新一次。由于实时索引有时仍然是实验性的,而且我个人已经看到了高插入/删除率的问题,所以我坚持进行增量更新。因此,我将使用增量索引来更新我网站的主要可搜索对象,因为这比实时索引(来自我自己的测试)占用的资源更少且性能更高。
请注意,为了通过 delta 处理删除以及您的 Sphinx 集合,您将需要一个 killlist 和某些过滤器用于您的 delta 索引。这是我的索引中的一个示例:
source main_delta : main
{
sql_query_pre = SET NAMES utf8
sql_query_pre =
sql_query = \
SELECT id, deleted, _id, uid, listing, title, description, category, tags, author_name, duration, rating, views, type, adult, videos, UNIX_TIMESTAMP(date_uploaded) AS date_uploaded \
FROM documents \
WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) OR update_time >( SELECT last_index_time FROM sph_counter WHERE counter_id=1 )
sql_query_killlist = SELECT id FROM documents WHERE update_time>=( SELECT last_index_time FROM sph_counter WHERE counter_id=1 ) OR deleted = 1
}
这每分钟处理一次删除和添加,这对于真正的 Web 应用程序来说几乎是实时的。
所以现在我们知道如何存储我们的索引了。我需要谈谈关系。Sphinx(即使它有 SphinxQL)不会跨数据进行整体连接,所以我个人建议在 Sphinx 之外进行关系,不仅如此,而且正如我所说,这个关系表会得到高负载,所以这可能会影响狮身人面像指数。
我会做一个查询来挑选所有的 id 并使用那组 id 使用 sphinx API 上的“过滤器”方法将主索引过滤到特定的文档 id。完成此操作后,您可以像往常一样在 Sphinx 中搜索。这是迄今为止我发现的处理此问题的最有效的方法。
始终要记住的关键是,Sphinx 是一种搜索技术,而 MySQL 是一种存储技术。记住这一点,你应该没问题。
编辑
正如@NB 所说(我在回答中忽略了)Sphinx 确实有 SphinxSE。尽管它是原始的并且仍处于其开发的测试阶段(与实时索引相同),但它确实为 Sphinx 提供了一个实际的 MyISAM/InnoDB 类型的存储。这太棒了。但是有一些警告(与任何事情一样):
但是,它可以/可以完成您正在寻找的工作,因此请务必对其进行调查。