何时应该使用NoSQL数据库而不是关系型数据库?在同一个站点上同时使用两者是否可行?

171

使用NoSQL数据库有哪些优势?最近我读了很多关于它们的文章,但我仍然不确定为什么要实现这样一种数据库,并在什么情况下使用。


2
一般来说,关系型数据库允许您将数据组织成明确定义的实体和它们之间的关系,避免冗余。当这种数据建模方式在性能方面达到极限时,NoSQL数据库可以提供帮助。在这种建模中,数据被存储以服务于特定的查询;为了读取性能(而牺牲写入性能和/或一致性),会增加冗余。 - The Impaler
9个回答

100
关系型数据库实施ACID。因此,您将拥有基于模式的事务性数据存储。这已经被证明适用于99%的现实世界应用程序。使用关系型数据库,您可以实际上做任何事情。
但是,在处理海量高可用性数据存储时,速度和扩展性方面存在限制。例如,Google和Amazon在其大型数据中心中存储了数千兆字节的数据。由于RDBMs的阻塞/模式/事务特性,在这些情况下查询和插入性能不佳。这就是它们实现自己的数据库(实际上是键值存储)以获得巨大性能提升和可扩展性的原因。
NoSQL数据库已经存在很长时间 - 只是术语是新的。一些例子包括图形、对象、列、XML和文档数据库。
对于您的第二个问题:在同一个站点上同时使用两者是否可以?
为什么不呢?两者服务于不同的目的,对吧?

2
我认为ACID并不是仅限于关系型数据库。在非关系型数据库中,您可以拥有耐久性保证、事务和视图一致性。 - Thilo
@RamshVel,你能给一个键值存储类型的数据库的例子吗?谢谢。 - Rachael
3
@Rachael,一些例子包括redis、leveldb和riak..还有很多其他的选择,你可以通过谷歌搜索来查找。 - RameshVel

91

NoSQL解决方案通常旨在解决关系数据库不适用、使用成本过高(如Oracle)或需要实现破坏您数据库关系性质的东西的问题。

优势通常与您的使用情况有关,但是,除非您在关系数据库管理系统中建模数据存在问题,否则我认为您没有理由选择NoSQL。

我自己使用MongoDB和Riak解决一些关系型数据库不可行的特定问题,对于其他所有事情,我使用MySQL(或SQLite进行测试)。

如果您需要一个NoSQL数据库,您通常会知道原因,可能的原因是:

  • 客户希望在高流量网站上获得99.999%的可用性。
  • 您的数据在SQL中没有意义,您发现自己需要执行多个JOIN查询以访问某些信息。
  • 您正在破坏关系模型,您有存储非规范化数据的CLOB,并生成外部索引来搜索该数据。

如果您不需要NoSQL解决方案,则请记住,这些解决方案并不是关系型数据库管理系统的替代品,而是在前者失败时提供的替代选择,更重要的是,它们相对较新,因此仍然存在许多错误和缺失的功能。

关于第二个问题,使用任何技术与其他技术结合使用都是可以的,所以根据我的经验,只要它们不在同一台机器上,MongoDB和MySQL一起工作得很好。


6
谢谢您的回答。您提供的关于何时使用NoSQL的示例含糊不清。我希望能得到一个更具体的用例,以便决定是否将我的某些数据存储在NoSQL数据库中。 - smfoote
我尽量避免重复回答同一个问题,可以查看我之前对非常相似问题的回答。 https://dev59.com/kVDTa4cB1Zd3GeqPHDFv#3621568 - Asaf
1
我同意Asaf的优秀回答,实际上只有少数情况下你需要使用NoSQL而不是RDBMS。我认为NoSQL更像是备份数据库或“附加数据库”,而不是主要数据库。我还没有看到一个好的系统,其中核心数据库是NoSQL。 - Jo Smo

51

Martin Fowler有一段非常好的视频,对NoSQL数据库进行了很好的解释。链接直接跳转到他使用它们的原因,但整个视频都包含了很好的信息。

  1. 您拥有大量数据 - 特别是如果您无法将所有数据放在一个物理服务器上,因为NoSQL的设计可以很好地扩展。

  2. 对象关系不匹配 - 您的领域对象在关系数据库模式中不适合。 NoSQL允许您将数据持久化为文档(或图形),这可能更接近于您的数据模型。


