MongoDB与MySQL:如何选择

MongoDB与MySQL:如何选择,第1张

MongoDB和MySQL分别是领先的开源NoSQL和关系数据。哪个最适合您的应用程序?

在1990年代的互联网泡沫时期,用于Web应用程序的一种通用软件堆栈是LAMP,它最初代表Linux(OS),Apache(Web服务器),MySQL(关系数据库)和PHP(服务器编程语言)。MySQL是首选的数据库,主要是因为它是免费的开源代码,并且具有良好的读取性能,非常适合从数据库动态生成网站的“ Web 2.0”应用程序。

之后,代表MongoDB(文档数据库),Express(Web服务器),AngularJS(前端框架)和Node.js(后端JavaScript运行时)的MEAN堆栈开始流行。除其他原因外,MEAN堆栈很有吸引力,因为您需要了解的唯一语言是JavaScript。与等效的LAMP堆栈相比,它还需要更少的RAM。

MySQL AB的Monty Widenius和David Axmark最初于1994年开始开发MySQL。产品名称中的“ My”是指Widenius的女儿,而不是英语单词“ my”。MySQL旨在与mSQL(又名Mini)兼容。 SQL),并添加了SQL查询层和开放源代码许可(实际上是专有和GPL双重许可)。MySQL的公共发行版于1996年底开始,并且每年或每两年持续发行一次。MySQL是当前最受欢迎的关系数据库。

Sun Microsystems于2008年以10亿美元的价格收购了MySQL AB,Oracle于2010年收购了Sun。在Oracle收购MySQL的广泛关注中,Widenius在收购Oracle之前就将MySQL 5.5合并到了MariaDB中。MariaDB努力维护与Oracle MySQL版本的兼容性。

与功能更强大的商业关系数据库(例如Oracle数据库,IBM DB / 2和Microsoft SQL Server)相比,MySQL最初是一个相当低端的关系数据库,尽管它足以成为动态网站的后备存储。多年来,它增加了您希望从关系数据库获得的大多数功能,包括事务,参照完整性约束,存储过程,游标,全文索引和搜索,地理索引和搜索以及群集。

尽管MySQL现在支持“大数据库”功能,例如主从部署,与Memcached一起使用以及水平分片,但它仍通常用于中小型部署。将MySQL扩展到多个从属服务器可以提高读取性能,但是只有主服务器才能接受写请求。

AWS提供了两种形式的MySQL即服务,即Amazon RDS和Amazon Aurora。后者具有更高的性能,可以处理TB级的数据,更新副本的延迟时间更短,并且可以直接与Oracle数据库和SQL Server竞争。

MongoDB是高度可伸缩的 *** 作文档数据库,可在开源版本和商业企业版本中使用,它可以在本地运行或作为托管云服务运行。托管云服务称为MongoDB Atlas。

MongoDB无疑是NoSQL数据库中最受欢迎的数据库。它的文档数据模型为开发人员提供了极大的灵活性,而其分布式体系结构则提供了很好的可伸缩性。因此,通常选择MongoDB用于必须管理大量数据,得益于水平可伸缩性并处理不适合关系模型的数据结构的应用程序。

MongoDB是一个基于文档的存储,在其之上还具有一个基于图形的存储。MongoDB实际上并不存储JSON:它存储BSON(二进制JSON),该扩展了JSON表示(字符串)以包括其他类型,例如int,long,date,浮点,decimal128和地理空间坐标。

MongoDB可以使用数据的类型生成正确的索引类型,从而在数据的单个副本上生成多模式图形,地理空间,B树和全文本索引。MongoDB使您可以在任何文档字段上创建索引。MongoDB 4具有多文档事务,这意味着即使必须标准化数据设计,您仍然可以获得ACID属性。

默认情况下,MongoDB使用动态模式,有时称为无模式。单个集合中的文档不需要具有相同的字段集,并且字段的数据类型可以在集合中的不同文档之间有所不同。您可以随时使用动态模式更改文档结构。

但是,可以使用架构治理。从MongoDB 3.6开始,MongoDB支持JSON模式验证,您可以在验证器表达式中将其打开。

在LAMP和MEAN堆栈上存在很多变化。例如,您可以在Windows(WAMP)或MacOS(MAMP)上运行而不是Linux OS。您可以运行IIS(WIMP),而不是Windows上的Apache Web服务器。

您可以运行PostgreSQL或SQL Server,而不是LAMP堆栈中的MySQL关系数据库。如果您需要全球分布,则可以运行CockroachDB或Google Cloud Spanner。可以使用Perl或Python代替PHP语言。如果要使用Java或C#进行编码,则需要考虑单独的堆栈系列。

