使用NoSQL数据库替代MySQL

11

我有一个运行在Java堆栈(Struts 2 + Spring + Hibernate)上并使用MySQL进行持久化的Web应用程序。我看过NoSQL数据库,它们比关系型数据库更容易理解和使用。这是一个音乐流媒体应用程序,用于存储艺术家信息并允许用户保存播放列表。

我想知道是否有任何优势(性能?硬件成本?简化代码?扩展性?)可以切换到NoSQL数据库(CouchDB?MongoDB?Cassandra?)。如果切换到NoSQL数据库,我会失去/获得什么?

请给予建议。


说句实话,我喜欢Aaronaught在这里提出的非常相似问题的答案(https://stackoverflow.com/questions/2571098/moving-to-nosql/2571516#2571516)。 - Dan K.
哇,Aaronaught的回答太棒了。我感觉应该删除我的回答,但是我会更新它,并附上一个链接。 - Kyle Wild
该问题已被删除,但我在 Stackoverflow 存档中找到了答案,并将其复制到这里:https://dev59.com/nW445IYBdhLWcg3we6Z9#18315669 - str
5个回答

38
"NoSQL"的礼貌解释已经变成了"Not Only SQL"。如果您的数据确实是真正关系型的,或者如果您的功能依赖于诸如连接和ACID性等事物,则应以关系方式存储该数据。在本文中,我将解释如何在两个NoSQL数据存储库旁边使用MySQL。现代的、面向Web规模的数据存储涉及了解如何选择最佳工具来完成任务。话虽如此,NoSQL实际上是对这样一个事实的反应:关系方法和思维方式已被应用于不适合它的问题(通常是数千万行或更多的巨大表)。一旦表格变得如此庞大,典型的SQL“最佳实践”就是手动分片数据--即将记录1到10000000放入表A中,将10000001到20000001放入表B中,依此类推。然后,通常在应用程序模型层中,根据此方案执行查找。这就是所谓的“应用程序感知”扩展。这是耗时且容易出错的,但为了在保持MySQL作为长表存储的情况下扩展某些东西,它已成为一种或多或少的标准MO。对我来说,NoSQL代表了“应用程序无关”的替代方案。"

键-值

当我的MySQL原型开始变得过于庞大时,我个人将尽可能多的数据移动到闪电般快速的Membase,它比Memcached表现更好,并且具有持久性。Membase是一个分布式键-值存储,通过将更多的商品服务器添加到集群中,可以实现更多或更少的线性扩展(例如,Zynga使用它处理每秒半百万次操作),因此非常适合Amazon EC2Joyent等云时代。

众所周知,分布式键-值存储是获得巨大的线性规模的最佳方法。键-值的弱点是可查询性和索引。但即使在关系型世界中,可扩展性的最佳实践也是尽可能多地将工作转移到应用程序服务器上,在商品应用程序服务器上内存中执行连接,而不是请求中央RDB集群处理所有那些逻辑。由于简单选择加上应用程序逻辑确实是实现大规模扩展的最佳方法,甚至在MySQL上,转换到类似Membase(或其竞争对手,如Riak)并不是太难。


文档存储

有时候——虽然我认为这种情况比许多人想象的要少——应用程序的设计本质上需要二级索引、范围查询等功能。NoSQL 的解决方案是通过像 MongoDB 这样的文档存储来实现的。与 Membase 一样,Mongo 在关系数据库特别薄弱的一些领域表现得非常出色,例如 不受应用程序影响 的扩展、自动分片即使数据集大小急剧增加也能保持平坦响应时间。它比 Membase 慢得多,并且在纯水平扩展方面有点棘手,但好处是它高度可查询。您可以实时查询参数和范围,或使用 Map/Reduce 在极大的数据集上执行复杂的批量操作。

在我之前提到的同一个项目中,我们使用 Membase 来提供大量实时玩家数据,而使用 MongoDB 存储分析/指标数据,这正是 MongoDB 的优势所在。


为什么要将东西保存在SQL中

我简要提到了“真正关系型”的信息应该留在关系数据库中。正如评论者Dan K.指出的那样,我漏掉了讨论离开RDBMS或至少完全离开它的缺点的部分。

首先,这里有SQL本身。 SQL是众所周知的,并且已经成为行业标准很长时间了。一些“NoSQL”数据库(例如Google的App Engine Datastore(基于Big Table构建))实现了自己的类似SQL的语言(Google的被称为可爱的GQL,即Google查询语言)。MongoDB通过其令人愉悦的JSON查询对象对查询问题采取了新的方法。尽管如此,SQL本身是从数据中获取信息的强大工具,这通常是数据库的整个目的。

最重要的留在关系型数据库的原因是ACID,或者说原子性、一致性、隔离性、持久性。我不会重新讲解Acid-NoSQL的状态,因为这在这篇帖子上已经很好地解决了。可以说,有一个理性的原因Oracle的RDBMS拥有如此巨大的市场,并且它不会消失:某些数据需要纯粹的ACID合规性。如果你的数据需要(如果需要,你可能已经非常清楚),那么你的数据库也需要。保持pH低!

编辑:请查看Aaronaught在这里的帖子。他更好地代表了商业对商业的观点,因为我整个职业生涯都在消费领域。


1
对于如何使用SQL和NoSQL,您有很好的解释,但我建议添加更多关于在两者之间切换的各种权衡的细节。例如,您根本没有谈论ACID。 - Dan K.
@Dan K. +1 谢谢,我会尽快进行编辑。 - Kyle Wild
@Dan K. 添加了一个“为什么要将事物保存在SQL中”的部分,再次感谢您的提醒。 - Kyle Wild
Aaronaught的回答所在的问题已被删除,但我在Stackoverflow存档中找到了它,并将其复制到了这里:https://dev59.com/nW445IYBdhLWcg3we6Z9#18315669 - str
1
“Not Only SQL”这个解释已经被取代成为“不,SQL”了。根据Mark Madsen的说法。;-) - Lukas Eder

