2011-08-19 55 views
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

这是一个非常开放的问题,所以我们所能做的就是根据经验给出建议。首先要考虑的是,如果决定使用之前没有用过的东西是一个好主意,而不是使用你熟悉的MySQL。当你有机会时不使用光亮的新东西是无聊的,但请相信我,当你把自己涂在角落里,因为你知道新玩具会在盒子上做它所说的一切,这是很糟糕的。在博客文章中,没有任何事情可以像它说的那样工作。

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

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

你应该考虑的是如果你需要在可用性方面保持一致,反之亦然(例如,如果消息丢失或延迟有多糟糕,如果用户不能发布或读取消息有多糟糕消息),或者你会对数据进行更新(例如Riak中的数据是不透明的blob,为了改变它,你需要读取它并将其写回,在Cassandra,HBase和MongoDB中,你可以添加和删除属性而无需一读物体)。易用性也是一个重要因素,从程序员的角度来看,Mongo确实很容易使用,而HBase非常糟糕,但是花一些时间制作自己的封装恶意内容的库,这将是值得的。

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

2

从我的经验来看,Hbase并不是您的应用程序的良好解决方案。 因为:

  1. 不含默认辅助索引(你应该安装插件或喜欢这些东西)。因此,您只能通过主键进行有效搜索。我已经使用hbase和其他表实现了二级索引。所以你不能在在线应用程序中使用这个,因为为了获得结果你应该运行map/reduce作业,并且它将花费很多时间在数据上。

  2. 这是很难支持和调整这个分贝。对于有效的工作,您将使用HBAse和Hadoop,并且它是必需的强大计算机或多个计算机。

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

3

我会建议看演示约Why databases suck for messaging这主要是针对这样的事实,为什么你不应该使用的数据库如MySQL的消息。

我认为在这种情况下,CouchDB的changes feed可能会非常方便,虽然您可能还需要基于查询消息元数据创建一些更复杂的views。如果速度至关重要,请尝试查看redis,该功能非常快速,并具有pub/sub功能。 MongoDB及其即时查询支持对于这种用例也可能是一个体面的解决方案。

2

我认为你在存储元数据以及每条消息时都是独一无二的!为了更快的检索时间而牺牲存储空间可能是一条可行的路。请注意,如果您需要更改用户的元数据并将其传播到所有消息,它可能会变得复杂。你应该考虑这种情况的发生频率,你是否真的需要更新所有的消息记录,并且基于它是否值得付出代价来减少查询的次数(这可能是值得的,但这取决于你系统的细节)。

我同意@Andrej_L Hbase不是这个问题的正确解决方案。卡桑德拉也因为同样的原因而陷入困境。

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

Riak会是一个更好的选择,因为它使用map-reduce查询您的数据。这使您可以构建您喜欢的任何查询,而不需要像沙发中那样预先索引所有数据。百万行不是 Riak的问题 - 没有担心那里。如果需要,它也可以通过简单地增加更多的节点来扩展(并且它也可以平衡自己,所以这实际上不是问题)。

所以根据我自己的经验,我建议Riak。然而,与你不同的是,我对MongoDB没有直接的经验,所以你必须再次判断它自己(或者其他人可以回答这个问题)。

+0

最好的部分是,我不必担心元数据更改。一旦使用元数据创建了一条消息,它就会为该消息设置一条消息。 –

0

由于元数据属性的数量和任意数量可以 被包含在查询,在这里创建SQL指标似乎并不像一个 好主意的事实。

听起来好像你需要一个连接,所以你可以大多数人忘记CouchDB,直到他们对多工作的代码进行了处理(不确定它是否还在工作)。

+0

它只是一个关系。所以加入并不是唯一的选择。您可以:a)将用户的记录#嵌入到消息记录中或b)嵌入元数据,因此您不必查找用户记录 – BenG

1

了Riak一样快,你让它查询,取决于

蒙戈将让你在任何领域创建一个索引,即使是一个数组

的CouchDB是非常不同的,它建立在节点上使用索引存储的map-reduce(但没有减少),他们所说的“视图”

RethinkDB会让你有SQL,但是要快一点 TokuDB将太

Redis的将杀死所有的速度,但它的ENTI依靠存储在内存中

单层关系可以在所有的关系中完成,但每个关系都不同。