您可以运行Couchbase或Azure Cosmos DB以获得更好的全局分布,而不是MEAN堆栈中的MongoDB文档数据库。可以使用十二个Node.js Web服务器框架中的任何一个来代替Express 。除了AngularJS前端框架,您还可以运行Angular 2或React。

选择数据库时要问的最重要的问题是:

这些问题中的几个会趋于缩小数据库的选择范围,但是与制定LAMP堆栈时相比,我们有更多选择。如果您要构建一个应用程序,并且该应用程序必须在99.999%的时间内对全世界的用户都具有高度的一致性,那么只有少数几个数据库适合您。如果您的应用程序将在工作日的上午9点至下午6点在一个国家/地区使用,并且可以容忍最终的一致性,那么几乎所有数据库都可以使用,尽管某些数据库对于开发人员和 *** 作员而言更容易,而某些数据库则可以为您的主要使用场景提供更好的性能。

虽然LAMP和MEAN堆栈一次是Web应用程序的良好解决方案,但现在都不是最佳选择。而不是盲目采用任何一种,您应该仔细考虑用例,并找到一种可在可预见的将来为您的应用程序服务的体系结构。

您什么时候需要关系数据库(例如MySQL)用于新应用程序?除了对标准SQL的明显支持外,关系数据库本身将数据强制为具有一致的强类型字段的表格模式,并且只要您利用规范化就可以帮助您避免数据重复。

另一方面,如果您还需要偶尔的自由格式文档,则MySQL和许多其他关系数据库也支持RFC 7159定义的JSON数据。如果您还想使用XML文档和XPath或XSLT,则大多数关系数据库都可以提供这种能力。

您何时需要像MongoDB这样的文档数据库?如果您的主要用例需要允许使用自由格式的数据,在文档之间更改类型的字段,随时间变化的架构或嵌套的文档,则NoSQL数据库将满足要求。另外,如果您的应用程序是用JavaScript编写的,那么文档数据库的JSON格式将很自然。

作者: Martin Heller是InfoWorld的特约编辑和审稿人。他曾担任Web和Windows编程顾问,从1986年至2010年开发数据库,​​软件和网站。最近,他担任Alpha Software技术和教育副总裁以及Tubifi董事长兼首席执行官。

如何选择数据库

一般来讲,数据分析的查询不会直接从生产环境的数据库来读取数据,一方面是影响线上性能,另一方面是OLTP的表结构设计更多的是面向插入,而不是读取。如何来选择合适的数据库做数据分析呢?本文给出了四方面的考量,抛砖引玉。

1. 客户要分析什么样的数据

2. 客户分析的数据量是多少

3. 客户工程师团队技术背景,运维能力

4. 预期的数据分析的响应时间

客户要分析什么样的数据

上文已简单介绍了关系型数据库和非关系型数据库的区别,这里就不再赘述。下图是一个简单的分类。

客户分析的数据量是多少

用户需要分析的数据量越大,就越应该考虑非关系型数据库。

上图给出了选择合适数据库的思路。不同的数据库处理数据的能力不同。如果你打算处理1T以下的数据,那么可以使用Postgres或者MySQL,但如果数据量增大到5T以上,需要在扩展性方面下些功夫。当然,各个数据库厂商也在不断的优化性能,像微策略这样的BI平台也在紧跟各个厂商的步伐,对各个数据库的特性进行深入的研究,把数据库新特性运用到BI产品中,给客户深入分析各个数据库的优势劣势, 确保为客户提供最大的投入产出比。

客户工程师团队技术背景,运维能力

客户需要了解自己技术团队的人员结构、技术偏好。如果有强大的技术团队,关系型和非关系型数据库都可选择。一般来讲,非关系型数据库需要更多管理维护的时间。如果没有足够的运维人员,可以选择像Postgres, Google SQL (a hosted MySQL option) 或者 Segment Warehouses (a hosted Redshift) 这样的数据库,要优于Redshift, Aurora or BigQuery等。如果运维人员充足,可以选择Redshift等,为以后强大的扩展性做好准备。从另一个角度来说,分析半结构化数据是也是比较普遍的需求。这样就对数据科学家的技能提出了更大的挑战。面向对象的编程背景,精通Python/R 等语言也是对客户工程师团队的重要考量。

预期的数据分析的响应时间

