1

我正在开发一项功能,并且可以就我应该使用哪个数据库来解决这个问题提出意见。

我们有一个使用 MySQL 的 Rails 应用程序。我们对 MySQL 没有任何问题,它运行良好。但是对于一个新特性,我们正在决定是否保留 MySQL。为了简化问题,我们假设有一个UserMessage模型。用户可以创建消息。消息根据他们与发布者的关联传递给其他用户。

显然,存在基于友谊的关联,但还有更多基于用户个人资料的关联。我计划将一些关于海报的元数据与消息一起存储。这样我就不必每次查询消息时都提取元数据。

因此,消息可能如下所示:

{
  id: 1,
  message: "Hi",
  created_at: 1234567890,
  metadata: {
    user_id: 555,
    category_1: null,
    category_2: null,
    category_3: null,
    ...
  }
}

当我查询消息时,我需要能够基于零个或多个元数据属性进行查询。这个调用需要快速并且经常发生。

由于元数据属性的数量以及查询中可以包含任意数量的事实,在此处创建 SQL 索引似乎不是一个好主意。

就个人而言,我有使用 MySQL 和 MongoDB 的经验。我已经开始研究 Cassandra、HBase、Riak 和 CouchDB。我可以从可能已经研究过哪个数据库适合我的任务的人那里获得一些帮助。

是的,消息表很容易增长到数百万或行。

4

6 回答 6

4

这是一个非常开放的问题,所以我们所能做的就是根据经验给出建议。首先要考虑的是,决定使用以前没有使用过的东西而不是使用您熟悉的 MySQL 是否是个好主意。当你有机会时不使用闪亮的新东西很无聊,但相信我,当你把自己画在角落里时会很糟糕,因为你认为新玩具会按照盒子上说的一切来做。没有什么能像博客文章中所说的那样有效。

我主要有 MongoDB 的经验。这是一个糟糕的选择,除非你想花很多时间尝试不同的事情并意识到它们不起作用。一旦你扩大了一点,你基本上就不能使用二级索引、更新和其他使 Mongo 成为一个非常好的工具的东西(其中大部分与它的全局写锁和磁盘上的数据库格式有关,它如果您删除数据,基本上很容易吸收并发性和碎片)。

我不同意 HBase 是不可能的,它没有二级索引,但是一旦超过一定的流量负载,你就不能使用它们。Cassandra 也是如此(它比 HBase 更容易部署和使用)。基本上,无论您选择哪种解决方案,您都必须实施自己的索引。

您应该考虑的是,如果您需要一致性而不是可用性,反之亦然(例如,如果消息丢失或延迟有多糟糕,而如果用户无法发布或阅读消息有多糟糕),或者如果您要更新您的数据(例如,Riak 中的数据是一个不透明的 blob,要更改它,您需要读取它并将其写回,在 Cassandra、HBase 和 MongoDB 中,您可以添加和删除属性而无需先读取对象)。易用性也是一个重要因素,从程序员的角度来看,Mongo 固然好用,而 HBase 很可怕,但只要花点时间制作自己的库来封装这些讨厌的东西,这将是值得的。

最后,不要听我的,试一试,看看他们的表现和感觉如何。确保您尽可能努力地加载它,并确保您测试您将要做的所有事情。我犯了一个错误,没有测试当你在 MongoDB 中删除大量数据时会发生什么,并且为此付出了高昂的代价。

于 2011-08-19T09:58:25.020 回答
3

我建议看一下关于为什么数据库不适合消息传递的演示文稿,该演示文稿主要针对的是为什么您不应该使用诸如 MySQL 之类的数据库进行消息传递的事实。

我认为在这种情况下,CouchDB 的更改提要可能会非常方便,尽管您可能还必须根据查询消息元数据创建一些更复杂的视图。如果速度很关键,请尝试查看速度非常快且带有发布/订阅功能的redis。具有即席查询支持的 MongoDB 也可能是此用例的一个不错的解决方案。

于 2011-08-19T08:25:52.480 回答
3

我认为您在将元数据与每条消息一起存储时非常准确!为了更快的检索时间而牺牲存储可能是要走的路。请注意,如果您需要更改用户的元数据并将其传播到所有消息,它可能会变得复杂。您应该考虑这可能发生的频率,是否真的需要更新所有消息记录,以及基于此是否值得为减少查询而付出代价(这可能是值得的,但这取决于您的系统的详细信息)。

我同意@Andrej_L 的观点,即 Hbase 不是解决这个问题的正确方法。出于同样的原因,Cassandra 也喜欢上了它。

CouchDB可以解决您的问题,但是您必须为要查询的任何元数据定义视图(物化索引)。如果这里不使用 MySQL 的全部目的是避免索引所有内容,那么 Couch 可能也不是正确的解决方案。

Riak 将是一个更好的选择,因为它使用 map-reduce 查询您的数据。这允许您构建您喜欢的任何查询,而无需像在沙发上那样预先索引所有数据。数百万行对 Riak 来说不是问题——不用担心。如果需要,它也可以通过简单地添加更多节点来很好地扩展(它也可以自我平衡,所以这真的不是问题)。

所以根据我自己的经验,我推荐Riak。但是,与您不同的是,我对 MongoDB 没有直接经验,因此您必须自己再次判断 Riak(或者也许这里的其他人可以回答)。

于 2011-08-19T08:29:11.147 回答
2

根据我对 Hbase 的经验,这对您的应用程序来说并不是一个好的解决方案。因为:

  1. 默认情况下不包含二级索引(您应该安装插件或类似的东西)。所以你只能通过主键有效地搜索。我已经使用 hbase 和附加表实现了二级索引。所以你不能在在线应用程序中使用这个,因为要获得结果,你应该运行 map/reduce 作业,这将花费大量时间处理百万数据。

  2. 支持和调整这个数据库非常困难。为了有效地工作,您将 HBAse 与 Hadoop 一起使用,并且需要功能强大的计算机或多台计算机。

  3. 当您需要对大量数据进行聚合报告时,Hbase 非常有用。看来你不需要。

于 2011-08-19T08:02:44.957 回答
1

由于元数据属性的数量以及查询中可以包含任意数量的事实,在此处创建 SQL 索引似乎不是一个好主意。

听起来您需要加入,因此您几乎可以忘记 CouchDB,直到他们整理出正在处理的多视图代码(实际上不确定它是否仍在处理)。

于 2011-08-19T11:54:40.157 回答
1

Riak 可以尽可能快地查询,具体取决于节点

Mongo 将允许您在任何字段上创建索引,即使那是一个数组

CouchDB 非常不同,它使用存储的 Map-Reduce(但没有 reduce)构建索引,他们称之为“视图”

RethinkDB 会让你拥有 SQL,但 TokuDB 也会更快一点

Redis 会在速度上扼杀一切,但它完全存储在 RAM 中

单级关系可以在所有这些中完成,但对每个都不同。

于 2011-12-06T05:51:12.793 回答