16

NoSQL是一种数据库系统,其中数据以文档(MongoDB)、键值对(MemCache, Redis)和图形结构形式(Neo4J)进行组织。

也许有可能的问题和答案可以看做是“何时使用NoSQL”:

  1. 需要灵活的架构或处理树状数据吗?
    通常情况下,在敏捷开发中,我们开始设计系统时不会事先知道所有需求,而随着开发的进行,数据库系统可能需要适应频繁的设计更改,展示MVP (Minimal Viable Product)。 或者你正在处理一个动态的数据模式。 例如 AWS CloudTrail 日志非常精确。

  2. 数据集很大/广泛吗?
    是的,NoSQL数据库是管理数百万甚至数十亿记录而不牺牲性能和可用性的应用程序的更好候选者,虽然在某些情况下可能会牺牲一致性(现代数据库在这里是例外,它允许可调整的一致性超过可用性,例如Cassandra,云提供商数据库CosmosDB,DynamoDB)。

  3. 在扩展和一致性之间权衡
    与关系型数据库不同,NoSQL数据库可能使数据集在其他节点上最终保持一致,这是默认行为,但易于在性能和可用性方面进行扩展。 例如:这对于存储在线人员的即时通讯应用程序、API令牌在DB中和记录网站流量统计数据可能是有益的。

  4. 执行地理位置操作: MongoDB具有丰富的支持进行GeoQuerying和地理位置操作的哈希功能。我真的很喜欢MongoDB的这个特性。PostresSQL也是如此,但实施的简易程度取决于使用案例。

简而言之,MongoDB非常适合大规模存储动态结构化数据的应用程序。

编辑: 更新了关于数据库一致性的答案。


5
“NoSQL 数据库可能会丢失一些小数据” 真是闹哪样?谁会想冒这种风险呢?这肯定不对。 - Jay Q.
1
@JayQ。是的,这可能是错误的。这就是为什么我说“可能”。那么为什么我们不能使用NpSQL数据库进行事务操作呢? - Hrishikesh
一切都可能会丢失数据。如果您没有从伽马射线事件端到端进行屏蔽,那么在某个时刻,一个比特位神奇地翻转,这可能是一个符号位,或者在CPU寄存器中用作布尔标志的位在错误的时刻导致条件实际上采取了错误的分支等等。这只是一个例子。此外,您的整个技术堆栈是否存在大问题也无法确定。唯一的区别在于丢失/错误的概率有多高,系统是否具有足够的冗余来注意到它发生了,并且系统是否在注意到时告诉您。 - mtraceur
1
最终,当人们说事务性数据库“不会丢失数据”时,这是简写的方式,表示特定方式的数据丢失变得不可能,当然这是有代价的,只是有时候代价微不足道。例如,两个客户端没有协调(或者协调得不够好,比如由于代码中的错误),在读取和修改同一个键后立即写入键值存储器,如果它们在大约同一时间这样做,就会出现竞争条件。通过强制一个客户端等待或执行其他操作,事务可以防止这种情况发生。 - mtraceur

10
一些必要的信息缺失,无法回答问题:数据库必须覆盖哪些用例?必须从现有数据执行复杂分析(OLAP)还是应用程序必须能够处理许多事务(OLTP)?数据结构是什么?这远远不是问题时间的结束。
在我看来,基于大胆的流行语做出技术决策是错误的,而不知道其背后的确切内容。NoSQL通常因其可扩展性而受到赞扬。但您还必须知道,水平扩展(跨多个节点)也有其代价,并非免费。然后,您必须处理诸如eventual consistency之类的问题,并定义如何解决数据冲突,如果它们无法在数据库级别解决。但是,这适用于所有分布式数据库系统。
开发人员对于NoSQL中“无模式”的这个词非常兴奋。但在技术分析后,这个流行语很快就让人失望了,因为它在写入数据时确实不需要模式,但读取数据时却需要。这就是为什么它确切地应该被称为“按需模式”。随心所欲地编写数据可能很诱人。但如果已经存在数据而新版本的应用程序期望不同的模式,我该如何处理这种情况?
例如,在MongoDB中采用的文档模型不适合存在许多数据关系的数据模型。连接必须在应用程序级别上完成,这是额外的工作,为什么要编写数据库应该处理的事情呢?
如果你认为Google和Amazon之所以开发自己的数据库是因为传统的RDBMS无法处理大量数据的洪流,那么只能说:你不是Google和Amazon。这些公司是先锋,只有在传统数据库不再适用的0.01%情况下才会这样做,但对于世界其他地方来说,传统数据库仍然很适合使用。