比如像欺诈检测、系统监控等实时数据分析需要的数据分析相应时间有严格的要求。其他的数据分析比如像电子商务网站的用户留存分析等,并没有实时响应的严格要求。客户需要结合自己的用户场景,来选择合适的数据仓库。如果绝大部分的分析是基于已有的数据,对数据的实时性没有特别高的要求,建议用户选择像Redshift or BigQuery这样的数据库,对数据的读取和合并做了大量的优化。如果客户对实时性要求非常高,可以考虑非结构化的数据库方向和内存数据库方向。

当然,选择用什么样的数据库做数据仓储,只是第一步。以实时分析为例,需要从数据仓库,数据湖,计算引擎等架构方面做出通盘的考虑。

如何选择数据库

柳树

公众号:柳树的絮叨叨

关注他

30 人赞同了该文章

我们正在做一个电子书小程序。

1.0 层次模型数据库

用户购买,生成订单,订单详情里有用户购买的电子书:

一层一层铺开,一对多,这是「层次模型数据库」(Hierarchical Database)。

2.0 网状模型数据库

一笔订单可以购买多本电子书,一本电子书也可以被多笔订单购买:

这就形成了「多对多」的「网状模型数据库」(Network Database)。

上面讲的两种数据库,也许你听都没听过。

我们用的,是「关系模型」,而非上面的「层次模型」或者「网状模型」。

为什么?

你会说,这样不方便遍历所有订单。

并不会,再加一个根节点就好:

你会说,这样查找效率很低。

也不会,因为可以优化下数据结构,比如换成 B+ 树。

为什么我们从一开始就在用「关系模型数据库」?

3.0 关系模型数据库

无论是层次模型还是网状模型,程序员看到的,都是实实在在的物理存储结构。

查询时,你要照着里面的数据结构,用对应的算法来查;

插入时,你也要照着数据结构,用对应算法来插入,否则你就破坏了数据的组织结构,数据也就坏掉了。

因为我们都没用过前面两种数据库,所以觉得「关系模型数据库」(以下简称 RDB)的一切都理所当然,但其实,它做出了一个革命性的变革:

用逻辑结构(logical representation of data)代替物理结构(physical representation of data)

所谓「逻辑结构」,也就是我们经常看到的「表格」,User 是一张表格,Order 是一张表格,Book 又是一张表格,它们之间的关系,用 id 来关联,这些 id,可能是 number 类型,也可能是 string 类型

但你看到的,不一定就是实际的,你看到的只是让你方便理解的「逻辑结构」,真实数据自然不是这样按表格来存储,表格无异于一个数组,数组查询是很慢的。

真实的「物理结构」,也许还是像「层次模型」和「网状模型」一样,是复杂的数据结构。

但到底是怎样的数据结构,你都无需关心,你只需把它想象成一张「表」去 *** 作,就连可视化工具,都会帮你把数据可视化成表,来方便你理解。

这个观念的提出,来自于 1970 年 Codd 的一篇论文,A Relational Model of Data for Large Shared Data Banks:

Future users of large data banks must be protected from having to know how the data is organized in the machine (the internal representation). 

Activities of users at terminals and most application programs should remain unaffected when the internal representation of data is changed and even when some aspects of the external representation are changed. 

—— Codd

Codd 的这种思想,其实就是经济学里提到的:分工产生效能。

程序员们不需要直接和物理结构打交道,只负责告诉数据库,他想做什么,至于数据是如何存储、如何索引,都交给数据库,最终他们看到的就是一张张特别直观、特别好理解的 excel 表格。

而数据库则把维护物理结构的复杂逻辑,交给了自己, 对程序员屏蔽了复杂的实现细节。

开发时写的代码少了,耦合性降低了,数据也不容易损坏,也就提高了生产效率(productive)。

一切能用同样的耗能,带来更多效能的技术,都会被广泛使用。

NoSQL

那后来为什么又有了 NoSQL 呢?

在 RDB 被发明的时代,软件多用于大型企业,比如银行、金融等等,人们对数据的要求非常纯粹:准确、可靠、安全,让数据按照期望,正确的写入,不要给老子算错钱就好,于是有了具有 ACID 特性的事务:原子性、一致性、隔离性和持久性。

那时候用网络的人很少,通过终端来访问客户端的人,更少,自然的,数据库的数据量和访问量都跟现在没法比,一台机器,足矣,最多再来个一主多从:

后来,你知道的,每个人手里都有个手机,每分每秒,都有成千上万的数据,写入你的数据库、从你的数据库被查出,于是有了「分布式」,有了 BASE 和 CAP。这时候,RDB 就会发现,自己之前的那一套 ACID,竟然有点作茧自缚了:

