对于需要按内容搜索的大型数据集,使用NoSQL数据库是否不切实际?


51

我已经学习NoSQL数据库已有一个星期了。

我真的了解NoSQL数据库的优势以及它们非常适合的许多用例。

但是人们通常会在撰写文章时就好像NoSQL可以代替关系数据库一样。还有一点我无法理解:

NoSQL数据库是(通常)键值存储。

当然,可以所有内容存储到键值存储中(通过将数据编码为JSON,XML等),但是我看到的问题是,在许多情况下,您需要获取一些与特定条件匹配的数据用例。在NoSQL数据库中,只有一个可以有效搜索的条件-密钥。关系数据库经过优化,可以有效地搜索数据行中的任何值。

因此,NoSQL数据库并不是持久存储需要按其内容搜索的数据的真正选择。还是我误会了什么?

一个例子:

您需要存储网上商店的用户数据。

在关系数据库中,您将每个用户存储为users表中的一行,并带有ID,名称,他的国家等。

在NoSQL数据库中,您将以ID为密钥存储每个用户,并将其所有数据(以JSON等编码)存储为值。

因此,如果您需要从某个特定国家/地区获取所有用户(出于某种原因,营销人员需要了解他们的某些信息),那么在Relational Database中这样做很容易,但是在NoSQL Database中却不是很有效,因为您必须获取每个用户,解析所有数据并进行过滤。

我并不是说这是不可能的,但是它变得更加棘手,如果您要搜索NoSQL条目的数据,我想那不是那么有效。

您可以为每个国家/地区创建一个密钥,以存储该国家/地区中每个用户的密钥,并通过获取存放在该国家/地区的密钥中的所有密钥来获取特定国家/地区的用户。但是我认为这种技术使复杂的数据集变得更加复杂-难以实现且不如查询SQL数据库有效。因此,我认为这不是您在生产中使用的方式。还是?

我不确定我是否会误解或忽略了一些概念或最佳实践来处理此类用例。也许您可以纠正我的陈述并回答我的问题。


16
这读起来更像是一个咆哮而不是一个问题。您似乎对键值存储相对于关系存储的优缺点有很好的了解。那么问题到底是什么呢?
JacquesB

16
这根本不是一件大事:) NoSQL数据库很棒,但是我认为关系数据库并不像某些人所说的那样糟糕。如果是我的论文,我只是想找出NoSQL数据库不是搜索“数据行”的最佳选择……或者如果我对主题的理解不正确。
Leo Lindhorst,2016年


5
但是MongoDB是Webscale![警告:包括某些NSFW语言]
杰里·科芬

5
@DevWurm:您一般不应该将键值存储与NoSQL合并。例如,谷歌的BigTable被认为是NoSQL数据库,但是您仍然可以在多个字段上搜索和创建索引。当您知道只需要在单个字段(键)上搜索时,就可以使用键值存储。
JacquesB

Answers:


40

尽管我同意NoSQL并非解决所有数据库问题的灵丹妙药的前提,但我认为您会误解一个关键点。

在NoSQL数据库中,只有一个可以有效搜索的条件-密钥。

这显然是不正确的。