2
我认为这非常取决于你要在数据库中存储什么。我没有使用过CouchDB或Cassandra,因此我会让其他人代替我发言,但我经常使用MongoDB和MySQL。
如果您正在开发需要交易的应用程序,例如计费应用程序,则绝对需要使用MySQL,因为它支持事务。MySQL是ACIDic,即具有原子性、一致性、隔离性和持久性。这实际上意味着当您更新MySQL中的一行时,保证已发生。但是,MySQL的问题在于它很难水平扩展(通过添加更多服务器)。MySQL服务器倾向于通过增加内存、硬盘空间等来进行垂直扩展,但最终会达到一个天花板,成本可能会变得非常高。
MongoDB是文档数据库。它将类似于JSON的文档存储在集合中,并且是无模式的 - 因此每个文档可以不同。这对于应用程序的灵活性非常有用。许多开发人员说,NoSQL解决方案更多地是为程序员开发的,并且它们通常更容易构建(根据我的经验)。此外,MongoDB通过将数据库分片来进行水平缩放。实际上,现在甚至可以自动完成此操作。
但是,使用MongoDB也有缺点。如果您在生产中使用它,则必须使用其复制从服务器。这是因为MongoDB没有完全的单服务器耐久性。因此,如果遭受停电,您可能需要修复整个MongoDB数据库,这可能需要数小时。如果您拥有充足的资金,这可能不是什么大问题,但如果您是一家资金不足的新组织,这可能很困难(使用云计算?)。此外,MongoDB不支持事务,这是保证原子性和隔离性所必需的。最后,MongoDB只有最终一致性(虽然我已经看到了一些关于此论点的侧面)-这意味着当写入发生时,所有其他进程不一定会立即看到信息 - 只能最终看到。
在我看来,如果你要存储艺术家信息和曲目元数据,那么MongoDB将是一个好的解决方案。如果您要存储用户数据、计费数据等,则请将其存储在MySQL中。

1

对于这个问题,只有一个正确的答案:仅在您遇到性能问题或者预计流量大幅增加并且通过压力测试测量出您的架构不适合时才更改当前解决方案。

否则 - 没有必要评估其他替代方案。


2
我自己曾经犯过那个代价高昂的错误,因此我认为不提前评估替代方案是非常不明智的。在我看来,这是智慧的定义特征之一。错过应用程序推出的时机,你可能永远无法恢复。 - Kyle Wild
如果你有多余的时间 - 当然可以评估。但是最好投资时间来改进功能,如果性能不会成为问题。请注意,你应该测试你当前的架构 - 这本身就是一个严肃的过程,测试你的应用程序是否具备未来可靠性。 - Bozho

1

由于一些人喜欢Aaronaught的答案,但相应的问题已被删除,因此我从Stackoverflow archive中复制了他的答案:

