3

问候!

我有以下问题。我有一个包含大量行的表,我需要对其进行搜索,然后按许多参数对搜索结果进行分组。假设这张桌子是

id, big_text, price, country, field1, field2, ..., fieldX

我们运行这样的请求

SELECT .... WHERE 
[use FULLTEXT index to MATCH() big_text] AND 
[use some random clauses that anyway render indexes useless, 
like: country IN (1,2,65,69) and price<100]

我们将其显示为搜索结果,然后我们需要获取这些搜索结果并按多个字段对它们进行分组以生成搜索过滤器

(results) GROUP BY field1
(results) GROUP BY field2
(results) GROUP BY field3
(results) GROUP BY field4

这是我需要的一个简化案例,手头的实际任务更有问题,例如有时第一个结果查询也有它自己的 GROUP BY。这种功能的例子是这个网站 http://www.indeed.com/q-sales-jobs.html (搜索结果加上左侧的过滤器)

我已经完成并且仍在对 MySQL 的功能进行深入研究,此时我完全认为这在 MySQL 中是不可能的。粗略地说,MySQL 表只是位于 HDD 上的一堆行,索引是这些表的微小版本,按索引字段排序并指向实际行。这当然是一种超级简化,但关键是我根本不知道如何解决这个问题,即如何使用多个索引,能够快速进行 GROUP BY-s(当查询到达 GROUP由于范围搜索和其他事情,BY 索引完全没用)。我知道 MySQL(或类似的数据库)有各种有用的东西,比如索引合并、松散的索引扫描等等,但这根本不够——上面的查询仍然需要永远执行。

有人告诉我,这个问题可以通过 NoSQL 来解决,它利用一些全新的方式来存储和处理数据,包括聚合任务。我想知道的是它是如何做到这一点的一些快速的示意图解释。我的意思是我只是想快速浏览一下它,这样我才能真正看到它确实做到了这一点,因为目前我根本不明白怎么可能做到这一点。我的意思是数据仍然是数据并且必须放在内存中,而索引仍然是具有所有限制的索引。如果这确实可行,那么我将开始详细研究 NoSQL。

PS。请不要告诉我去读一本关于 NoSQL 的大书。我已经为 MySQL 做过这个,只是发现它在我的情况下不可用 :) 所以我想在买一本大书之前对这项技术有一些初步的了解。

谢谢!

4

1 回答 1

12

基本上有 4 种类型的“NoSQL”,但四种类型中的三种实际上足够相似,可以在其上编写 SQL 语法(包括 MongoDB,它是疯狂的查询语法 [我说即使 Javascript 是我的最喜欢的语言])。

键值存储

这些是简单的 NoSQL 系统,例如 Redis,基本上是一个非常精美的哈希表。您有一个稍后想要获取的值,因此您为其分配一个键并将其填充到数据库中,您一次只能查询一个对象并且只能通过一个键。

你绝对不想要这个。

文件存储

这比键值存储更上一层楼,也是大多数人在说 NoSQL(例如 MongoDB)时谈论的内容。

基本上,这些是具有层次结构的对象(如 XML 文件、JSON 文件和计算机科学中的任何其他类型的树结构),但树上不同节点的值可以被索引。相对于传统的基于行的 SQL 数据库,它们在查找时具有更高的“速度”,因为它们牺牲了连接性能。

如果您正在从具有大量列的单个表中查找 MySQL 数据库中的数据(假设它不是视图/虚拟表),并假设您已为查询正确索引(这可能是您真正的问题,在这里) , 像 MongoDB 这样的文档数据库不会给你带来任何比 MySQL 更大的优势,所以你可能不想仅仅因为这个原因迁移过来。

列式存储

这些是最像 SQL 数据库的。事实上,一些(如 Sybase)实现了 SQL 语法,而另一些(Cassandra)则没有。它们将数据存储在列中而不是行中,因此添加和更新成本很高,但大多数查询都很便宜,因为每列本质上都是隐式索引的。

但是,如果您的查询不能使用索引,那么使用列式存储就不会比使用常规 SQL 数据库更好。

图存储

图形数据库扩展SQL 之外。任何可以用图论表示的东西,包括键值、文档数据库和 SQL 数据库都可以用图数据库表示,比如 neo4j。

图形数据库使连接尽可能便宜(与文档数据库相反)来做到这一点,但他们必须这样做,因为即使是简单的“行”查询也需要许多连接来检索。

表扫描类型的查询可能会比标准 SQL 数据库慢,因为检索数据的所有额外连接(以脱节的方式存储)。

那么解决方案是什么?

你可能已经注意到我没有准确地回答你的问题。我不是说“你已经完成了”,但真正的问题是查询是如何执行的。

  1. 您确定不能更好地索引您的数据吗?诸如多列键之类的东西可以提高特定查询的性能。Microsoft 的 SQL Server 具有适用于您提供的示例的全文键类型PostgreSQL 可以模拟它
  2. 大多数 NoSQL 数据库相对于 SQL 数据库的真正优势是 Map-Reduce——具体来说,集成了一个高速运行的完整图灵完备语言,可以写入查询约束。可以编写查询函数以快速“失败”出”不匹配的查询或在满足“优先级”要求的记录上快速返回成功,而在 SQL 中做同样的事情有点麻烦。

但是,最后,您要解决的确切问题是:带有可选过滤参数的文本搜索,通常称为 a search engine,并且有非常专业的引擎来处理这个特定问题。我建议使用Apache Solr来执行这些查询。

基本上,将文本字段、“过滤”字段和表的主键转储到 Solr 中,让它索引文本字段,通过它运行查询,如果之后需要完整记录,查询你的 SQL 数据库对于您从 Solr 获得的特定索引。它使用更多内存并需要第二个进程,但可能最适合您的需求,在这里。

为什么所有这些文字都得到这个答案?

因为你的问题的标题和你的问题的内容真的没有任何关系,所以我两个都回答了。:)

于 2012-03-22T20:13:13.647 回答