重要的是:SQL 已经存在了40多年,大型系统如Oracle或Microsoft SQL已经投入了数百万小时的开发。一些新数据库必须实现这一点。有时找到SQL管理员比找MongoDB管理员更容易。这就带来了维护和管理的问题。这个主题并不是很吸引人,但它是技术决策的一部分。


1
似乎正确,但我认为如果这样比较花费的时间并不正确。如果是这样的话,每个人都会在他们所有的应用程序中使用汇编语言。我宁愿说这总归取决于你的应用程序和用例。 - Gopherine

9

处理大量读写操作

在需要快速扩展时,可以考虑使用NoSQL数据库。一般情况下,何时需要快速扩展呢?当您的网站有大量读写操作或需要处理大量数据时,NoSQL数据库是最适合的选择。由于它们具有动态添加节点的能力,因此可以处理更多并发流量和大量数据,并且延迟最小。

数据建模灵活性

第二个提示是在开发的初始阶段,当您不确定数据模型、数据库设计以及预期变化速度时,NoSQL数据库为我们提供了更多的灵活性。

最终一致性优于强一致性

当我们不需要事务时,最好选择NoSQL数据库,允许最终一致性代替强一致性。

一个很好的例子是像Twitter这样的社交网络网站。当名人的推文走红,并且来自世界各地的人都在点赞和转推时,如果喜欢的数量短时间内稍微增加或减少一点,那又有什么关系呢?

如果系统显示的“喜欢”的计数从实际的550万减少到525万,名人肯定不会在意。

当一个大型应用程序部署在遍布全球的数百台服务器上时,地理分布式节点需要一些时间来达成全局共识。在它们达成共识之前,实体的值是不一致的。在短时间内,实体的值最终变得一致。这就是最终一致性。

尽管不一致并不意味着任何形式的数据丢失。它只是意味着数据需要经过一段短暂的时间通过海底互联网电缆在全球范围内传输以达到全球共识并变得一致。

我们经常会遇到这种情况,特别是在YouTube上。您经常会看到一个视频有10个观看次数和15个赞。这怎么可能呢?

实际上不可能。实际的观看次数已经超过了“喜欢”的数量。只是观看次数不一致,并且需要一段时间才能更新。

运行数据分析

NoSQL数据库也非常适合处理大量数据分析用例。


5
我在寻找有说服力的理由来偏离关系型数据库设计时遇到了这个问题。
Julian Brown写了一篇很棒的文章,介绍了分布式系统的限制。这个概念被称为 Brewer's CAP 定理,简而言之如下:
分布式系统的三个要求是:一致性、可用性和分区容错性(简称CAP)。但你只能同时满足其中两个。
以下是我的总结:
如果你牺牲一致性,最好选择NoSQL。

2
我设计并实现了NoSQL数据库的解决方案,以下是我的决策清单,帮助你决定使用SQL还是面向文档的NoSQL。 不应该这样做 在以下情况下,很难辩称使用面向文档的NoSQL更合适:
  • 需要 OLAP/OLTP
  • 项目小/数据库结构简单
  • 需要特定查询
  • 无法避免即时一致性
  • 需求不明确
  • 缺乏经验丰富的开发人员
应该这样做 如果你没有以上条件或者能够缓解这些问题,以下两个理由可能让你受益于NoSQL:
  • 需要大规模运行
  • 便于开发(与你的技术栈更好地集成,无需ORM等)
更多信息 在我的博客文章中,我会详细解释这些原因。

注意:上述内容仅适用于面向文档的NoSQL。还有其他类型的NoSQL需要考虑其他因素。


0
看到这个帖子,想分享一下我的经验。许多 SQL 数据库支持在列中存储 JSON 数据并支持对其进行查询。因此,我使用了混合方法,将 JSON 存储在关系型数据库的列中...

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