{"id":41493,"date":"2015-07-06T10:00:19","date_gmt":"2015-07-06T07:00:19","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=41493"},"modified":"2023-12-05T16:37:08","modified_gmt":"2023-12-05T14:37:08","slug":"mysql-vs-mongodb","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html","title":{"rendered":"MySQL vs. MongoDB: Choosing a Data Management Solution"},"content":{"rendered":"<div class=\"toc\">\n<h3>Table Of Contents<\/h3>\n<dl>\n<dt><a href=\"#introduction\">1. Introduction<\/a><\/dt>\n<dt><a href=\"#RDBM\">2. The dominance of RDBM systems<\/a><\/dt>\n<dt><a href=\"#a_new_era\">3. A new era of NoSQL movement<\/a><\/dt>\n<dt><a href=\"#tables_vs_documents\">4. Tables vs Documents vs Graphs vs Key\/Values<\/a><\/dt>\n<dt><a href=\"#conscious_decision\">5. MySQL and MongoDB: Conscious Decision<\/a><\/dt>\n<dd>\n<dl>\n<dt><a href=\"#enforced\">5.1. Enforced Schema vs Schemaless<\/a><\/dt>\n<dt><a href=\"#normalization_vs_duplication\">5.2. Normalization vs Duplication<\/a><\/dt>\n<dt><a href=\"#relations_vs_references\">5.3. Relations vs References<\/a><\/dt>\n<dt><a href=\"#transactions_vs_atomic\">5.4. Transactions vs Atomic Updates<\/a><\/dt>\n<dt><a href=\"#sql_vs_json\">5.5. SQL vs JSON<\/a><\/dt>\n<dt><a href=\"#procedures_vs_scripting\">5.6. Stored Procedures vs Scripting<\/a><\/dt>\n<dt><a href=\"#group_vs_aggregations\">5.7. GROUP BY vs Aggregations<\/a><\/dt>\n<dt><a href=\"#clustering\">5.8. Clustering and Sharding\/Partitioning<\/a><\/dt>\n<dt><a href=\"#full\">5.9. Full text search<\/a><\/dt>\n<dt><a href=\"#development\">5.10. Development<\/a><\/dt>\n<dt><a href=\"#monitoring\">5.11. Monitoring &amp; Diagnostics<\/a><\/dt>\n<dt><a href=\"#security\">5.12. Security<\/a><\/dt>\n<dt><a href=\"#tradeoffs\">5.13. Trade-offs, not battles<\/a><\/dt>\n<dt><a href=\"#mysql_or_mongodb?\">5.15. MySQL or MongoDB?<\/a><\/dt>\n<dt><a href=\"#nowadays\">5.16. MySQL and MongoDB: Nowadays<\/a><\/dt>\n<\/dl>\n<\/dd>\n<dt><a href=\"#conclusions\">6. Conclusions<\/a><\/dt>\n<\/dl>\n<\/div>\n<h2><a name=\"introduction\"><\/a>1. Introduction<\/h2>\n<p>It would be fair to say that as IT professionals we are living in the golden age of data management era. As our software systems become more complex and more distributed, driven by myriads of scalability and availability requirements, the traditional solutions used for years began to fall behind.<\/p>\n<p>The goal of this tutorial is to provide a fair overview of the two data management solutions: mature and widely used relation database represented by <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and a new kid on the block, <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a>, which in turn represents a new generation of data store. By no means is it a battle with a clear winner at the end. Instead, the intention is to help developers to make a choice and find a right fit for their applications by going through the features of <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a>, discussing the different guarantees and limitations each one has.<\/p>\n<h2><a name=\"RDBM\"><\/a>2. The dominance of RDBM systems<\/h2>\n<p>The history and evolution of data management software is not a particularly exciting topic to spend time on. For a quite some time relational database management systems took a leadership and for years the choice was obvious, either <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, <a href=\"http:\/\/www.postgresql.org\/\">PostreSQL<\/a> or <a href=\"http:\/\/www.oracle.com\/ca-en\/index.html\">Oracle<\/a>, just to name a few. <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> (and its vendor-specific dialects) was the de-facto standard for querying relational data stores and by definition every backend software developer had to learn and understand a least some basics of it. It worked surprisingly well until recently, when a whole family of new data management systems has emerged, the phenomenon also known as <strong>NoSQL<\/strong> (or <strong>Not Only SQL<\/strong>) movement.<\/p>\n<h2><a name=\"a_new_era\"><\/a>3. A new era of NoSQL movement<\/h2>\n<p>The challenges which modern software systems are facing nowadays with respect to data volumes and requests\/transactions throughput requirements revealed that relational data stores often become a bottleneck, thus imposing the limits on overall system scalability. Traditionally, the way to solve this problem was just buying a bigger box (so called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Scalability#Horizontal_and_vertical_scaling\">vertical scalability<\/a>), however at some point the price to pay becomes very, very high, making the whole system ridiculously expensive and impractical.<\/p>\n<p>The industry was actively looking into a cheaper ways to build complex distributed systems, making use of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Scalability#Horizontal_and_vertical_scaling\">horizontal scalability<\/a> instead. It also meant to come up with alternatives to relation data stores, which could scale horizontally as well. That the moment, when <a href=\"https:\/\/en.wikipedia.org\/wiki\/NoSQL\">NoSQL movement<\/a> has begun.<\/p>\n<h2><a name=\"tables_vs_documents\"><\/a>4. Tables vs Documents vs Graphs vs Key\/Values<\/h2>\n<p>A <a href=\"https:\/\/en.wikipedia.org\/?title=Relational_model\">Relational data model<\/a> represents all data in terms of tuples and relations (better known as tables). The structured data fits this model very well and for a long time no other viable alternative existed. With the <a href=\"https:\/\/en.wikipedia.org\/wiki\/NoSQL\">NoSQL movement<\/a>, many alternative data models were developed, giving a birth to a whole bunch of specialized data storage systems.<\/p>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/NoSQL\">NoSQL<\/a> solutions could be classified in a few different categories. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Document-oriented_database\">Document data stores<\/a> are designed for storing, querying and managing documents (semi-structured data). The more mature representatives of this category include <a href=\"http:\/\/couchdb.apache.org\/\">CouchDB<\/a>, <a href=\"http:\/\/www.couchbase.com\/\">Couchbase<\/a>, <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a>, <a href=\"http:\/\/orientdb.com\">OrientDB<\/a> and <a href=\"http:\/\/hyperdex.org\/\">HyperDex<\/a>. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Key-value_database\">Key\/Value data stores<\/a> are designed for storing, querying and managing associative arrays (also known as dictionaries or hashes).<\/p>\n<p>The most widely used representatives of this category include <a href=\"http:\/\/aws.amazon.com\/dynamodb\/\">DynamoDB<\/a>, <a href=\"https:\/\/foundationdb.com\/\">FoundationDB<\/a>, <a href=\"http:\/\/hyperdex.org\/\">HyperDex<\/a>, <a href=\"http:\/\/memcachedb.org\/\">MemcacheDB<\/a>, <a href=\"http:\/\/redis.io\/\">Redis<\/a>, <a href=\"http:\/\/basho.com\/products\/\">Riak<\/a>, <a href=\"http:\/\/www.aerospike.com\/\">Aerospike<\/a> and <a href=\"http:\/\/orientdb.com\">OrientDB<\/a>. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Graph_database\">Graph data stores<\/a> are designed for efficiently storing and operating graph structures. The well-known representatives of this category include <a href=\"http:\/\/neo4j.com\/\">Neo4J<\/a>, <a href=\"http:\/\/www.objectivity.com\/products\/infinitegraph\/\">InfiniteGraph<\/a>, <a href=\"http:\/\/graphbase.net\/\">GraphBase<\/a> and <a href=\"http:\/\/orientdb.com\">OrientDB<\/a>. Last but not least, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Column_(data_store)\">wide-column data stores<\/a> are taking a hybrid approach (combining some characteristics of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Key-value_database\">key\/value data stores<\/a> and traditional <a href=\"https:\/\/en.wikipedia.org\/?title=Relational_database\">relational data stores<\/a>). The most advanced representatives of this category include <a href=\"https:\/\/accumulo.apache.org\/\">Accumulo<\/a>, <a href=\"http:\/\/cassandra.apache.org\/\">Cassandra<\/a> and <a href=\"http:\/\/hbase.apache.org\/\">HBase<\/a>.<\/p>\n<p>Please notice that the list of different <a href=\"https:\/\/en.wikipedia.org\/wiki\/NoSQL\">NoSQL<\/a> data stores presented above is far from being complete, it just contains the most well-known and widely used names, but there are a lot more out there.<\/p>\n<h2><a name=\"conscious_decision\"><\/a>5. MySQL and MongoDB: Conscious Decision<\/h2>\n<p>Enough with the introduction, so let us move on to more practical things. In this part of the tutorial we are going to take a look on all aspects of application development process using <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a>, also spending some time talking about deployment and monitoring. The goal is to discuss the trade-offs and design decisions that each of those data stores make and analyze how they are changing the way we develop applications. Also, another purpose this tutorial serves is to assist in making a decision when <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> may be a better choice than <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> (and vice versa), taking into account application architecture, data access patterns and storage requirements.<\/p>\n<p>As we already now, <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> is a document data store. It stores JSON-style documents which are grouped into collections. At the top of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> data model hierarchy is a database (please refer to <a href=\"http:\/\/docs.mongodb.org\/manual\/\">official documentation<\/a> in order to get the comprehensive details). The current production ready version of <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> is <strong>3.0.4<\/strong>.<\/p>\n<p>From other side, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is relational data store. The data is stored in tables which contains columns. The tables are grouped into database (please refer to <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/index.html\">official documentation<\/a> in order to get the comprehensive details). The current production ready version of <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is <strong>5.6.25<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> supports multiple <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/storage-engines.html\">storage engines<\/a>, each of them serves own purpose and has some features not available in other storage engines. Along this tutorial we assume that <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/innodb-storage-engine.html\">InnoDB<\/a> storage engine is used as it is the default and most general-purpose one which is recommended for use except for specialized use cases.<\/p>\n<h3><a name=\"enforced\"><\/a>5.1. Enforced Schema vs Schemaless<\/h3>\n<p><a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> as a relation data store requires a strict schema for its data model: all tables should be created with columns defined. Only then the data could be stored and queried using the <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> language. It somewhat complicates the development and deployment process as every time the modification of data model is required, the schema should be changed first and then data migrated. Here is an example of typical steps required to create new database, new table and insert one row into it using <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> shell and <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> language:<\/p>\n<pre class=\"brush:sql\">CREATE DATABASE tutorial;\nUSE tutorial;\nCREATE TABLE chapters (\n    id INT PRIMARY KEY AUTO_INCREMENT, \n    title VARCHAR(255) NOT NULL\n);\nINSERT INTO chapters (title) VALUES (\"MySQL and MongoDB: trade-offs, not battles\");\n<\/pre>\n<p>In contrast, <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> does not impose any schema on the documents being stored in the collection. It becomes the responsibility of application to deal with that, the only thing <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> restricts is the supported <a href=\"http:\/\/docs.mongodb.org\/manual\/reference\/bson-types\/\">data types<\/a>. It significantly speeds up the development process as <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> could be used right away to store JSON documents of any shape.<\/p>\n<p>The structure of the documents could evolve and change over time, and different generations of the documents may coexist in the same collection. It is up to application developer to decide how to perform data cleanup or migration if necessary. Let us take a look on how the same steps of creating new database, new collection and inserting one document into it could be done using <a href=\"https:\/\/www.mongodb.org\/\">MongoDB<\/a> shell:<\/p>\n<pre class=\"brush:java\">use tutorial\n\ndb.chapters.insert({ \n    \"title\": \"MySQL and MongoDB: trade-offs, not battles\" \n})\n<\/pre>\n<p>It is worth to mention that upcoming <strong>5.7<\/strong> version of <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> (which is currently in release candidate phase) introduces the native JSON support. With the introduction of this new JSON data type it would be possible to combine enforced schema and schemaless data in <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>.<\/p>\n<h3><a name=\"normalization_vs_duplication\"><\/a>5.2. Normalization vs Duplication<\/h3>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Database_normalization\">Normalization<\/a> in the world of relational databases is the process of organizing tables to minimize data redundancy. It involves decomposing a table into less redundant (and smaller) tables without losing data. It also assumes defining foreign keys in the old tables referencing the primary keys of the new ones. For example, this is the way to create two tables in <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, where the <strong>books<\/strong> table references the <strong>authors<\/strong> table:<\/p>\n<pre class=\"brush:sql\">CREATE TABLE authors (\n    id INT PRIMARY KEY AUTO_INCREMENT, \n    name VARCHAR(255) NOT NULL\n);\nCREATE TABLE books (\n    id INT PRIMARY KEY AUTO_INCREMENT, \n    title VARCHAR(255) NOT NULL, \n    author_id INT NOT NULL, \n    FOREIGN KEY (author_id) REFERENCES authors(id)\n);\nINSERT INTO authors (name) VALUES (\"Michael Kofler\");\nINSERT INTO books (title, author_id) VALUES (\"The Definitive Guide to MySQL 5\", 1);\n<\/pre>\n<p>The normalization is obsolete for <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>. Instead, careful data modeling and certain level of data duplication is the way to get most out of document data store. It also becomes the responsibility of the application to decide the level of data repetition and to keep all data fragments in sync in case of modifications. For example:<\/p>\n<pre class=\"brush:java\">db.books.insert( { \n    \"title\": \"The Definitive Guide to MySQL 5\", \n    \"author\": { \n        \"name\": \"Michael Kofler\" \n    }\n})\n<\/pre>\n<h3><a name=\"relations_vs_references\"><\/a>5.3. Relations vs References<\/h3>\n<p>In the normalized database, a <strong>JOIN<\/strong> clause from the <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> is usually used to combine records from two or more <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> tables (there are other techniques as well but by and large they essentially lead to the same results). For example:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush:sql\">SELECT * FROM books b INNER JOIN authors a ON a.id = b.author_id;<\/pre>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> supports document references but does not support joins: to resolve the reference, the additional query (or queries) should be executed (leading to infamous in relational world N+1 query problem). For example, in the snippet below we are inserting the reference to <strong>authors<\/strong> collection from the <strong>books<\/strong> collection instead of embedding author details:<\/p>\n<pre class=\"brush:java\">db.authors.insert({ \n    \"name\": \"Michael Kofler\", \n    \"_id\": 1  \n})\ndb.books.insert({ \n    \"title\": \"The Definitive Guide to MySQL 5\", \n    \"author\": { \n        \"$ref\": \"authors\", \n        \"$id\": 1 \n    }\n})\n<\/pre>\n<p>The necessary round-trips are the price to pay for the flexibility of going schemaless. However, as we already mentioned in section <a href=\"#_Normalization_vs_duplication\">Normalization vs Duplication<\/a>, certain level of data duplication and careful analysis of data access patterns may mitigate the problem.<\/p>\n<h3><a name=\"transactions_vs_atomic\"><\/a>5.4. Transactions vs Atomic Updates<\/h3>\n<p>A transaction is a logical unit of work performed by data management system against its data. The importance of transaction is encapsulated into its foundational properties: transaction must be <strong>atomic<\/strong>, <strong>consistent<\/strong>, <strong>isolated<\/strong> and <strong>durable <\/strong>(also known as <a href=\"https:\/\/en.wikipedia.org\/?title=ACID\">ACID<\/a> model). <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is a fully transactional relation data store which makes it a perfect choice for the mission-critical applications that are not able to tolerate data lost or inconsistency. However, transactions are not free: they significantly limit the horizontal scalability of the data stores, and <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is not an exception.<\/p>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> does not support transactional guarantees. Instead, it supports atomic updates on the single document level. It means when a single update operation modifies multiple documents, the modification of each document is atomic, but the operation as a whole is not atomic and other operations may interleave. It worth mentioning that it is possible to implement <strong>transaction-like<\/strong> semantic on top of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> (using the <a href=\"http:\/\/docs.mongodb.org\/manual\/tutorial\/perform-two-phase-commits\/\">two-phase commits<\/a> technique) but it requires quite complex implementations.<\/p>\n<h3><a name=\"sql_vs_json\"><\/a>5.5. SQL vs JSON<\/h3>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/SQL\">SQL<\/a> is a special-purpose programming language designed for managing data held in a relational database management system. It is the only query language supported by <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, enriched with a few <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/extensions-to-ansi.html\">vendor-specific extensions<\/a>. Despite its simplicity, <a href=\"https:\/\/en.wikipedia.org\/wiki\/SQL\">SQL<\/a> is a very powerful language which essentially consists of two parts: a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Data_definition_language\">data definition language<\/a> (DDL) and a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Data_manipulation_language\">data manipulation language<\/a> (DML). We have seen quite a few examples already, but let us take a look on the simplest and probably most useful example of selecting rows from the table:<\/p>\n<pre class=\"brush:sql\">SELECT * FROM books;\nSELECT * FROM books WHERE title LIKE \"%MySQL%\";<\/pre>\n<p>In <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>, everything is a document, represented as JSON. <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> does not have a dedicated language to manage the documents and takes very different approach instead. Document manipulation or querying is described using very rich <a href=\"http:\/\/docs.mongodb.org\/manual\/reference\/operator\/\">set of operators<\/a>, composed with each other using JSON structure, as any other document. This unified representation is quite powerful, expressive and easy to understand, plus it does not require to learn yet another programming language. Most of the operators are self-explanatory and intuitive, for example:<\/p>\n<pre class=\"brush:java\">db.books.find();\ndb.books.find({\n    \"title\": { \n        \"$regex\": \"MySQL\" \n    }\n});\n<\/pre>\n<h3><a name=\"procedures_vs_scripting\"><\/a>5.6. Stored Procedures vs Scripting<\/h3>\n<p>A stored procedure is a special kind of routine available on the server side of relational data store. Stored procedures could be implemented in different programming languages however most of the time they are written using <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> or its vendor-specific dialect, which is the case with <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>. Typically, stored procedures help increase the performance of the applications by executing some logic directly on the server, requiring less information to be sent between the server and the client. For example, here is a very simple <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> stored procedure:<\/p>\n<pre class=\"brush:sql\">DELIMITER \/\/\nCREATE PROCEDURE find_books\n(IN pattern CHAR(255))\nBEGIN\n    SELECT COUNT(*) FROM books WHERE title LIKE pattern;\nEND \/\/\nDELIMITER ;\n\nCALL find_books(\"%MySQL%\");\n<\/pre>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> supports server-side scripting in the form of executing JavaScript code on the server. Those server-side scripts may resemble stored procedures but the implementation goes beyond just simple scripting as it supports <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">map\/reduce<\/a> paradigm, firstly populated by Google, and widely adopted for big data analytics. Essentially, by supplying the script to <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">map\/reduce<\/a> command, it becomes possible parallelize the processing of a large and very large datasets across many <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> data store instances. Let us take a look on very na\u00efve <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">map\/reduce<\/a> script example which counts how many books have \u201cMySQL\u201d string in their title:<\/p>\n<pre class=\"brush:sql\">db.runCommand( {\n    mapReduce: \"books\",\n    map: function() {\n        if (this.title.indexOf(\"MySQL\") &gt;= 0) { \n            emit(\"MySQL\", 1);        \n        }\n    },\n    reduce: function(key, counters) {\n        count = 0;\n\n        for (var index = 0; index &lt; counters.length; ++index) { \n            count += counters[index];                    \n        }\n\n        return count;\n    },\n    out: { inline: 1 }\n} )\n<\/pre>\n<p>Compared to the <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> stored procedure example, the <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> one looks overly verbose and complicated. However once the concepts of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">map\/reduce<\/a> paradigm become more clear, the example is going to look quite simple, opening a whole new frontier of applying many data processing, exploration and analysis techniques.<\/p>\n<h3><a name=\"group_vs_aggregations\"><\/a>5.7. GROUP BY vs Aggregations<\/h3>\n<p>In data management domain, an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Aggregate_function\">aggregate function<\/a> is a function where the values of multiple data records are grouped together depending on certain aggregation criteria, as such producing a single value of more significant meaning or measurement. The <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a> language defines a set of specific clauses for performing aggregations: <strong>GROUP BY<\/strong> and <strong>HAVING<\/strong>. The set of standard grouping functions among many others include <strong>AVG()<\/strong>, <strong>COUNT()<\/strong>, <strong>MAX()<\/strong>, <strong>MIN()<\/strong>, <strong>STD()<\/strong>, <strong>SUM()<\/strong>. Let us take a look on <strong>GROUP BY<\/strong> example in <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> shell:<\/p>\n<pre class=\"brush:sql\">CREATE TABLE orders (\n    id INT PRIMARY KEY AUTO_INCREMENT, \n    publisher VARCHAR(255) NOT NULL,\n    product VARCHAR(255) NOT NULL,\n    price NUMERIC (15,2) NOT NULL\n);\nINSERT INTO orders (product, publisher, price) VALUES \n    (\"The Definitive Guide to MySQL 5\", \"APress\", 37.36),\n    (\"MySQL Cookbook\", \"O\u2019Reilly\", 49.65),\n    (\"Learning MySQL\", \"O\u2019Reilly\", 29.48);\nSELECT publisher, SUM(price) FROM orders GROUP BY publisher;\n<\/pre>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> offers a specialized set of aggregations operations which process documents and return computed (or aggregated) results. Aggregation operations group values from multiple documents together, and can perform a variety of operations on the grouped data to return a single result. Aggregations in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> could be done in two ways: using <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/aggregation-pipeline\/\">aggregation pipeline<\/a> or <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/single-purpose-aggregation\/\">single purpose aggregation methods and commands<\/a>.<\/p>\n<p>Let us take a look on the same example we have prepared to demonstrate <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> aggregations, this time using <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>\u2019s <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/aggregation-pipeline\/\">aggregation pipeline<\/a>:<\/p>\n<pre class=\"brush:java\">db.books.insert( { \n    \"title\": \"The Definitive Guide to MySQL 5\", \n    \"publisher\": \"APress\",\n    \"price\": 37.36\n})\ndb.books.insert( { \n    \"title\": \"MySQL Cookbook\", \n    \"publisher\": \"O\u2019Reilly\",\n    \"price\": 49.65\n})\ndb.books.insert( { \n    \"title\": \"Learning MySQL\", \n    \"publisher\": \"O\u2019Reilly\",\n    \"price\": 29.48\n})\ndb.books.aggregate([\n    { $match: {} }, \n    { $group: {\n        \"_id\": \"$publisher\", \n        \"price\": { \n            \"$sum\": \"$price\"\n        }\n    }}\n]);\n<\/pre>\n<p>The <a href=\"http:\/\/en.wikipedia.org\/wiki\/MapReduce\">map\/reduce<\/a> command which we discussed in <a href=\"#_Stored_Procedures_vs\">Stored Procedures vs Scripting<\/a> section could also be considered as a way to do aggregations.<\/p>\n<h3><a name=\"clustering\"><\/a>5.8. Clustering and Sharding\/Partitioning<\/h3>\n<p>Nowadays, the data volumes are growing exponentially and the single physical instance of data store often is not able to persist and manage such a mass of data at acceptable pace. Clustering is technology that allows to bring many individual computing instances to work together. With respect to data storages, clustering goes side by side with data sharding\/partitioning, which is a technique to split large amount of data across multiple data store instances.<\/p>\n<p>For quite a while, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> has been available in the <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a> edition which claims to be a write-scalable, real-time, <a href=\"https:\/\/en.wikipedia.org\/?title=ACID\">ACID<\/a>-compliant transactional data store. <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a> is built on top of distributed, multi-master architecture, which supports auto-sharding\/partitioning and scales horizontally to serve read and write intensive workloads.<\/p>\n<p>Historically, <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a> has a reputation of being too complex, quite hard to configure, monitor and maintain. In contrast to standalone <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> deployments, the data schema should be designed in such a way so to take data sharding \/ partitioning into account, otherwise the performance of the data store will suffer a lot. Lastly, <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a> has many limitations comparing to the regular <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> distribution.<\/p>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> document data store supports sharding\/partitioning out of the box using concept of <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/sharded-cluster-components\/\">sharded clusters<\/a>. The strong side of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> sharding\/partitioning is that it has simple and easy configuration. It scales horizontally pretty well but there are quite a <a href=\"http:\/\/docs.mongodb.org\/manual\/reference\/limits\/#limits-sharding\">few limitations<\/a> to be aware of.<\/p>\n<h4>5.8.1. Replication<\/h4>\n<p>Replication is an essential technique to keep data safe (by replicating it across many data store instances) and in many cases to improve scalability and fault-tolerance of the applications dealing with this data. <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> supports traditional <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/replication.html\">master\/slave replication<\/a>, which by default is asynchronous but semi-synchronous and delayed replication modes are also possible.<\/p>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> approaches replication by introducing replica sets. Basically, it is master\/slave replication but <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> uses a little bit different terminology. The master, called the <strong>primary<\/strong>, receives all write operations and slaves, called <strong>secondaries<\/strong>, apply operations from the primary. The one of the greatest features supported by replica sets is <a href=\"http:\/\/docs.mongodb.org\/manual\/core\/replication-introduction\/\">automatic failover<\/a>: when a primary does not communicate with the other members of the replica set, the replica set will attempt to select another member to become the new primary.<\/p>\n<p>To be fair, it is possible to configure <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> master\/slave replication with <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/replication-solutions-switch.html\">automatic failover<\/a> as well but there are some concerns and discussions about this feature in <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> community.<\/p>\n<h3><a name=\"full\"><\/a>5.9. Full text search<\/h3>\n<p>Since a long time <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> has support for full-text indexing and searching that is implemented using special type of the index. It is important to mention that full-text indexing support became available on the <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/innodb-storage-engine.html\">InnoDB<\/a> storage engine only since <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> <strong>5.6<\/strong> release branch.<\/p>\n<p>Interestingly, full-text search in <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is possible using natural language search (phrase search), boolean search (terms search) where the words to search for might be marked as \u201cmust be present\u201d or \u201cmust be absent\u201d, and query expansion search (a slight modification of a natural language search). However, at the moment full-text indexing is not supported in clustered <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> deployments (see please <a href=\"#_Clustering_and_Sharding\/Partitionin\">Clustering and Sharding\/Partitioning<\/a> section for a brief discussion about <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a>). Let us take a look on quick example:<\/p>\n<pre class=\"brush:sql\">CREATE TABLE products (\n    id INT PRIMARY KEY AUTO_INCREMENT, \n    product VARCHAR(255) NOT NULL,\n    description VARCHAR(255) NOT NULL,\n\n    FULLTEXT product_description (product, description)\n);\nINSERT INTO products (product, description) VALUES \n    (\"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#\"),\n    (\"MySQL Cookbook\", \"Ideal for beginners and professional database and web developers\"),\n    (\"Learning MySQL\", \"Book travels far into MySQL's subtleties, including complex queries and joins\");\nSELECT * FROM products \n    WHERE MATCH (product, description)\n    AGAINST ('database guide' IN NATURAL LANGUAGE MODE);\n<\/pre>\n<p>Full-text search support was introduced in <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> not so long ago. Similarly to <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>, it is implemented using special type of the index on the string content (or array of strings). <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> also supports phrase search, terms search and boolean search as a combinations of those. It is easy to use and elegantly implemented feature but not without limitations. Unfortunately, at the moment <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> gives no control to specify the subset of fields to perform full-text search against: it is always matches all the fields included in the full-text index. Let us take a look on <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> full-text search in action:<\/p>\n<pre class=\"brush:java\">db.products.insert({\n    \"product\": \"The Definitive Guide to MySQL 5\",\n    \"description\": \"This book shows readers how to connect to MySQL via all of the major APIs, including PHP, Perl, Java, JSP, and C#\"\n})\ndb.products.insert({\n    \"product\": \"MySQL Cookbook\",\n    \"description\": \"Ideal for beginners and professional database and web developers\"\n})\ndb.products.insert({\n    \"product\": \"Learning MySQL\",\n    \"description\": \"Book travels far into MySQL's subtleties, including complex queries and joins\"\n})\ndb.products.createIndex({\n    product: \"text\",\n    description: \"text\"\n})\ndb.products.find({\n    $text: { \n        $search: \"database guide\" \n    } \n})\n<\/pre>\n<h3><a name=\"development\"><\/a>5.10. Development<\/h3>\n<p>When it comes to development, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> provides a wide <a href=\"https:\/\/www.mysql.com\/products\/connector\/\">set of connectors<\/a> which could be used to communicate with the server from most of the mainstream programming languages of your choice. With respect to Java development, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> includes a JDBC driver which conforms to the JDBC 3.0 and JDBC 4.0 specifications.<\/p>\n<p>Although it is quite rare to encounter the code which uses straight JDBC interfaces to communicate with relation data store (many frameworks have been built to facilitate that), it is good to know what is involved. Let us take a look on following code snippet which connects to <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and executes a single <strong>SELECT<\/strong> statement:<\/p>\n<pre class=\"brush:java\">try {\n    connection = DriverManager.getConnection(\"jdbc:mysql:\/\/localhost\/tutorial\");\n\n    Statement statement = null;\n    ResultSet resultSet = null;\n\n    try {\n        statement = connection.createStatement();\n        resultSet = statement.executeQuery(\"SELECT * FROM books\");\n\t\t\t\t\n        while (resultSet.next()) { \n            \/\/ Now do something with the ResultSet .... \n        }\n    } catch (SQLException ex) {\n        \/\/ Log exception\n    } finally {\n        if (resultSet != null) {\n\t    try { resultSet.close(); } catch ( SQLException ex) { \/* ignore *\/ }\n        }\n\n        if (statement != null) {\n\t    try { statement.close(); } catch ( SQLException ex) { \/* ignore *\/ }\n        }\n    }\n} catch (SQLException ex) {\n    \/\/ Log exception\n} finally {\n    if (connection != null ) {\n        try { connection.close(); } catch( SQLException ex ) { \/* ignore *\/ }\n    }\n}\n<\/pre>\n<p>It looks quite verbose and full of exception handling. <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> in turn has a rich ecosystem of <a href=\"http:\/\/docs.mongodb.org\/ecosystem\/drivers\/\">drivers<\/a>, which aside from mainstream languages includes drivers for <a href=\"http:\/\/docs.mongodb.org\/ecosystem\/drivers\/erlang\/\">Erlang<\/a>, <a href=\"http:\/\/docs.mongodb.org\/ecosystem\/drivers\/go\/\">Go<\/a>, <a href=\"http:\/\/docs.mongodb.org\/ecosystem\/drivers\/node-js\/\">Node.js<\/a> and <a href=\"http:\/\/docs.mongodb.org\/ecosystem\/drivers\/scala\/\">Scala<\/a>. Having a freedom to come up with own specifications, <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> is in the process of development of the <a href=\"https:\/\/www.mongodb.com\/blog\/post\/server-discovery-and-monitoring-next-generation-mongodb-drivers\">next generation drivers<\/a> and quickly adapting the existing implementations to the latest trends in the industry (the good example of that is <a href=\"http:\/\/reactivemongo.org\/\">ReactiveMongo: Reactive Scala Driver for MongoDB<\/a>).<\/p>\n<p>As an example, let us take a look on one of the way to connect to <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> using Java and <a href=\"https:\/\/github.com\/mongodb\/morphia\">Morphia<\/a> driver (assuming we have Book and Author data model classes):<\/p>\n<pre class=\"brush:java\">final MongoClient client = new MongoClient( \"localhost\", 27017 );\nfinal Datastore dataStore = morphia\n    .map( Book.class, Author.class )\n    .createDatastore( client, \"tutorial\" );\n\nfinal Query&lt; Book &gt; query = dataStore.createQuery( Book.class ).\nfinal List&lt; Book &gt; books =  query.asList();        \n<\/pre>\n<p>Historically, JSON support in Java was quite good because of rich set of the community supported libraries, thus making conversions of JSON documents to Java classes (and back) no brainer.<\/p>\n<p>It would be unfair not to mention that Java community has developed quite a lot of different <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object-relational_mapping\">object-relational mapping<\/a> frameworks (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Object-relational_mapping\">ORM<\/a>s) to abstract from low-level JDBC interfaces, which essentially allow to write the code as concise as <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>\u2019s example. However, it is important to understand that they add quite a lot of complexity into existing applications.<\/p>\n<h4>5.10.1. Deployment<\/h4>\n<p>Both <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> are available on most of the major operating systems. In most cases <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is being installed from platform-specific packages and requires privileged access to the system. Although the downloadable archives are also available, depending on the operating system, configuration and edition (for example, <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a>), the installation may get quite complex and non-intuitive (however may not require privileged access to the system).<\/p>\n<p>Contrary, <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> in most cases is distributed as downloadable archive which could be unpacked and used right away. The sensible defaults play the great role here by requiring minimum configuration, just run the <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> server and start filling data store with documents.<\/p>\n<p>It will be fair to mention that with containerization and <a href=\"https:\/\/www.docker.com\/\">Docker<\/a>, the landscape of deployment procedures (we so get used to) is changing very rapidly. Moving from traditional package-based distributions to preconfigured containers flatten the installable packages and download-unpack-run models: everything becomes an image, run as isolated container, available in milliseconds.<\/p>\n<p>Not to mention that many cloud providers (<a href=\"http:\/\/aws.amazon.com\/\">AWS<\/a>, <a href=\"http:\/\/www.cloudfoundry.com\/\">Cloud Foundry<\/a>, <a href=\"https:\/\/openshift.redhat.com\">Open Shift<\/a>, just to name a few) have software-as-a-service offerings for <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and\/or <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>, taking care of all configuration, infrastructure and scalability details.<\/p>\n<h3><a name=\"monitoring\"><\/a>5.11. Monitoring &amp; Diagnostics<\/h3>\n<p>Clearly, monitoring is a critical component of any data store administration procedure. There is quite a number of commercial solutions for monitoring data store of your choice but let us discuss the ones available as part of the <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> distributions.<\/p>\n<p><a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> has a several ways to perform monitoring and diagnostics. First of all, it is <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/show-engine.html\">SHOW ENGINE &lt;ENGINE&gt; STATUS<\/a> command. Secondly, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> supports <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/performance-schema.html\">performance schema<\/a> which is a feature for monitoring <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> server execution at a low level. And lastly, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> supports <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/dba-dtrace-server.html\">DTrace probes<\/a> (not supported by every operating system) which are designed to provide information about the execution of queries within <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> server and the different areas of the system being utilized during that process.<\/p>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> distribution includes a number of command line utilities that allow to quickly retrieve statistics about the performance and activity of each data store instance. Not only that, every running <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> instance also provides a web interface that exposes diagnostic and monitoring information through a simple web page. And lastly, <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> includes a number of commands to get the insights about the state of the database by connecting to it through the shell.<\/p>\n<h3><a name=\"security\"><\/a>5.12. Security<\/h3>\n<p><a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> uses privilege-based security model. The primary function of the <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a>\u2019s <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/privilege-system.html\">privilege system<\/a> is to authenticate a user and to associate that user with privileges on a particular database (such as <strong>CREATE<\/strong>, <strong>DROP<\/strong>, <strong>SELECT<\/strong>, <strong>INSERT<\/strong>, <strong>UPDATE<\/strong>, <strong>DELETE <\/strong><a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/privileges-provided.html\">and others<\/a>).<\/p>\n<p>As of now, there are few things that are not supported by <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/privilege-system.html\">MySQL privilege system<\/a>: inability to explicitly specify that a given user should be denied access and inability to specify that a user has privileges to create or drop tables in a database but not to create or drop the database itself. On the transport layer, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> supports secure (encrypted) connections between clients and the server using the SSL (Secure Sockets Layer) using the TLS v1.0 protocol.<\/p>\n<p><a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> security features include authentication, authorization and auditing. Its foundation is a role-based access control with flexible set of privileges. It worth to mention that <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> provides a basis for user-defined roles by defining a set of build-in roles. It is also possible to use TLS\/SSL (Transport Layer Security\/Secure Sockets Layer) to encrypt all of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>\u2019s network traffic to ensure that it is only readable by the intended client.<\/p>\n<h3><a name=\"tradeoffs\"><\/a>5.13. Trade-offs, not battles<\/h3>\n<p>As we have seen, <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> both serve same common goal: be a comprehensive data management solution for its users. However, the ways each of them approaches this goal are very, very different. From one side, we see quite mature and battle-tested relational data store. From other side, we met young but quickly maturing document data store, so suitable for certain classes of modern web applications.<\/p>\n<p>As was stated several times along this tutorial, it is not a battle and we are not looking for a winner. Rather, we are looking for solution which better fits to the needs of your applications. Even more, heterogeneous data storage infrastructure becomes rather a norm than an exception nowadays: for example, <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> may perfectly fit into analytics and reporting demands, whereas <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> may store billing transactions. Luckily, with the help of this tutorial you will be able to pick the right tool to do the job.<\/p>\n<p>In many respects it would be fair to say that <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> was built for web: embracing JSON, very short learning curve, foundation of rapid development, new features added every release. <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is battle-tested, conservative and old fashion, however things are changing very fast as relation data stores try to adapt themselves to meet modern application needs.<\/p>\n<h3><a name=\"mysql_or_mongodb?\"><\/a>5.15. MySQL or MongoDB?<\/h3>\n<p>A lot have been already said about <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>. It would be good to finish the discussion with the set of recommendations when <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> is preferred than <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and vice-versa.<\/p>\n<p>First of all, if your data is critical to your business, very likely <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> is a safer choice: <a href=\"https:\/\/en.wikipedia.org\/?title=ACID\">ACID<\/a> properties are there for a reason. But every application is different. Content management systems, logs management, analytics, forums and blogs, events stores, product catalogs, inventory management, those kinds of applications may benefit from <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> as a data store.<\/p>\n<p>Schemaless data model is an enabler for rapid development: just introduce new properties as you go without a need to perform schema evolutions and data migration. Arguably, but <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>\u2019s style of manipulating documents and running queries is much more developer-friendly (moreover, it does not require any language to learn, like <a href=\"https:\/\/en.wikipedia.org\/?title=SQL\">SQL<\/a>). Configuring <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>\u2018s replica sets and sharded clusters is really easy and fast, comparing to <a href=\"http:\/\/dev.mysql.com\/downloads\/cluster\/\">MySQL Cluster<\/a> configuration (and management).<\/p>\n<p>Modern architectural patterns are promoting to split application\u2019s read and write paths (for example, <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn568103.aspx\">Command and Query Responsibility Segregation<\/a> or just <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn568103.aspx\">CQRS<\/a>). With that, applications could be designed in a way where write path is served by <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> but <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> could be a data storage for read path, where data pieces are composed into meaningful documents.<\/p>\n<h3><a name=\"nowadays\"><\/a>5.16. MySQL and MongoDB: Nowadays<\/h3>\n<p>It is worth mentioning that two companies, <a href=\"https:\/\/twitter.com\/\">Twitter<\/a> and <a href=\"https:\/\/www.facebook.com\/\">Facebook<\/a>, successfully operate some of the largest <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> deployments out there. They happily share their experience though the numerous blog posts: <a href=\"https:\/\/blog.twitter.com\/2012\/mysql-twitter\">MySQL at Twitter<\/a>, <a href=\"https:\/\/blog.twitter.com\/2015\/another-look-at-mysql-at-twitter-and-incubating-mysos\">Another look at MySQL at Twitter and incubating Mysos<\/a>, <a href=\"http:\/\/highscalability.com\/blog\/2011\/12\/19\/how-twitter-stores-250-million-tweets-a-day-using-mysql.html\">How Twitter Stores 250 Million Tweets a Day Using MySQL<\/a>, <a href=\"https:\/\/code.facebook.com\/posts\/1474977139392436\/webscalesql-a-collaboration-to-build-upon-the-mysql-upstream\/\">WebScaleSQL: A collaboration to build upon the MySQL upstream<\/a>, and more.<\/p>\n<p>From other side, adoption of <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> is growing every day with <a href=\"https:\/\/www.mongodb.com\/mongodb-scale\">more and more companies<\/a> deploying it at a larger and larger scale. For example, <a href=\"http:\/\/www.ebay.com\/\">eBay<\/a> shared <a href=\"http:\/\/www.ebaytechblog.com\/2013\/05\/17\/how-we-built-ebays-first-node-js-application\/\">How We Built eBay\u2019s First Node.js Application<\/a>, while <a href=\"http:\/\/www.craigslist.org\">Craigslist<\/a> followed up with <a href=\"http:\/\/blog.mongodb.org\/post\/22327647691\/mongodb-at-craigslist-1-year-later\">MongoDB at Craigslist: 1 Year Later<\/a>. No doubts, we are going to see more wide adoption in the future.<\/p>\n<h2><a name=\"conclusions\"><\/a>6. Conclusions<\/h2>\n<p>In this short tutorial we tried to take a look on two very popular data stores, traditional relation database represented by <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and document data store represented by <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a>. We briefly walked through most important features and data guarantees each of those has, trying to assess how applications scalability and availability might be affected. We have omitted a lot of low-level intrinsic details as both <a href=\"https:\/\/www.mysql.com\/\">MySQL<\/a> and <a href=\"http:\/\/www.mongodb.org\/\">MongoDB<\/a> worth several books alone. Instead, we did a high-level overview, picking the most interesting and important areas.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table Of Contents 1. Introduction 2. The dominance of RDBM systems 3. A new era of NoSQL movement 4. Tables vs Documents vs Graphs vs Key\/Values 5. MySQL and MongoDB: Conscious Decision 5.1. Enforced Schema vs Schemaless 5.2. Normalization vs Duplication 5.3. Relations vs References 5.4. Transactions vs Atomic Updates 5.5. SQL vs JSON 5.6. &hellip;<\/p>\n","protected":false},"author":141,"featured_media":2386,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[662,112,43,113,244],"class_list":["post-41493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development","tag-databases","tag-mongodb","tag-mysql","tag-nosql","tag-sql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\/Values5. MySQL and\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\/Values5. MySQL and\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2015-07-06T07:00:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-05T14:37:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"MySQL vs. MongoDB: Choosing a Data Management Solution\",\"datePublished\":\"2015-07-06T07:00:19+00:00\",\"dateModified\":\"2023-12-05T14:37:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html\"},\"wordCount\":4407,\"commentCount\":11,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"keywords\":[\"Databases\",\"MongoDB\",\"MySQL\",\"NoSQL\",\"SQL\"],\"articleSection\":[\"Software Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html\",\"name\":\"MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"datePublished\":\"2015-07-06T07:00:19+00:00\",\"dateModified\":\"2023-12-05T14:37:08+00:00\",\"description\":\"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\\\/Values5. MySQL and\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/software-development-2-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2015\\\/07\\\/mysql-vs-mongodb.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Software Development\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/software-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"MySQL vs. MongoDB: Choosing a Data Management Solution\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks","description":"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\/Values5. MySQL and","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html","og_locale":"en_US","og_type":"article","og_title":"MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks","og_description":"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\/Values5. MySQL and","og_url":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2015-07-06T07:00:19+00:00","article_modified_time":"2023-12-05T14:37:08+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"20 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"MySQL vs. MongoDB: Choosing a Data Management Solution","datePublished":"2015-07-06T07:00:19+00:00","dateModified":"2023-12-05T14:37:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html"},"wordCount":4407,"commentCount":11,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","keywords":["Databases","MongoDB","MySQL","NoSQL","SQL"],"articleSection":["Software Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html","url":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html","name":"MySQL vs. MongoDB: Choosing a Data Management Solution - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","datePublished":"2015-07-06T07:00:19+00:00","dateModified":"2023-12-05T14:37:08+00:00","description":"Table Of Contents 1. Introduction2. The dominance of RDBM systems3. A new era of NoSQL movement4. Tables vs Documents vs Graphs vs Key\/Values5. MySQL and","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/software-development-2-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2015\/07\/mysql-vs-mongodb.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Software Development","item":"https:\/\/www.javacodegeeks.com\/category\/software-development"},{"@type":"ListItem","position":3,"name":"MySQL vs. MongoDB: Choosing a Data Management Solution"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/41493","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=41493"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/41493\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/2386"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=41493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=41493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=41493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}