为了保证事务的隔离性,要进行加锁,在分布式的环境下,就要对多台机器的数据进行加锁;

为了保证事务的原子性,在机器 A 的 *** 作和在机器 B 的 *** 作,要么一起成功,要么一起失败;

…...

这些都要去不同节点的机器进行通讯和协调,实现起来非常复杂,而且要付出更多的网络 IO,影响性能。

ACID 在分布式系统上实现起来就会变得难以实现,即使实现了,也要付出很大的性能成本,于是才有了后来的各种「分布式一致性协议」,Paxos、Raft、2PC …… 而 Mysql 也提供了各种方案来实现分布式,当然,这些方案自然是很复杂的,比如 「NDB Cluster」 :

而 NoSQL 则没有这么多承诺,它的一致性,一般都是最终一致性,当然你可以选择强一致,那自然就要付出点性能作为代价,当然你还可以弱一致,这样会更不安全,但是更快,一切取决于你对数据的要求。

除此之外,RDB 的「数据库范式」(Database Schema),也成了限制扩展性的瓶颈。为了避免数据冗余导致的各种问题(占用空间、删除异常、更新异常等等),我们在设计关系模型时,通常都是按照最小单位来设计的。

什么叫最小单位,比如用户有地址和爱好,那么在正确设计的关系模型(比如 3NF)里,这就是三张表:

如果这三张表被分散在不同的机器,那进行关联查询时,就需要多次跨机器的通讯;

而对于 NoSQL,这三类信息,都可以利用 Json 格式的数据,将它们存放在一起:

完整的存储进去,完整的取出来,不需要额外的 *** 作。

NoSQL 比 RDB 有更强的扩展性,可以充分利用分布式系统来提升读写性能和可靠性。

这不是谁设计好坏的问题,而是跟他们要解决的问题有关:RDB 诞生于互联网萌芽的时代,那时数据的准确、可靠是最重要的,而 NoSQL 诞生于互联网快速发展普及的时代,大数据、分布式、扩展性成了数据库的另一个重要特性。

总结一下:

RDB 首先得是准确、可靠,然后才向更高的「可拓展性」发展;

而 NoSQL 生而分布式,可拓展性强,然后才向更高的「准确性」发展。

NoSQL ,not only SQL,其实就是对那种打破了 RDB 严格事务和关系模型约束的那些数据库的泛指,而随着要解决的问题的不同,又诞生了各种各样的 NoSQL。

首先是「列式数据库」(Column-oriented DBMS),数据量上去了,我们想分析网站用户的年龄分布,简单说,就是你需要对同一个特征进行大数据量的分析统计,于是把原来 RDB 的「按行存储」的范式打破,变成了「按列存储」,比如 HBase;

然后你发现有些数据变动不是很大,但是经常需要被查询, 查询时还要关联很多张表,于是你把这些来自不同表的数据,揉成一个大对象,按 key-value 的格式存起来,比如 Redis;

再后来你需要对博客内容进行相关性搜索,传统 RDB 不支持相关性搜索,最重要的,还是扩展性差,增加机器的带来边际效益有限,于是有了「全文搜索引擎」,比如 Elasticsearch;

除此之外,还有「文档数据库」、「图形数据库」……

没有一种数据库是银d。

总结

这篇文章的题目是「如何选择数据库」,这是困扰很多人的问题,那么多数据库,到底要选什么好?

可是当你问出这样一个问题时,其实你是在问一种「手段」。我现在要做这样一个需求,用什么数据库可以帮我实现它?

但其实你需要的不只是一种「手段」,因为如果对方甩给你一个冷冰冰的名字,Mysql、Elasticsearch、MongoDB,你肯定会问,凭什么?

你需要的,是一种「解决方案」。如果你需要数据十分严格准确,分毫不差,那我会推荐你采用「事务」和「关系模型」来处理数据;如果你需要数据能够被大量读取和写入,那我会推荐你扩展性强的「分布式」;如果你的数据经常是整个读取、整个更新的,那「关系模型」就没有「文档模型」适合你。

「事务」、「关系模型」、「分布式」、「文档模型」等等,这些就是「解决方案」,知道用什么「解决方案」,用哪个数据库,自然水到渠成。

正如一位大牛说的:

设计实践中,要基于需求、业务驱动架构。无论选用 RDB/NoSQL,一定是以需求为导向,最终数据存储方案必然是各种权衡的综合性设计。

用户不会因为你用了 Mysql 或者 MongoDB 而使用你的软件,毕竟绝大多数用户都不知道 Mysql 和 MongoDB 是什么玩意。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9680532.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存