在人们开始称之为“NoSQL”之前,这项技术的原始名称是分布式键/值存储。这是一个更具描述性的名称,我最初记得看到它时说,“嘿,很酷,我敢打赌这将对许多人非常有用。”此术语后来扩展到基本上包括“任何不是关系数据库”的内容,但通常,当大多数人谈论NoSQL时,他们正在谈论键/值存储。
自从NoSQL这个术语被创造出来以来,它一直被吹捧为银弹。我对像Cassandra这样的产品感兴趣,并跟踪它们的进展,但它们仍然是不成熟的技术,声称它们正在“取代”SQL或RDBMS总体(或者它们将在不久的将来)是至少虚假推理,如果不是彻头彻尾的谎言。
适合NoSQL范畴的产品和技术面向以下问题领域:
- 您计划部署大规模,高并发数据库(数百GB,数千用户); - 不需要ACID保证; - 或关系或约束; - 存储相当狭窄的数据集(相当于SQL中的5-10个表); - 将在商品硬件上运行(即Amazon EC2); - 需要在非常低的预算和“扩展”的情况下实施。
这实际上描述了今天许多网站。Google和Twitter非常符合这些要求。如果有一些推文丢失或延迟,真的很重要吗?另一方面,这些规格适用于几乎0%的业务系统,这是我们中很多人正在开发的内容。大多数企业有非常不同的要求:
- 中到大型数据库(10-100 GB),并发性相对较低(最多数百用户); - ACID(特别是A和C-原子性和一致性)是一个硬性要求; - 数据高度相关(层次结构,主细节,历史); - 必须存储各种数据-规范化模式中通常有数百或数千个表(更多用于反规范化表,数据仓库等); - 在高端硬件上运行; - 有大量资本可用(如果您的业务拥有数百万客户,则可以在沙发后找到约25,000美元或更多)。
高端SQL数据库(SQL Server,Oracle,Teradata,Vertica等)旨在进行垂直扩展,它们喜欢在具有大量内存,通过SAN和SSD进行快速I / O以及通过群集(HA)和分区(HC)进行偶尔的水平扩展。
“NoSQL”在性能方面经常与“SQL”进行比较。但是,完全达到最大化的高端SQL数据库服务器或群集将几乎无限地扩展。这就是它们旨在部署的方式。要小心怀疑性能差的规范化不良,索引不良的SQL数据库在入门级服务器上运行mysql(或更糟糕,像Amazon EC2这样的云服务器)与类似部署的NoSQL数据库进行比较的基准测试。苹果和橙子。如果您使用SQL,请不要被那种炒作吓倒。
SQL不会消失。由于NoSQL,DBA不太可能消失,就像由于Java和XML,PHP程序员

0

我发现 NoSQL 数据库不适合原型制作,因为你必须按照获取数据的方式来构建数据结构。使用 NoSQL 时,模式需要匹配查询需求。但在原型设计中,你还不知道如何提取数据,你会发现自己要么进行过多的查询,要么每次想添加新功能时都需要重新设计模式。

使用关系数据库,你只需要规范化数据,就可以随意提问。只有在模型与真实世界的实体没有正确匹配时,才需要重新设计模式。

我不得不多次重构我的 MongoDB 数据库,在 Web 应用程序中每次添加新数据查看方式时都要重构一次。毫不奇怪,我正在趋向于采用关系模式,以更好地利用文档数据库可能具有的嵌套数组和对象。

如果你四处寻找,会发现 NoSQL 最成功的用途是针对那些使用关系数据库开发应用程序的人。现在他们已经了解了它们的特性,并可以切换到 NoSQL,明确地知道如何满足自己的查询需求。如果你仍在探索应用程序及其所需数据库的问题类型,我建议坚持使用关系数据库。


1
一旦我更加熟悉NoSQL数据库,我发现它们在我所从事的游戏服务器开发中有一个重要的优点:速度。模式工作会减缓我的速度,特别是在原型阶段,设计经常快速而且经常发生巨大变化的时候。当一个无模式数据库以纯声明方式定义时,花费时间更新模型层和运行ALTER表语句真的很麻烦。 - Kyle Wild
在SQL世界中,人们已经有几十年的时间来磨练他们的设计并创建工具和流程来帮助他们。使用文档存储需要同样的前期思考,目前你被迫创新你的设计过程使其可行,但根据我的经验,它可以从那时起节省大量开销 - 即使在原型制作期间也是如此。 - Kyle Wild
使用NoSQL进行迁移和更改非常顺畅...模式更改非常糟糕。如果我想要,在NoSQL中可以保持数据冗余并在需要时进行迁移。实际上,这似乎是鼓励的做法。我发现很难看出如何在具有该能力的情况下原型设计可能会很差。 - hpavc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接