例如,MongoDB支持索引。(来自https://docs.mongodb.org/v3.0/core/indexes-introduction/

索引支持在MongoDB中高效执行查询。没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的那些文档。如果查询存在适当的索引,则MongoDB可以使用该索引来限制它必须检查的文档数。

索引是特殊的数据结构[1],它以易于遍历的形式存储集合数据集的一小部分。索引存储一个特定字段或一组字段的值,按该字段的值排序。索引条目的排序支持有效的相等匹配和基于范围的查询操作。另外,MongoDB可以使用索引中的顺序返回排序的结果。

沙发床也一样(来自http://docs.couchbase.com/admin/admin/Views/views-intro.html

Couchbase视图允许索引和查询数据。

视图根据定义的格式和结构在数据上创建索引。该视图由特定字段和从Couchbase中的对象提取的信息组成。

实际上,任何自称为NoSQL 数据库而不是键值存储的东西都应该真正支持某种索引方案。

实际上,正是这些索引方案的灵活性使NoSQL大放异彩。在我看来,用于定义NoSQL索引的语言通常比SQL更具表达性或自然性,并且由于它们通常位于表外部,因此您无需更改表架构即可支持它们。(并不是说您不能在SQL中做类似的事情,但对我来说,感觉像是涉及到更多的跳跳)。


13
“ ...由于它们通常位于表外部,因此您无需更改表模式即可支持它们。” 在SQL数据库中的非聚集索引和noSQL数据库的索引之间,情况相同,对吗?
Jirka Hanika

相当可靠的答案。我还要补充一点,NoSQL是基于这样一个想法的:如果您想提高速度,应该在没有联接的情况下通过主键发出90%++的请求,并且如果您想做其他事情,那么您将表扫描和二级索引的世界,它们始终具有性能和规模限制。一旦您搜索了索引或创建了一个索引束,您就根本不在可以达到速度的区域(只有几百万行的小型数据集除外)。如果您以很少使用替代查找的方式进行编码,那么最终将获得一个非常可靠的操作系统。
Brian Bulkowski

40

通常,如果您的工作流程非常适合关系数据库查询,那么您会发现关系数据库是最有效的方法。它是重言式的,但却是真实的。

许多NoSQL拥护者会宣称,实际上许多工作流都被压缩为一种关系形式,并且在进行这种按摩之前会更加有效。这项索赔的有效性很难确定。显然,SQL查询对作业进行了很好的描述。我可以根据经验说,使用NoSQL可以以几乎相同的效率(甚至更高)来完成我的特定关系编程任务。但是,这是基于狭窄经验的非常主观的陈述。

我感觉NoSQL方法的销售主要来自大型数据库的假设。数据库越大,您就必须修饰工作流程越多,以支持更大的数据集。NoSQL在支持这种修饰工作方面似乎更好。因此,数据库越大,NoSQL的功能就可能越重要。

要使用该示例,在SQL中按国家/地区查询与对所有用户进行NoSQL扫描一样慢,除非您明确告诉SQL users按国家/地区对表进行索引。NoSQL可以做同样的事情,您可以创建索引的有序键值集合(就像SQL在后台一样)并进行维护。

区别?SQL引擎具有内置表索引的概念。这意味着您要做的工作更少(您要做的就是向表中添加索引)。但是,这也意味着您的控制较少。在大多数情况下,失去控制是可以接受的,以换取SQL引擎为您完成工作。但是,在海量数据集中,您可能需要与典型的SQL ACID模型不同的一致性模型。您可能要使用支持最终一致性的BASE模型。在SQL中这可能非常困难,因为SQL引擎正在为您完成工作,因此必须由SQL引擎的规则来完成。在NoSQL中,这些层通常是公开的,可让您对其进行破解。


2
在您的示例中,您断言“ 按国家/地区进行SQL查询的速度与对所有用户的NoSQL扫描一样慢 ”。您是否有证据支持这一点?问题中描述的NoSQL是键值对,因此您必须扫描值以获取国家/地区的位置,然后进行比较。SQL已经知道该数据在哪里,因此可以直接从磁盘中选择数据(跳过不需要的内容),然后检查该值。如果国家/地区是外键,则是快速整数比较。但这不会总是更快,因为您从磁盘上拉的次数更少并且检查更快。
Trisped'1

1
@Trisped很难提供证据,因为NoSQL是一种方法,而不是产品(与SQL相同)。但是,值得注意的是,NoTable实现BigTable具有列的概念,就像SQL表一样。它的列概念使您可以通过知道在哪里看来跳过数据,可以将其应用于任一实现。
Cort Ammon

16

NoSQL是一个模糊的术语,因为它基本上涵盖了所有非关系数据库系统。

您所描述的是一个键值存储,它是一种数据库,在该数据库中,一堆数据存储在一个键下,如果您知道该键,则可以快速查找。如果您知道确切的密钥,这些数据库将非常快,但是正如您自己说的那样,如果您需要搜索或筛选数据上的多个属性,它将很慢且麻烦。

在他们的头脑中,没有人会声称键值存储一般可以代替关系数据库。但是,在某些特殊情况下,键值存储非常适合。键值存储通常用于缓存,因为您通常按ID缓存项,但不需要对缓存执行临时查询。例如,#1位点本身使用的Redis(键值分贝)广泛,但仅用于输出缓存。底层规范数据仍保留在关系数据库中。

因此答案很明显:如果只需要使用一个键来存储和查找,则使用键值存储。否则,请使用其他类型的数据库。并且,如果您有疑问,请使用关系数据库,因为这是最通用的数据库,而NoSQL数据库通常针对非常特殊的用例进行了优化。


2
“ NoSQL是一个模糊的术语,因为它基本上涵盖了所有非关系数据库系统。” - 这不是真的。它涵盖了不是SQL数据库的所有数据库系统。有一些不使用SQL的关系数据库,例如Rel和Tutorial D(旨在更紧密地遵循关系模型而又不像SQL那样“软化”的数据库)。有超关系数据库。实际上,NoSQL的意思是“不仅仅是SQL”,这意味着“不要自动采用SQL,而是选择与您的日期结构相匹配的正确数据库模型……这很可能就是SQL。”
约尔格W¯¯米塔格

@JörgWMittag根据您的定义,如果我选择MySQL是因为它是与我的数据匹配的最佳数据库,那就是有效的NoSQL解决方案。

1
@JörgWMittag:Thee不是NoSQL的正式定义,但是通常它确实是指非关系数据库系统。实际上,“ Not Only Sql” -backronym实际上是一种较新的retcon,用于抵消不可避免的炒作反弹。但是通常使用NoSQL来描述MongoDb,Bigtable等系统,而不是教程D(甚至不是数据库)。
JacquesB

2
@JörgWMittag NoSQL的原意是“非SQL”或“非关联”。“ Not Only SQL”将是NOSQL,因为它是首字母缩写词,而不是单词“ No”和首字母缩写词“ SQL”的组合。它作为一种反对将所有内容都放入数据库的通用做法而流行(如Wikipedia文章所述)。正如您所评论的那样,该领域现在要复杂得多。
Trisped

完全同意。看来NoSQL的主要模式是键值(例如Redis)文档存储(例如Mongo)和图形(例如Neo4J)。我希望人们放弃NoSQL并使用其中一个术语。
paj28 '16

10

您对关系数据库的主张都是正确的,直到您拥有如此多的数据为止,再也无法在单个服务器上容纳它的副本。然后,您开始遇到各种有趣的问题。如何拆分表,以便大多数查询可以在单个服务器上运行?您制作多少个数据副本?您如何处理这些副本之间的不一致之处?您如何将用户的数据保存在地理位置相对较近的数据中心中?

这些目标经常相互冲突。许多Twitter用户关注来自世界各地的人们。Twitter的数据库是否应该在地理上优化以读取或写入推文?

事实证明,当您处理这种规模的问题时,便会开始发明解决方案,添加冗余并施加非常类似于NoSQL数据库的限制。如果您可以将所有数据放在一个盒子中,那么您将得到限制,而无需任何好处。


@Daniel将RAM读取到10TB会花费一些时间……几个小时会是一个很好的结果。从灾难中恢复将是灾难性的。
2016年

1
我想说大数据无疑是NoSQL数据库发挥作用的领域之一,但这只是其中之一。还有许多其他原因使NoSQL数据库更适合解决问题。如果您有数据图,则使用图数据库是有意义的;如果您有XML数据,则使用XML数据库是有意义的。选择合适的数据库时,不仅大数据而且数据模型也是一个重要标准(当然,根据问题,很多时候SQL数据库是正确的选择)
dirkk 2013年

5
错了 作为编程方法,分片在大型数据库中已经成为标准,并且一些数据库支持具有透明数据共享功能的集群(Oracle RAC)。您如何看待所有银行?通过正确的设置,您几乎不会还原备份-这是真正的“ 2个数据中心被烧毁”方案。是的,曾经在30TB数据库上工作过-我们没有问题。
TomTom

是的,关系数据库执行透明的数据分片和群集,但是如果您关心优化性能,则它是一个非常漏水的抽象。
Karl Bielefeldt

5

NoSQL数据库与“ No SQL” 无关。

他们是要承认您不能拥有一个始终如一支持复杂事务具有持久性的大规模数据库。

在普通的关系数据库中,所有索引会在事务范围内自动保持更新,因此可用于任何查询。

在NoSQL数据库中,程序员负责维护许多索引,并且假定索引将始终过时。

例如:

  • 按税收人数索引可能包含一些从未完成税收注册过程的人员。
  • 因此,使用索引的代码必须能够应付不完整的税收注册
  • 另一种选择是在某些情况下需要注册的人不在索引中。(因此,您的设计必须处理没有一致的数据,并决定如何使数据不一致。)

举一个真实的例子,亚马逊宁愿给我显示一本书的过时描述,而不是通过等待106台计算机确认已取出正确的锁来延迟网页的显示。

因此.....

如果单个正常的关系数据库可以保存您的所有数据并足够快地处理每个事务,以致锁定不会阻止您的系统执行有用的工作,那么关系数据库是最佳选择。

但是,一旦您开始考虑使用多个关系数据库或拆分事务以避免锁定错误,就走上了使用“ NoSQL”数据库时必须解决的问题。

由于“ NoSQL”数据库不会隐藏这些问题,因此在扩展系统时,它们可能成为最佳选择。 但是请记住,Stackoverflow仍然使用关系数据库来存储其所有数据,并且在缓存层中使用NoSQL的程度有限-因此在被迫使用NoSQL来存储数据之前,您必须非常庞大。


最后一个花絮非常有趣-您是否有指向一些meta SO网站的链接,以供感兴趣的读者点击以了解关于SO(非)使用NoSQL的信息?谢谢!
kcrisman


2

关系数据库经过优化,可以有效地搜索数据行中的任何值。

不要混淆连续搜索“任何”值与连续“每个”值的能力。最有效的方法需要一个或多个索引。您可能使索引包括所有字段,但是您只是阻碍了进行需要更改索引的更改(插入,更新,删除)的能力。您(或您的DBA)必须了解数据,用法,瓶颈等。


一个很好的例子就是保存聊天记录。可能需要将它们与其他数据相关联并进行各种分析,但是在聊天会话本身期间,用户会更快地体会到一些没有RDBMS所有开销(例如事务或约束)的东西。
JeffO

-1

已经有很多答案,但是我只想添加我的摘要。

显然,NoSQL概念涵盖了组织磁盘上的数据,内存中的数据以及通过查询语言公开数据的各种不同方法(有些甚至类似于SQL!)。我认为,强大的力量来自于各种系统,因此您可以选择最适合工作的工具。但是仍然希望您可以通过几种不同的解决方案满足多种需求,而您并不想管理多种不同的系统。

关系数据库可以使您走得更远并且是一种可靠的技术,但是就像数据库一样,您可能希望根据每个项目的需求选择编程语言(但也要考虑团队的经验)。


-2

我已经使用两年的沙发床了。它主要用于内容管理和配置。

对于分层关系,当您可以可视化它们时更容易管理。对于大多数读数据,在许多情况下,编辑JSON比编写UPDATE语句更容易。实际上,不需要程序员来编辑JSON。SQL提供行和列,然后您必须将它们映射到某种对象结构中。

您还可以提高性能,因为您不会在复杂查询中加入10-20个表。Couchdb视图非常快,因为它们基于的javascript不会在查询时执行。

大多数程序员都了解Javascript,并且大多数程序员偶尔也会遇到SQL问题。

在Couchdb中,视图可以认为是JSON文档的摘要。视图数据的结构由您决定(不受原始层次结构的约束)。

我不会将Couchdb用于高度事务性的数据,但是对于具有部件爆炸类型结构的半静态数据,它比SQL更容易使用。

但是请注意,没有明确的“规范化”可应用(尽管避免重复数据是一个值得的目标),并且本质上存在类似于乐观锁定的“乐观”更新策略。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.