目录
1.简介
2. RDBM系统的优势
3. NoSQL运动的新时代
4.表格,文档,图形,键/值
5. MySQL和MongoDB:明智的决策
5.1。
强制模式与无模式
5.2。
归一化与复制
5.3。
关系与参考
5.4。
事务与原子更新
5.5。
SQL与JSON
5.6。
存储过程与脚本
5.7。
GROUP BY与汇总
5.8。
集群和分片/分区
5.9。
全文搜索
5.10。
发展历程
5.11。
监控与诊断
5.12。
安全
5.13。
权衡而非战斗
5.15。
MySQL还是MongoDB?
5.16。
MySQL和MongoDB:如今
6。结论
1.简介
可以公平地说,作为IT专业人员,我们生活在数据管理时代的黄金时代。 随着我们的软件系统在无数的可伸缩性和可用性要求的驱动下变得越来越复杂和分散,多年来使用的传统解决方案开始落后。
本教程的目的是对这两种数据管理解决方案进行公平的概述:以MySQL为代表的成熟且广泛使用的关系数据库,以及一个新的子代MongoDB , MongoDB则代表了新一代的数据存储。 决不是一场与明确赢家的战斗。 相反,其目的是通过研究MySQL和MongoDB的功能,讨论每个开发人员具有的不同保证和限制,来帮助开发人员做出选择并找到适合其应用程序的合适方法。
2. RDBM系统的优势
数据管理软件的历史和发展并不是花费时间的特别令人兴奋的话题。 在相当长的一段时间里,关系数据库管理系统一直处于领导地位,多年来,显而易见的选择是MySQL , PostreSQL或Oracle ,仅举几例。 SQL (及其特定于供应商的方言)是查询关系数据存储的实际标准,根据定义,每个后端软件开发人员都必须学习并至少了解其一些基础知识。 直到最近,当出现了一系列新的数据管理系统时,它的效果都出乎意料地好,这种现象也被称为NoSQL (或不仅SQL )运动。
3. NoSQL运动的新时代
如今,现代软件系统在数据量和请求/事务吞吐量要求方面面临的挑战表明,关系数据存储通常成为瓶颈,从而对整个系统的可伸缩性施加了限制。 传统上,解决此问题的方法是购买一个更大的设备(所谓的垂直可伸缩性 ),但是在某些时候,要付出的代价变得非常非常高,这使整个系统非常昂贵且不切实际。
业界一直在积极寻求一种便宜的方法来构建复杂的分布式系统,而使用水平可伸缩性 。 它还意味着想出关系数据存储的替代方案,它们也可以水平扩展。 那一刻, NoSQL运动开始了。
4.表格,文档,图形,键/值
关系数据模型以元组和关系(最好称为表)表示所有数据。 结构化数据非常适合此模型,并且很长一段时间没有其他可行的替代方案。 随着NoSQL的发展,开发了许多替代数据模型,催生了一大堆专用数据存储系统。
NoSQL解决方案可以分为几种不同的类别。 文档数据存储区旨在存储,查询和管理文档(半结构化数据)。 这类更成熟的代表包括CouchDB , Couchbase , MongoDB , OrientDB和HyperDex 。 键/值数据存储区旨在存储,查询和管理关联数组(也称为字典或哈希)。
该类别中使用最广泛的代表包括DynamoDB , FoundationDB , HyperDex , MemcacheDB , Redis , Riak , Aerospike和OrientDB 。 图形数据存储区旨在有效地存储和操作图形结构。 该类别的著名代表包括Neo4J , InfiniteGraph , GraphBase和OrientDB 。 最后但并非最不重要的一点是, 宽列数据存储正在采用混合方法(将键/值数据存储和传统关系数据存储的某些特征结合在一起)。 该类别中最先进的代表包括Accumulo , Cassandra和HBase 。
请注意,上面介绍的不同NoSQL数据存储列表远非完整,它仅包含最知名和使用最广泛的名称,但是还有更多的名称。
5. MySQL和MongoDB:明智的决策
足够的介绍,让我们继续进行更实际的事情。 在本部分的教程中,我们将研究使用MySQL和MongoDB进行应用程序开发过程的各个方面,还将花费一些时间来讨论部署和监视。 目的是讨论每个数据存储区所做的取舍和设计决策,并分析它们如何改变我们开发应用程序的方式。 此外,本教程的另一个目的是在考虑到应用程序体系结构,数据访问模式和存储要求的情况下,帮助您确定何时MongoDB可能是比MySQL更好的选择(反之亦然)。
如我们现在所知 , MongoDB是文档数据存储。 它存储JSON样式的文档,这些文档被分组到集合中。 数据库在MongoDB数据模型层次结构的顶部(请参阅官方文档以获取全面的详细信息)。 MongoDB的当前生产就绪版本为3.0.4 。
从另一方面来看, MySQL是关系数据存储。 数据存储在包含列的表中。 这些表被分组到数据库中(请参阅官方文档以获取全面的详细信息)。 MySQL的当前生产就绪版本为5.6.25 。
MySQL支持多个存储引擎 ,每个存储引擎都有自己的用途,并且具有其他存储引擎不具备的某些功能。 在本教程中,我们假设使用InnoDB存储引擎,因为它是默认的,并且是最通用的存储引擎,除特殊用例外,建议使用它。
强制模式与无模式
MySQL作为关系数据存储区,其数据模型需要严格的架构:所有表均应使用定义的列来创建。 只有这样,才能使用SQL语言存储和查询数据。 由于每次需要修改数据模型时,都应先更改架构,然后再迁移数据,这使开发和部署过程变得有些复杂。 这是使用MySQL Shell和SQL语言创建新数据库,新表并向其中插入一行所需的典型步骤示例:
CREATE DATABASE tutorial;
USE tutorial;
CREATE TABLE chapters (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL
);
INSERT INTO chapters (title) VALUES ("MySQL and MongoDB: trade-offs, not battles");
相反, MongoDB不会在集合中存储的文档上强加任何架构。 处理该任务成为应用程序的责任, MongoDB唯一的限制是受支持的数据类型 。 由于可以立即使用MongoDB来存储任何形状的JSON文档,因此极大地加快了开发过程。
文档的结构可能会随着时间的推移而发展和变化,不同代的文档可能会共存于同一集合中。 如有必要,应由应用程序开发人员决定如何执行数据清除或迁移。 让我们看一下如何使用MongoDB shell来完成创建新数据库,新集合以及向其中插入一个文档的相同步骤:
use tutorial
db.chapters.insert({
"title": "MySQL and MongoDB: trade-offs, not battles"
})
值得一提的是,即将发布的MySQL 5.7版本(目前处于发布候选阶段)引入了本机JSON支持。 通过引入这种新的JSON数据类型,可以在MySQL中组合强制模式和无模式数据。
归一化与复制
关系数据库领域的规范化是组织表以最小化数据冗余的过程。 它涉及将表分解为冗余程度较小(和较小)的表,而不会丢失数据。 它还假定在旧表中定义外键,引用新表的主键。 例如,这是在MySQL中创建两个表的方式,其中books表引用authors表:
CREATE TABLE authors (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL
);
CREATE TABLE books (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
author_id INT NOT NULL,
FOREIGN KEY (author_id) REFERENCES authors(id)
);
INSERT INTO authors (name) VALUES ("Michael Kofler");
INSERT INTO books (title, author_id) VALUES ("The Definitive Guide to MySQL 5", 1);
MongoDB的规范化已过时。 取而代之的是,仔细的数据建模和一定程度的数据重复是最大程度地利用文档数据存储的方式。 在修改的情况下,决定数据重复级别并使所有数据片段保持同步也是应用程序的责任。 例如:
db.books.insert( {
"title": "The Definitive Guide to MySQL 5",
"author": {
"name": "Michael Kofler"
}
})
关系与参考
在规范化的数据库中, SQL的JOIN子句通常用于合并来自两个或多个MySQL表的记录(也有其他技术,但总的来说,它们实际上导致相同的结果)。 例如:
SELECT * FROM books b INNER JOIN authors a ON a.id = b.author_id;
MongoDB支持文档引用,但不支持联接:要解析引用,应执行其他查询(导致在关系世界N + 1查询中声名狼藉)。 例如,在下面的代码段中,我们将插入对books集合中对authors集合的引用,而不是嵌入作者的详细信息:
db.authors.insert({
"name": "Michael Kofler",
"_id": 1
})
db.books.insert({
"title": "The Definitive Guide to MySQL 5",
"author": {
"$ref": "authors",
"$id": 1
}
})
必需的往返行程是为无模式的灵活性付出的代价。 但是,正如我们在“ 标准化与复制”一节中已经提到的那样,一定程度的数据复制和对数据访问模式的仔细分析可能会缓解此问题。
事务与原子更新
事务是数据管理系统针对其数据执行的逻辑工作单元。 事务的重要性封装在其基本属性中:事务必须是原子的 , 一致的 , 隔离的和持久的 (也称为ACID模型)。 MySQL是一个完全事务性的关系数据存储,对于不能容忍数据丢失或不一致的任务关键型应用程序,它是一个完美的选择。 但是,事务不是免费的:它们极大地限制了数据存储的水平可伸缩性, MySQL也不例外。
MongoDB不支持交易担保。 相反,它支持单个文档级别的原子更新。 这意味着当一个更新操作修改多个文档时,每个文档的修改都是原子的,但是整个操作不是原子的,其他操作可能会交错。 值得一提的是,可以在MongoDB之上实现类似事务的语义(使用两阶段提交技术),但是它需要非常复杂的实现。
SQL与JSON
SQL是专用于管理关系数据库管理系统中保存的数据的专用编程语言。 它是MySQL支持的唯一查询语言,并提供了一些特定于供应商的扩展 。 尽管简单,但SQL是一种非常强大的语言,它基本上由两部分组成: 数据定义语言 (DDL)和数据操作语言 (DML)。 我们已经看到了很多示例,但是让我们看一下从表中选择行的最简单也是最有用的示例:
SELECT * FROM books;
SELECT * FROM books WHERE title LIKE "%MySQL%";
在MongoDB中 ,所有内容都是一个文档,表示为JSON。 MongoDB没有专用的语言来管理文档,而是采用了非常不同的方法。 文档操作或查询是使用非常丰富的一组运算符来描述的,这些运算符与其他任何文档一样都使用JSON结构彼此组成。 这种统一的表示功能非常强大,表达力强,易于理解,而且不需要学习另一种编程语言。 大多数操作员都是不言自明和直观的,例如:
db.books.find();
db.books.find({
"title": {
"$regex": "MySQL"
}
});
存储过程与脚本
存储过程是关系数据存储的服务器端可用的一种特殊例程。 可以使用不同的编程语言来实现存储过程,但是大多数情况下,它们是使用SQL或其特定于供应商的方言编写的, MySQL就是这种情况。 通常,存储过程通过直接在服务器上执行某些逻辑来帮助提高应用程序的性能,从而需要在服务器和客户端之间发送较少的信息。 例如,这是一个非常简单的MySQL存储过程:
DELIMITER //
CREATE PROCEDURE find_books
(IN pattern CHAR(255))
BEGIN
SELECT COUNT(*) FROM books WHERE title LIKE pattern;
END //
DELIMITER ;
CALL find_books("%MySQL%");
MongoDB支持在服务器上执行JavaScript代码的形式的服务器端脚本。 这些服务器端脚本可能类似于存储过程,但其实现不只是简单的脚本,还因为它支持map / reduce范式,该范式首先由Google填充,并被大数据分析广泛采用。 本质上,通过提供用于map / reduce命令的脚本,可以跨许多MongoDB数据存储实例并行处理大型和超大型数据集。 让我们看一下非常幼稚的map / reduce脚本示例,该示例计算有多少本书的书名中带有“ MySQL”字符串:
db.runCommand( {
mapReduce: "books",
map: function() {
if (this.title.indexOf("MySQL") >= 0) {
emit("MySQL", 1);
}
},
reduce: function(key, counters) {
count = 0;
for (var index = 0; index < counters.length; ++index) {
count += counters[index];
}
return count;
},
out: { inline: 1 }
} )
与MySQL存储过程示例相比, MongoDB看起来过于冗长和复杂。 但是,一旦地图/简化范例的概念变得更加清晰,该示例将看起来非常简单,从而为应用许多数据处理,探索和分析技术开辟了一个全新的领域。
GROUP BY与汇总
在数据管理域中, 聚合函数是一种功能,其中多个数据记录的值根据特定的聚合标准分组在一起,这样就产生了具有更重要意义或度量的单个值。 SQL语言定义了一组用于执行聚合的特定子句: GROUP BY和HAVING 。 标准分组函数集包括AVG() , COUNT() , MAX() , MIN() , STD() , SUM() 。 让我们看一下MySQL shell中的GROUP BY示例:
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
publisher VARCHAR(255) NOT NULL,
product VARCHAR(255) NOT NULL,
price NUMERIC (15,2) NOT NULL
);
INSERT INTO orders (product, publisher, price) VALUES
("The Definitive Guide to MySQL 5", "APress", 37.36),
("MySQL Cookbook", "O’Reilly", 49.65),
("Learning MySQL", "O’Reilly", 29.48);
SELECT publisher, SUM(price) FROM orders GROUP BY publisher;
MongoDB提供了一组专门的聚合操作,可处理文档并返回计算的(或聚合的)结果。 聚合操作将来自多个文档的值组合在一起,并且可以对分组的数据执行各种操作以返回单个结果。 MongoDB中的聚合可以通过两种方式完成:使用聚合管道或单用途聚合方法和命令 。
让我们看一下我们准备演示MySQL聚合的同一示例,这次使用MongoDB的聚合管道 :
db.books.insert( {
"title": "The Definitive Guide to MySQL 5",
"publisher": "APress",
"price": 37.36
})
db.books.insert( {
"title": "MySQL Cookbook",
"publisher": "O’Reilly",
"price": 49.65
})
db.books.insert( {
"title": "Learning MySQL",
"publisher": "O’Reilly",
"price": 29.48
})
db.books.aggregate([
{ $match: {} },
{ $group: {
"_id": "$publisher",
"price": {
"$sum": "$price"
}
}}
]);
我们在“ 存储过程与脚本”部分中讨论的map / reduce命令也可以被视为进行聚合的一种方式。
集群和分片/分区
如今,数据量呈指数级增长,并且数据存储的单个物理实例通常无法以可接受的速度持久地管理如此大量的数据。 群集是一项技术,可以使许多单独的计算实例协同工作。 关于数据存储,群集与数据分片/分区并排,这是一种在多个数据存储实例之间拆分大量数据的技术。
相当长一段时间以来, MySQL已在MySQL Cluster版本中可用,该版本声称是可写伸缩,实时, 符合ACID的事务性数据存储。 MySQL Cluster建立在分布式,多主机的架构之上,该架构支持自动分片/分区并可以水平扩展以服务于读写密集型工作负载。
从历史上看, MySQL Cluster的名声过于复杂,难以配置,监视和维护。 与独立的MySQL部署相比,数据架构的设计方式应考虑到数据分片/分区,否则数据存储的性能将受到很大影响。 最后,与常规的MySQL发行版相比, MySQL Cluster具有许多限制。
MongoDB文档数据存储区支持使用分片群集的概念对分片/分区进行开箱即用。 MongoDB分片/分区的强项是配置简单。 它在水平方向上的缩放比例很好,但是有很多限制要注意。
5.8.1。 复写
复制是一种确保数据安全(通过在许多数据存储实例之间复制数据)并在许多情况下提高处理此数据的应用程序的可伸缩性和容错能力的一项重要技术。 MySQL支持传统的主/从复制 ,默认情况下是异步的,但也可以使用半同步和延迟复制模式。
MongoDB通过引入副本集来实现复制。 基本上,它是主/从复制,但是MongoDB使用了一些不同的术语。 主服务器(称为主服务器 )接收所有写操作,而从服务器(称为辅助服务器)从主服务器应用操作。 副本集支持的最大功能之一是自动故障转移 :当主副本不与副本集的其他成员通信时,副本集将尝试选择另一个成员以成为新的主副本。
公平地说,也可以配置具有自动故障转移功能的 MySQL主/从复制,但是在MySQL社区中对此功能存在一些担忧和讨论。
全文搜索
长期以来, MySQL一直支持使用特殊类型的索引实现的全文本索引和搜索。 值得一提的是,只有从MySQL 5.6版本分支开始, InnoDB存储引擎才提供全文索引支持。
有趣的是,可以使用自然语言搜索(短语搜索),布尔搜索(术语搜索)在MySQL中进行全文搜索,在布尔搜索中,要搜索的单词可能标记为“必须存在”或“必须不存在”,并且可以进行查询扩展搜索(对自然语言搜索的略微修改)。 但是,目前在集群MySQL部署中不支持全文本索引(有关MySQL Cluster的简要讨论,请参见“ 集群和分片/分区”部分)。 让我们看一个简单的例子:
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
product VARCHAR(255) NOT NULL,
description VARCHAR(255) NOT NULL,
FULLTEXT product_description (product, description)
);
INSERT INTO products (product, description) VALUES
("The Definitive Guide to MySQL 5", "This book shows readers how to connect to MySQL via all of the major APIs, including PHP, Perl, Java, JSP, and C#"),
("MySQL Cookbook", "Ideal for beginners and professional database and web developers"),
("Learning MySQL", "Book travels far into MySQL's subtleties, including complex queries and joins");
SELECT * FROM products
WHERE MATCH (product, description)
AGAINST ('database guide' IN NATURAL LANGUAGE MODE);
不久前, MongoDB中引入了全文搜索支持。 与MySQL相似,它是使用字符串内容(或字符串数组)上特殊类型的索引来实现的。 MongoDB还支持词组搜索,术语搜索和布尔搜索的组合。 它易于使用且实现优雅,但并非没有限制。 不幸的是,目前, MongoDB无法控制要指定针对其执行全文本搜索的字段子集:它始终与全文本索引中包含的所有字段匹配。 让我们看一下实际使用的MongoDB全文搜索:
db.products.insert({
"product": "The Definitive Guide to MySQL 5",
"description": "This book shows readers how to connect to MySQL via all of the major APIs, including PHP, Perl, Java, JSP, and C#"
})
db.products.insert({
"product": "MySQL Cookbook",
"description": "Ideal for beginners and professional database and web developers"
})
db.products.insert({
"product": "Learning MySQL",
"description": "Book travels far into MySQL's subtleties, including complex queries and joins"
})
db.products.createIndex({
product: "text",
description: "text"
})
db.products.find({
$text: {
$search: "database guide"
}
})
发展历程
在开发方面, MySQL提供了广泛的连接器集,可用于通过您选择的大多数主流编程语言与服务器进行通信。 关于Java开发, MySQL包括一个符合JDBC 3.0和JDBC 4.0规范的JDBC驱动程序。
尽管很少见到使用直接JDBC接口与关系数据存储进行通信的代码(已构建了许多框架来简化此过程),但还是很高兴知道所涉及的内容。 让我们看一下连接到MySQL并执行一个SELECT语句的以下代码片段:
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost/tutorial");
Statement statement = null;
ResultSet resultSet = null;
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM books");
while (resultSet.next()) {
// Now do something with the ResultSet ....
}
} catch (SQLException ex) {
// Log exception
} finally {
if (resultSet != null) {
try { resultSet.close(); } catch ( SQLException ex) { /* ignore */ }
}
if (statement != null) {
try { statement.close(); } catch ( SQLException ex) { /* ignore */ }
}
}
} catch (SQLException ex) {
// Log exception
} finally {
if (connection != null ) {
try { connection.close(); } catch( SQLException ex ) { /* ignore */ }
}
}
它看起来很冗长,并且充满了异常处理。 反过来, MongoDB具有丰富的驱动程序生态系统,除了主流语言外,还包括Erlang , Go , Node.js和Scala的驱动程序。 由于可以自由制定自己的规范,因此MongoDB正在开发下一代驱动程序,并Swift使现有实现适应行业最新趋势(其中一个很好的例子是ReactiveMongo:适用于MongoDB的Reactive Scala驱动程序 ) 。
例如,让我们看一下使用Java和Morphia驱动程序连接到MongoDB的一种方法(假设我们有Book和Author数据模型类):
final MongoClient client = new MongoClient( "localhost", 27017 );
final Datastore dataStore = morphia
.map( Book.class, Author.class )
.createDatastore( client, "tutorial" );
final Query< Book > query = dataStore.createQuery( Book.class ).
final List< Book > books = query.asList();
从历史上看,由于社区支持的库集丰富,因此Java对JSON的支持非常好,因此可以轻松地将JSON文档转换为Java类(或从Java类转换)。
更不用说Java社区已经开发了许多不同的对象关系映射框架( ORM )来从低级JDBC接口进行抽象,这从本质上讲可以使代码编写得像MongoDB的示例一样简洁,这是不公平的。 但是,重要的是要了解它们在现有应用程序中增加了很多复杂性。
5.10.1。 部署方式
在大多数主要操作系统上都可以使用MySQL和MongoDB 。 在大多数情况下, MySQL是从特定于平台的软件包中安装的,并且需要对系统的特权访问。 尽管也提供了可下载的存档,但是取决于操作系统,配置和版本(例如MySQL Cluster ),安装可能会变得非常复杂且不直观(但是可能不需要特权访问系统)。
相反,在大多数情况下, MongoDB是作为可下载的存档分发的,可以将其解压缩并立即使用。 合理的默认值在这里起着至关重要的作用,因为它需要最少的配置,只需运行MongoDB服务器并开始用文档填充数据存储即可。
可以公平地说,借助容器化和Docker ,部署过程(我们已经习惯了)的格局正在Swift变化。 从传统的基于程序包的发行版到预配置的容器,将可安装的程序包和可下载运行的模型压平:一切都变成一个映像,作为隔离的容器运行,可在几毫秒内获得。
更不用说许多云提供商( AWS , Cloud Foundry , Open Shift ,仅举几例)都提供了适用于MySQL和/或MongoDB的软件即服务产品,并负责所有配置,基础架构和可扩展性细节。
监控与诊断
显然,监视是任何数据存储管理过程的关键组成部分。 有很多用于监视您选择的数据存储的商业解决方案,但让我们讨论一下作为MySQL和MongoDB发行版的一部分可用的解决方案。
MySQL有几种执行监视和诊断的方法。 首先,它是SHOW ENGINE <ENGINE> STATUS命令。 其次, MySQL支持性能模式 ,这是一种用于在较低级别监视MySQL服务器执行的功能。 最后, MySQL支持DTrace探针 (并非每个操作系统都支持),这些探针旨在提供有关MySQL服务器中查询执行以及该过程中所使用系统的不同区域的信息。
MongoDB发行版包含许多命令行实用程序,可用于快速检索有关每个数据存储实例的性能和活动的统计信息。 不仅如此,每个正在运行的MongoDB实例还提供一个Web界面,该界面通过一个简单的网页公开诊断和监视信息。 最后, MongoDB包含许多命令,这些命令通过外壳连接到数据库,从而获得有关数据库状态的见解。
安全
MySQL使用基于特权的安全模型。 MySQL 特权系统的主要功能是验证用户身份,并将该用户与特定数据库(例如CREATE , DROP , SELECT , INSERT , UPDATE , DELETE 等 )的特权相关联。
到目前为止, MySQL特权系统尚不支持一些功能:无法明确指定应拒绝给定用户的访问权限,并且无法指定用户具有创建或删除数据库中的表但没有创建权限的特权。或删除数据库本身。 在传输层, MySQL支持使用TLS v1.0协议的SSL(安全套接字层)在客户端和服务器之间建立安全(加密)连接。
MongoDB安全功能包括身份验证,授权和审核。 它的基础是具有灵活权限集的基于角色的访问控制。 值得一提的是, MongoDB通过定义一组内置角色为用户定义的角色提供了基础。 也可以使用TLS / SSL(传输层安全性/安全套接字层)来加密MongoDB的所有网络流量,以确保仅目标客户端可以读取。
权衡而非战斗
如我们所见, MySQL和MongoDB都达到相同的共同目标:成为为其用户提供全面的数据管理解决方案。 但是,他们每个人实现此目标的方式都非常不同。 从一方面来看,我们看到了相当成熟且经过考验的关系数据存储。 从另一面看,我们遇到了年轻但很快成熟的文档数据存储,因此适合某些类别的现代Web应用程序。
正如本教程中多次提到的那样,这不是一场战斗,我们也没有在寻找胜利者。 而是,我们正在寻找更适合您的应用程序需求的解决方案。 甚至,异构数据存储基础架构如今已成为一种规范,而不是一种例外:例如, MongoDB可能完全适合分析和报告需求,而MySQL可以存储计费交易。 幸运的是,借助本教程,您将能够选择合适的工具来完成这项工作。
在许多方面,可以说MongoDB是为Web构建的:拥抱JSON,学习时间非常短,快速开发的基础,每个发行版都添加了新功能。 MySQL经过了久经考验的,保守的和老式的方式,但是随着关系数据存储试图适应自身以满足现代应用程序的需求,事物的变化非常快。
MySQL还是MongoDB?
关于MySQL和MongoDB的讨论已经很多了。 当MongoDB比MySQL更受青睐时,最好以一组建议结束讨论,反之亦然。
首先,如果您的数据对您的业务至关重要,则MySQL很可能是一个更安全的选择:存在ACID属性是有原因的。 但是每个应用程序都是不同的。 内容管理系统,日志管理,分析,论坛和博客,事件存储,产品目录,库存管理,那些类型的应用程序可以从MongoDB作为数据存储中受益。
无模式数据模型是快速开发的推动力:只需随需引入新属性,而无需执行模式演变和数据迁移。 可以说,但是MongoDB的处理文档和运行查询的风格对开发人员更加友好(而且,它不需要像SQL一样学习任何语言)。 与MySQL Cluster配置(和管理)相比,配置MongoDB的副本集和分片集群确实非常容易和快捷。
现代体系结构模式正在促进拆分应用程序的读写路径(例如, 命令和查询职责隔离或仅CQRS )。 这样,应用程序可以通过MySQL提供写路径的方式进行设计,而MongoDB可以作为读路径的数据存储,其中数据段组成有意义的文档。
MySQL和MongoDB:如今
值得一提的是, Twitter和Facebook这两家公司成功地运营了一些最大的MySQL部署。 他们通过无数博客文章愉快地分享了自己的经验: Twitter 上的MySQL,Twitter上的MySQL以及Mysos的发展 , Twitter如何使用MySQL每天存储2.5亿条推文 , WebScaleSQL:基于MySQL上游的协作等等。
另一方面,越来越多的公司以越来越大的规模部署它, MongoDB的采用每天都在增长。 例如, eBay共享了“我们如何构建eBay的第一个Node.js应用程序” ,而Craigslist 在1年后的 Craigslist上跟进了MongoDB 。 毫无疑问,未来我们将看到更多的采用。
6。结论
在这个简短的教程中,我们试图看一下两个非常流行的数据存储,以MySQL表示的传统关系数据库和以MongoDB表示的文档数据存储。 我们简要地介绍了每个功能所具有的最重要的功能和数据保证,试图评估如何影响应用程序的可扩展性和可用性。 我们已经省略了许多底层的内在细节,因为MySQL和MongoDB都值得单独购买几本书。 相反,我们进行了高层次的概述,选择了最有趣和最重要的领域。
翻译自: https://www.javacodegeeks.com/2015/07/mysql-vs-mongodb.html